Multiple Layers of Anti-Sandboxing Techniques
It has been a while that I did not find an interesting malicious Python script. All the scripts that I recently spotted were always the same: a classic intostealer using Discord as C2 channel. Today I found one that contains a lot of anti-sanboxing techniques. Let's review them. For malware, it's key to detect the environment where they are executed. When detonated inside a sandbox (automatically or, manually, by an Analyst), they will be able to change their behaviour (most likely, do nothing)
Like all scripting languages running in the Windows eco-system, Python can call any Microsoft API call and there are useful to perform check at operating system. Here is what the scripts try to detect:
1. Is the script running inside a debugger?
from ctypes import * XVeGwgv = windll.kernel32.IsDebuggerPresent() if XVeGwgv == 0:
2. Does the host have enough physical memory?
import ctypes class CaMiHTTSf (ctypes.Structure): _fields_ = [ ("dwLength", ctypes.c_ulong), ("dwMemoryLoad", ctypes.c_ulong), ("ullTotalPhys", ctypes.c_ulonglong), ("ullAvailPhys", ctypes.c_ulonglong), ("ullTotalPageFile", ctypes.c_ulonglong), ("ullAvailPageFile", ctypes.c_ulonglong), ("ullTotalVirtual", ctypes.c_ulonglong), ("ullAvailVirtual", ctypes.c_ulonglong), ("sullAvailExtendedVirtual", ctypes.c_ulonglong), ] jJrSHLb = CaMiHTTSf() jJrSHLb.dwLength = ctypes.sizeof(CaMiHTTSf) ctypes.windll.kernel32.GlobalMemoryStatusEx(ctypes.byref(jJrSHLb)) if jJrSHLb.ullTotalPhys/1073741824 > 3:
3. Is there a user behind the keyboard, pressing keys?
import win32api nPnpCRlvJ = 0 CsZoAodMwrnNBW = 100 while nPnpCRlvJ < CsZoAodMwrnNBW: BBpvCYBI = win32api.GetAsyncKeyState(1) RkfbrNjlQLiYMc = win32api.GetAsyncKeyState(2) if BBpvCYBI % 2 == 1: nPnpCRlvJ += 1 if RkfbrNjlQLiYMc % 2 == 1: nPnpCRlvJ += 1 if nPnpCRlvJ >= CsZoAodMwrnNBW:
4. Is the mouse moving?
from time import sleep import win32api dJpkzPW = 30 ESPKUCFSNpN, MNoTiqFAmrJb = win32api.GetCursorPos() sleep(30) sToXQq, nGVNgR = win32api.GetCursorPos() if ESPKUCFSNpN - sToXQq != 0 or MNoTiqFAmrJb - nGVNgR != 0:
5. Is the script spending too much time in a debugger (ex: Python debugger)
from time import sleep from socket import AF_INET, SOCK_DGRAM import sys import datetime import time import socket import struct client = socket.socket(AF_INET, SOCK_DGRAM) client.sendto((bytes.fromhex("1b") + 47 * bytes.fromhex("01")), ("us.pool.ntp.org",123)) msg, address = client.recvfrom( 1024 ) BsaylVZq = datetime.datetime.fromtimestamp(struct.unpack("!12I",msg)[10] - 2208988800) sleep(100000) client.sendto((bytes.fromhex("1b") + 47 * bytes.fromhex("01")), ("us.pool.ntp.org",123)) msg, address = client.recvfrom( 1024 ) if ((datetime.datetime.fromtimestamp((struct.unpack("!12I",msg)[10] - 2208988800)) - BsaylVZq).seconds >= 100000):
Only if all these checks results are negative, then the Python will perform the malicious actions and inject a shellcode in memory...
Note that this script remains simple. They are plenty of sandbox-evasion techniques available[1].
The script (SHA256:a6eac5716bce341f14569d69fcac4f449e9c0f1e97adeb9cb4d02dc82962a30a) has a VT score of 12/61[2].
[1] https://evasions.checkpoint.com
[2] https://www.virustotal.com/gui/file/a6eac5716bce341f14569d69fcac4f449e9c0f1e97adeb9cb4d02dc82962a30a/detection
Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
Reverse-Engineering Malware: Advanced Code Analysis | Online | Greenwich Mean Time | Oct 28th - Nov 1st 2024 |
Comments
Per that documentation, Virtual-Key Code 1 is a left mouse button click, and 2 is a right mouse button click. One could further augment that code to check for other keyboard clicks, but then the question becomes, which ones do you want to monitor?
jdimpson
Oct 31st 2023
11 months ago