Who4reu
Who4reu
Platform: TaipanByte | Category: Misc | Type: Challenge | Difficulty: Medium | OS: Windows | Author: XESXOR | Date: 2026-02-14 | Status: Solved Techniques: alert_override, array_shuffle_pattern, base32_decoding, js_deobfuscation, wim_extraction
Summary
The challenge provides a file 2.tb (3329 bytes). The name "Who4reu" ("Who are you") hints that the file contents hide their true nature behind layers of obfuscation and encoding.
Who4reu — TaipanByte
Description
The challenge provides a file 2.tb (3329 bytes). The name "Who4reu" ("Who are you") hints that the file contents hide their true nature behind layers of obfuscation and encoding.
Flag format: flag{...}
Analysis
1. File Format Identification
The file command identifies the file as "Windows imaging (WIM) image v1.13". A hex dump confirms the MSWIM magic bytes at the beginning:
bash read-only • copy allowed$ file 2.tb 2.tb: Windows imaging (WIM) image v1.13 $ xxd 2.tb | head 00000000: 4d53 5749 4d00 0000 ... MSWIM...
2. Content Extraction
The strings command reveals obfuscated JavaScript code inside the WIM container. The WIM XML metadata at the end of the file indicates a single file 2.py (2075 bytes). Despite the .py extension, the content is JavaScript.
bash read-only • copy allowed$ strings 2.tb | head -20 # Obfuscated JS code found
3. Obfuscation Structure
The obfuscated JavaScript uses a typical pattern:
-
String array — the
_0x5ae5function returns an array with scrambled elements:'987870zOeAGi','SWY3BQL4YX','NZ6Q====','MZWGCZ33NB', etc. -
Shuffle function — an IIFE (Immediately Invoked Function Expression) that rotates the array via
push/shiftuntil the checksum matches the expected value. -
Lookup function —
_0x3981maps hex indices to elements of the shuffled array. -
Payload — an
alert()call concatenating 5 strings from the array:javascript read-only • copy allowedalert(_0x1b1606(0xcc) + _0x1b1606(0xd1) + _0x1b1606(0xc4) + _0x1b1606(0xc5) + _0x1b1606(0xcb))
4. Base32 in Output
The JS execution result is a string with characteristic ==== padding, indicating Base32 encoding.
Solution
Step 1: Extract JS from WIM File
python read-only • copy allowed#!/usr/bin/env python3 """Extract JavaScript code from WIM container.""" with open('2.tb', 'rb') as f: data = f.read() # Find the start of JS code (look for characteristic patterns) # Code starts after WIM header js_start = data.find(b'var _0x') if js_start == -1: js_start = data.find(b'function') js_end = data.rfind(b');') + 2 js_code = data[js_start:js_end].decode('utf-8', errors='ignore') with open('code.js', 'w') as f: f.write(js_code) print(f"Extracted {len(js_code)} bytes of JS code")
Step 2: Execute Obfuscated JS
Replace alert with console.log for execution in Node.js:
bash read-only • copy allowednode -e "global.alert = console.log; $(cat code.js)"
Output:
MZWGCZ33NBSWY3BQL4YXI427GBRGM5LTMM2HIMLPNZ6Q====
Step 3: Decode Base32
bash read-only • copy allowedecho "MZWGCZ33NBSWY3BQL4YXI427GBRGM5LTMM2HIMLPNZ6Q====" | base32 -d
Result: flag{REDACTED}
Complete Solution Script
python read-only • copy allowed#!/usr/bin/env python3 """ Who4reu — TaipanByte CTF WIM file → JS deobfuscation → Base32 decode """ import subprocess import base64 import base64 # 1. Extract JS from WIM with open('2.tb', 'rb') as f: data = f.read() js_start = data.find(b'var _0x') if js_start == -1: js_start = data.find(b'function') js_end = data.rfind(b');') + 2 js_code = data[js_start:js_end].decode('utf-8', errors='ignore') # 2. Execute JS with alert → console.log replacement result = subprocess.run( ['node', '-e', f'global.alert = console.log; {js_code}'], capture_output=True, text=True ) b32_string = result.stdout.strip() print(f"JS output: {b32_string}") # 3. Decode Base32 import base64 flag = base64.b32decode(b32_string).decode() print(f"Flag: {flag}") # Flag: flag{REDACTED}