# 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

1. **Main Function Analysis**: The program reads input via `fgets()` and validates it using `sub_401367()`.
2. **Validation Logic**: The validation function `sub_401367()` checks:

   - Input length must be exactly 53 characters
   - Calls `sub_4011B6()` and `sub_40120D()` (these appear to be initialization functions)
   - For each position `i` from 0 to 52, checks:

     ```
     if (sub_4012BC(i) ^ input[permutation[i]] != target_xor[i]) return 0;
     ```
   - Where `permutation` is an array at address `0x402040` and `target_xor` is at `0x402080`
3. **Key Function `sub_4012BC()`**: This function generates a key byte for each position `i` using:

   - Initial values: `v6 = 92`, `v5 = -46`, `v4 = 359969064`
   - Loop from 0 to `i`:

     - `v6 -= 4`
     - `v5 += i * i`
     - `v4 = ROL4(v4, i & 7)` (rotate left 32-bit)
   - Final calculation:

```
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:

1. Implements the `sub_4012BC()` function logic
2. Extracts the permutation and target XOR arrays from the binary
3. Computes the correct input by solving the XOR equation
4. 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".
