In this walkthrough, we'll analyze a Python-compiled stealers using common reverse engineering tools. Always perform this analysis in a isolated VM environment.
- PyInstxtractor
- Pylingual decompiler
- Python cryptography libraries
- cURL
- Download pyinstxtractor
- Execute with:
python pyinstxtractor.py RedTigerStealer.exe
- Locate the extracted
.pycfile in the created directory (typicallymain.pyc)
- Use Pylingual to decompile the .pyc file
- Search for cryptographic functions - in this case, we found:
def Decrypt(QNMDHUMNTJQMXQYXOXWFIRSGCDRGQNDLVXYEUHFNFAZCCLSZMDGYEPJ, v4r_key): # [implementation details]
The stealer uses AES-256-CBC with PBKDF2 key derivation. Here's the reconstructed decryption routine:
import base64
from cryptography.hazmat.primitives import hashes, padding
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
def Decrypt(encrypted_data_b64, password):
# Key derivation function
def DeriveKey(password, salt):
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
backend=default_backend()
)
return kdf.derive(password.encode() if isinstance(password, str) else password)
# Decryption process
encrypted_data = base64.b64decode(encrypted_data_b64)
salt = encrypted_data[:16]
iv = encrypted_data[16:32]
ciphertext = encrypted_data[32:]
key = DeriveKey(password, salt)
cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend())
decryptor = cipher.decryptor()
# Handle padding
decrypted_padded = decryptor.update(ciphertext) + decryptor.finalize()
unpadder = padding.PKCS7(128).unpadder()
return (unpadder.update(decrypted_padded) + unpadder.finalize()).decode()-
Locate the encrypted configuration:
encrypted_webhook = '\nLfMKTGpBnaXnEVp6RZ7Yb1VQmAPsUC+YKgE00fzwVP6ZqXlVBm5pIMympdh+GBWOklOnfgFt4+m4zXXpO0+cMtnEmIl2s9JnYSONQd698pAq3QHHoRjtbQHmVYpmSXTw0vCzutEM5RGt8pqT5rttRd+p8HNC5SfJCB32VAHP0uoSlXDSeY3ow9SrEWy2F/NhLi73Ud6E7ccRYST0k3YFdg==\n' encryption_key = 'uDsVlYqrhZRgdRVBvklMUoSffRbjqVzEfGXCzBthdZnsknEIvhjYWpyOJxXncsCKVeLXzGGbhUOkTMcWUgoUYyxBoxDhowBGTJKqEHimpJuAqnq'
-
Execute the decryption:
print(Decrypt(encrypted_webhook.strip(), encryption_key))
This will output the Discord webhook URL used by the stealer.