HuntMe3
The forest is no longer just watched.
Now, every step you take is measured.
Every wrong move is quietly absorbed by the trees.
Only those who truly understand the pattern may pass.
Author : N!L
Attack script written by AI agent:
#!/usr/bin/env python3
# Data from the binary
permutation = [
0x2d, 0x2c, 0x32, 0x14, 0x6, 0x25, 0xf, 0x3, 0x22, 0x7,
0x2f, 0x23, 0x0, 0x31, 0x1c, 0x27, 0x10, 0x2, 0x30, 0xa,
0x2a, 0x16, 0x5, 0x12, 0x1d, 0x1, 0x9, 0x17, 0x1b, 0x1f,
0x1a, 0x8, 0xc, 0x24, 0x4, 0x20, 0x2e, 0x34, 0xb, 0x26,
0xe, 0x33, 0x15, 0x1e, 0x19, 0x29, 0x13, 0x11, 0x2b, 0x28,
0x21, 0xd, 0x18
]
target_xor = [
0xc7, 0x8e, 0xb, 0xe5, 0x23, 0x81, 0x18, 0x23, 0x27, 0xed,
0x6, 0xa1, 0x19, 0x30, 0x38, 0xd0, 0x2e, 0x66, 0xe2, 0x26,
0x6e, 0x23, 0xaa, 0xa1, 0x5d, 0x7d, 0x36, 0xe5, 0x6c, 0x6d,
0x35, 0xa0, 0x34, 0xc, 0xf9, 0x84, 0xd7, 0xc9, 0x5e, 0x56,
0xc2, 0xe9, 0x44, 0xe0, 0x77, 0x7b, 0x20, 0x78, 0x1f, 0xd9,
0x98, 0x85, 0xf5
]
# First, let's implement sub_4012BC based on the decompiled code
def sub_4012BC(a1):
"""Implementation of sub_4012BC from decompiled code"""
v6 = 92
v5 = -46 & 0xFF # Convert to unsigned byte
v4 = 359969064
for i in range(a1 + 1):
v6 = (v6 - 4) & 0xFF
v5 = (v5 + i * i) & 0xFF
# sub_4012A0 rotates left by (i & 7) bits
rotate_amount = i & 7
# ROL4 implementation
v4 = ((v4 << rotate_amount) | (v4 >> (32 - rotate_amount))) & 0xFFFFFFFF
# Calculate v2
rotated_v4 = (v4 >> (a1 & 7)) & 0xFF
xor_result = rotated_v4 ^ v5 ^ v6
v2 = ((8 * xor_result) ^ xor_result) & 0xFF
# Final result
return ((v2 >> 5) ^ v2) & 0xFF
# We also need to consider that sub_4011B6() and sub_40120D() are called before the loop
# These might modify global state. Let me check what they do
# From decompilation:
# sub_40120D() processes byte_4020E0 and byte_402100 arrays
# sub_4011B6() might also modify some state
# Let me check if there are any global variables being modified
# Looking at the decompiled sub_40120D, it returns a value but doesn't seem to modify globals
# sub_4011B6 is small (0x57 bytes)
# Actually, looking more carefully at the validation:
# if ( ((unsigned __int8)sub_4012BC(i) ^ a1[byte_402040[i]]) != byte_402080[i] )
# So we need: a1[permutation[i]] = sub_4012BC(i) ^ target_xor[i]
# Let's compute the flag
flag_chars = [0] * 53
for i in range(53):
key_byte = sub_4012BC(i)
target_index = permutation[i]
if target_index >= 53:
print(f"Warning: index {target_index} out of bounds at i={i}")
continue
flag_chars[target_index] = key_byte ^ target_xor[i]
# Convert to string
flag = ''.join(chr(c) for c in flag_chars)
print(f"Flag: {flag}")
print(f"Flag length: {len(flag)}")
print(f"Flag hex: {flag.encode().hex()}")
Writeup written by AI agent:
HuntMe3 CTF Challenge Solution
Challenge Analysis
This is a reverse engineering challenge where we need to find the correct 53-character input that passes validation.
Binary Analysis
The binary HuntMe3 is a 64-bit ELF executable with:
- Partial RELRO
- No stack canary
- NX enabled
- No PIE
- Stripped symbols
Reverse Engineering Process
- Main Function Analysis: The program reads input via
fgets()and validates it usingsub_401367(). - Validation Logic: The validation function
sub_401367()checks:- Input length must be exactly 53 characters
- Calls
sub_4011B6()andsub_40120D()(these appear to be initialization functions) - For each position
ifrom 0 to 52, checks:if (sub_4012BC(i) ^ input[permutation[i]] != target_xor[i]) return 0; - Where
permutationis an array at address0x402040andtarget_xoris at0x402080
- Key Function
sub_4012BC(): This function generates a key byte for each positioniusing:- Initial values:
v6 = 92,v5 = -46,v4 = 359969064 - Loop from 0 to
i:v6 -= 4v5 += i * iv4 = ROL4(v4, i & 7)(rotate left 32-bit)
- Final calculation:
- Initial values:
rotated_v4 = (v4 >> (i & 7)) & 0xFF
xor_result = rotated_v4 ^ v5 ^ v6
v2 = (8 * xor_result) ^ xor_result
result = (v2 >> 5) ^ v2
Solution
The solution involves reconstructing the input by solving:
input[permutation[i]] = sub_4012BC(i) ^ target_xor[i]
The permutation array maps each position i to an index in the input string, and target_xor contains the expected XOR result.
Flag
The flag is: nexus{thr33_hunt5_c0mpl3t3_th3_f0r3st_gr4nts_p4ss4g3}
Exploit Script
See solve.py for the complete solution implementation that:
- Implements the
sub_4012BC()function logic - Extracts the permutation and target XOR arrays from the binary
- Computes the correct input by solving the XOR equation
- Reconstructs the flag in the correct order using the permutation mapping
Testing
The flag was successfully tested with the binary:
echo "nexus{thr33_hunt5_c0mpl3t3_th3_f0r3st_gr4nts_p4ss4g3}" | ./HuntMe3
This produces the success message showing "THE FOREST RECOGNIZES ITS MASTER" and "CONGRATULATIONS, MASTER HUNTER".