TrueSecrets
hackthebox
Our cybercrime unit has been investigating a well-known APT group for several months. The group has been responsible for several high-profile attacks on corporate organizations. However, what is interesting about that case, is that they have developed a custom command & control server of their own.
$ ls tags/ techniques/
TrueSecrets — HackTheBox
Description
Our cybercrime unit has been investigating a well-known APT group for several months. The group has been responsible for several high-profile attacks on corporate organizations. However, what is interesting about that case, is that they have developed a custom command & control server of their own. Fortunately, our unit was able to raid the home of the leader of the APT group and take a memory capture of his computer while it was still powered on. Analyze the capture to try to find the source code of the server.
Files
TrueSecrets.raw— 200MB Windows memory dump (extracted from ZIP with passwordhackthebox)
Analysis
Step 1: Initial Analysis — OS Identification
Used Volatility3 windows.info to identify the system:
- Windows 7 SP1 32-bit (build 7601)
python3 -m volatility3 -f TrueSecrets.raw windows.info
Step 2: Process Analysis
Ran windows.pslist and identified key processes:
| PID | Process | Significance |
|---|---|---|
| 2128 | TrueCrypt.exe | TrueCrypt disk encryption — the challenge name hint |
| 2176 | 7zFM.exe | 7-Zip, opened backup_development.zip |
| 3212 | DumpIt.exe | Memory acquisition tool |
python3 -m volatility3 -f TrueSecrets.raw windows.pslist
Step 3: File Discovery & Extraction
Ran windows.filescan and found two critical files:
| Offset | File |
|---|---|
| 0xbbf6158 | \Users\IEUser\Documents\backup_development.zip |
| 0xc50c550 | \Users\IEUser\Documents\development.tc |
Extracted backup_development.zip (304KB) from memory:
python3 -m volatility3 -f TrueSecrets.raw windows.dumpfiles --virtaddr 0xbbf6158
Unzipped to get development.tc — a 300KB TrueCrypt encrypted container.
Step 4: TrueCrypt Password Recovery from Process Memory
This is the critical step. TrueCrypt caches passwords in process memory as a struct:
- 4-byte length field + password bytes (up to 64) + null padding
Dumped TrueCrypt process memory (PID 2128):
python3 -m volatility3 -f TrueSecrets.raw windows.memmap --pid 2128 --dump
This produced a 69MB process dump. Wrote a Python script to scan for the cached password pattern:
#!/usr/bin/env python3 """Scan TrueCrypt process memory for cached password struct.""" import struct with open("pid.2128.dmp", "rb") as f: data = f.read() for i in range(len(data) - 68): length = struct.unpack_from("<I", data, i)[0] if 4 <= length <= 30: candidate = data[i+4:i+4+length] padding = data[i+4+length:i+68] if all(32 <= b < 127 for b in candidate) and padding.count(b'\x00') > len(padding) * 0.9: print(f"Offset {i:#x}: length={length}, password={candidate.decode()}")
Recovered password: X2Hk2XbEJqWYsh8VdbSYg6WpG9g7
Step 5: TrueCrypt Container Decryption
No TrueCrypt CLI available, so wrote a custom Python decryption script implementing the full TrueCrypt decryption chain:
#!/usr/bin/env python3 """Custom TrueCrypt container decryption (AES-256-XTS).""" from Crypto.Cipher import AES from Crypto.Protocol.KDF import PBKDF2 from Crypto.Hash import SHA512, HMAC import struct password = b"X2Hk2XbEJqWYsh8VdbSYg6WpG9g7" with open("development.tc", "rb") as f: container = f.read() # TrueCrypt header structure: # Bytes 0-63: Salt # Bytes 64-511: Encrypted header salt = container[:64] enc_header = container[64:512] # Derive header key: PBKDF2-HMAC-SHA512, 1000 iterations, 128 bytes output header_key = PBKDF2( password, salt, dkLen=128, count=1000, prf=lambda p, s: HMAC.new(p, s, SHA512).digest() ) # Decrypt header with AES-256-XTS (first 64 bytes of derived key) key1 = header_key[:32] # AES key key2 = header_key[32:64] # XTS tweak key cipher = AES.new(key1 + key2, AES.MODE_XTS) dec_header = cipher.decrypt(enc_header) # Verify: first 4 bytes should be "TRUE" assert dec_header[:4] == b"TRUE", "Decryption failed!" # Extract master key (64 bytes at offset 192) master_key = dec_header[192:256] # Volume metadata from header data_offset = struct.unpack_from(">Q", dec_header, 28)[0] # 131072 data_size = struct.unpack_from(">Q", dec_header, 36)[0] # 45056 # Decrypt data area sector-by-sector (512-byte sectors) data_area = container[data_offset:data_offset + data_size] decrypted = bytearray() mk1 = master_key[:32] mk2 = master_key[32:64] for sector_num in range(len(data_area) // 512): sector_data = data_area[sector_num * 512:(sector_num + 1) * 512] tweak = struct.pack("<QQ", sector_num, 0) # 16-byte tweak cipher = AES.new(mk1 + mk2, AES.MODE_XTS, tweak=tweak) decrypted.extend(cipher.decrypt(sector_data)) with open("decrypted_volume.img", "wb") as f: f.write(decrypted)
The decrypted volume was identified as a FAT12 filesystem.
Step 6: Filesystem Extraction
Used 7-Zip to extract the FAT12 image:
7z x decrypted_volume.img
Contents:
malware_agent/
AgentServer.cs # C2 server source code (C#)
sessions/
5818acbe-68f1-4176-a2f2-8c6bcb99f9fa.log.enc
c65939ad-5d17-43d5-9c3a-29c6a7c31a32.log.enc
de008160-66e4-4d51-8264-21cbc27661fc.log.enc
Step 7: C2 Source Code Analysis
AgentServer.cs is a C# TCP C2 server listening on port 40001:
- Receives commands from operator, sends to infected machines
- Receives output, encrypts and logs everything
- Encryption: DES-CBC with hardcoded keys:
- Key:
AKaPdSgV(8 bytes) - IV:
QeThWmYq(8 bytes)
- Key:
- Logs are base64-encoded after DES encryption, written to
.log.encfiles
Step 8: Session Log Decryption
#!/usr/bin/env python3 """Decrypt C2 session logs (DES-CBC + Base64).""" from Crypto.Cipher import DES import base64 import os KEY = b"AKaPdSgV" IV = b"QeThWmYq" def decrypt_line(b64_line): ct = base64.b64decode(b64_line.strip()) cipher = DES.new(KEY, DES.MODE_CBC, IV) pt = cipher.decrypt(ct) # Remove PKCS7 padding pad_len = pt[-1] return pt[:-pad_len].decode('utf-8', errors='replace') for logfile in sorted(os.listdir("sessions")): if not logfile.endswith(".log.enc"): continue print(f"\n=== {logfile} ===") with open(f"sessions/{logfile}") as f: for line in f: line = line.strip() if line: print(decrypt_line(line))
Results:
| Session | User | Commands | Finding |
|---|---|---|---|
| 1 | john | hostname, whoami, dir | No interesting files |
| 2 | paul | hostname, whoami, dir | No interesting files |
| 3 | greg | hostname, whoami, dir, type flag.txt | FLAG found! |
Session 3 (greg) contained:
> type c:\users\greg\documents\flag.txt
HTB{570r1ng_53cr37_1n_m3m0ry_15_n07_g00d}
Attack Chain Summary
Memory dump (TrueSecrets.raw)
|
v
Volatility3: pslist -> find TrueCrypt.exe (PID 2128)
|
v
Volatility3: filescan -> find backup_development.zip & development.tc
|
v
Volatility3: dumpfiles -> extract backup_development.zip -> development.tc
|
v
Volatility3: memmap --pid 2128 -> dump TrueCrypt process memory
|
v
Pattern scan -> recover cached password: X2Hk2XbEJqWYsh8VdbSYg6WpG9g7
|
v
Custom PBKDF2-HMAC-SHA512 + AES-256-XTS decryption -> FAT12 volume
|
v
7z extract -> AgentServer.cs (C2 source) + encrypted session logs
|
v
Source code analysis -> DES-CBC key/IV: AKaPdSgV / QeThWmYq
|
v
DES-CBC + Base64 decrypt session logs -> flag in greg's session
Key Indicators
Use these techniques when you see:
- TrueCrypt.exe in process list of a memory dump
.tcfile extension — TrueCrypt encrypted container- Challenge name hinting at "True" + "Secrets" (TrueCrypt)
- Need to recover encryption passwords from process memory (cached credentials)
- C# source code with hardcoded DES/AES keys
- Base64-encoded encrypted log files
Key Insight
The flag message "storing secret in memory is not good" (570r1ng_53cr37_1n_m3m0ry_15_n07_g00d) reinforces the core vulnerability: TrueCrypt caches the volume password in process memory while the container is mounted. A memory dump captures this cached password, allowing full decryption of the container without brute-forcing. This is a fundamental limitation of full-disk encryption when the system is powered on.
$ cat /etc/motd
Liked this one?
Pro unlocks every writeup, every flag, and API access. $9/mo.
$ cat pricing.md$ grep --similar
Similar writeups
- [mobile][free]Protected— HackTheBox
- [forensics][Pro]Stockpile Breach— 0xl4ugh
- [forensics][Pro]Advanced Packaged Threat— scarlet
- [misc][Pro]Who4reu— TaipanByte
- [reverse][Pro]Challenge7— tamuctf