106 lines
3.1 KiB
Python
106 lines
3.1 KiB
Python
#!/usr/bin/env python3
|
|
|
|
import re
|
|
import base64
|
|
from pathlib import Path
|
|
from Crypto.Cipher import AES
|
|
from Crypto.Util.Padding import unpad
|
|
|
|
correct_order = Path('order.txt').read_text().strip().split('\n')
|
|
correct_order[0] = correct_order[0].split('=')[-1]
|
|
|
|
print("=" * 80)
|
|
print("decrypting...")
|
|
print("=" * 80)
|
|
|
|
print(f"\ngot {len(correct_order)} vars:")
|
|
for idx, var_name in enumerate(correct_order, 1):
|
|
print(f" {idx:2d}. {var_name}")
|
|
|
|
content = Path('dontrunACTIVEmalware.bat.txt').read_text(encoding='utf-8', errors='ignore')
|
|
lines = content.split('\n')
|
|
|
|
variables = {}
|
|
for line in lines:
|
|
matches = re.findall(r'[sS][eE][tT]\s+([a-zA-Z0-9_]+)=([A-Za-z0-9+/=]{1000,})', line, re.IGNORECASE)
|
|
for var_name, var_value in matches:
|
|
variables[var_name] = var_value
|
|
|
|
print(f"\nfound {len(variables)} b64 vars")
|
|
|
|
payload_segments = []
|
|
for var_name in correct_order:
|
|
if var_name in variables:
|
|
payload_segments.append(variables[var_name])
|
|
print(f" ok {var_name}: {len(variables[var_name])} chars")
|
|
else:
|
|
print(f" missing {var_name}")
|
|
|
|
complete_b64 = ''.join(payload_segments)
|
|
print(f"\ntotal b64: {len(complete_b64)} chars")
|
|
|
|
encrypted_data = base64.b64decode(complete_b64)
|
|
print(f"decoded: {len(encrypted_data)} bytes")
|
|
|
|
aes_key = bytes([150,182,100,248,129,91,226,48,131,19,150,255,147,141,114,162,91,237,159,83,174,199,218,120,251,42,139,22,30,130,227,189])
|
|
|
|
iv = encrypted_data[:16]
|
|
ciphertext = encrypted_data[16:]
|
|
|
|
print(f"\niv: {iv.hex()}")
|
|
print(f"ciphertext: {len(ciphertext)} bytes")
|
|
|
|
cipher = AES.new(aes_key, AES.MODE_CBC, iv)
|
|
complete_blocks = (len(ciphertext) // 16) * 16
|
|
if complete_blocks < len(ciphertext):
|
|
print(f"truncating {len(ciphertext) - complete_blocks} bytes")
|
|
ciphertext = ciphertext[:complete_blocks]
|
|
|
|
decrypted = cipher.decrypt(ciphertext)
|
|
|
|
try:
|
|
decrypted_unpadded = unpad(decrypted, AES.block_size)
|
|
print(f"removed padding: {len(decrypted)} -> {len(decrypted_unpadded)} bytes")
|
|
decrypted = decrypted_unpadded
|
|
except:
|
|
print(f"no padding found")
|
|
|
|
print(f"\ndone")
|
|
print(f"size: {len(decrypted)} bytes")
|
|
print(f"first 16: {decrypted[:16].hex()}")
|
|
print(f"first 2: {decrypted[:2]}")
|
|
|
|
if decrypted[:2] == b'MZ':
|
|
print(f"\nit's a PE!")
|
|
|
|
Path('payTheload.bin').write_bytes(decrypted)
|
|
print(f"saved to payTheload.bin")
|
|
|
|
print(f"\ninfo:")
|
|
print(f" sig: {decrypted[:2]}")
|
|
print(f" size: {len(decrypted)} bytes ({len(decrypted)/1024:.1f} KB)")
|
|
|
|
strings = []
|
|
current = b''
|
|
for byte in decrypted[:5000]:
|
|
if 32 <= byte < 127:
|
|
current += bytes([byte])
|
|
else:
|
|
if len(current) >= 5:
|
|
try:
|
|
strings.append(current.decode('ascii'))
|
|
except:
|
|
pass
|
|
current = b''
|
|
|
|
if strings:
|
|
print(f"\nstrings:")
|
|
for s in strings[:20]:
|
|
print(f" {s}")
|
|
else:
|
|
print(f"\nnot a PE")
|
|
print(f"got: {decrypted[:2].hex()} (wanted: 4d5a)")
|
|
print(f"order still wrong maybe?")
|
|
|
|
print("\n" + "=" * 80)
|