← Back to Writeups
CUSTOMMediumMisc

Who4reu

XESXOR9/2/20263 min read
#misc#custom#medium#alert_override#array_shuffle_pattern#base32_decoding#js_deobfuscation#wim_extraction#windows

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
$ 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
$ strings 2.tb | head -20
# Obfuscated JS code found

3. Obfuscation Structure

The obfuscated JavaScript uses a typical pattern:

  1. String array — the _0x5ae5 function returns an array with scrambled elements: '987870zOeAGi', 'SWY3BQL4YX', 'NZ6Q====', 'MZWGCZ33NB', etc. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

  2. Shuffle function — an IIFE (Immediately Invoked Function Expression) that rotates the array via push/shift until the checksum matches the expected value.

  3. Lookup function — _0x3981 maps hex indices to elements of the shuffled array.

  4. Payload — an alert() call concatenating 5 strings from the array:

    javascript
    alert(_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
#!/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
node -e "global.alert = console.log; $(cat code.js)"

Output:

MZWGCZ33NBSWY3BQL4YXI427GBRGM5LTMM2HIMLPNZ6Q====

Step 3: Decode Base32

bash
echo "MZWGCZ33NBSWY3BQL4YXI427GBRGM5LTMM2HIMLPNZ6Q====" | base32 -d

Result: flag{REDACTED}

Complete Solution Script

python
#!/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}

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍