# HuntMe2

```
The trail doesn’t stay still. The forest shifts, and the signs no longer speak plainly. What was once hidden in plain sight is now layered behind changing patterns.

Author : N!L
```

Attack script written by AI agent:

```
#!/usr/bin/env python3

# Data from the binary
byte_402060 = [
    0xf8, 0x98, 0x76, 0xfb, 0xc9, 0x0a, 0x03, 0x0d,
    0x44, 0x3d, 0x6b, 0xa6, 0xc3, 0x25, 0xa8, 0x60,
    0xfb, 0x57, 0x6c, 0xf3, 0xa1, 0xf0, 0xcf, 0x61,
    0xe6, 0xe4, 0x45, 0x16, 0x0e, 0x18, 0x3e, 0x27
]

# The arrays at unk_402020 (5 arrays of 7 bytes each based on the code)
# From address 0x402020, we have data. Looking at the code, v2[0] = &unk_402020,
# v2[1] = &unk_402027, v2[2] = &unk_40202E, v2[3] = &unk_402035, v2[4] = &unk_40203C
# So each is 7 bytes apart (0x402027 - 0x402020 = 7)

data_at_402020 = [
    0xa8, 0xc5, 0x83, 0xa0, 0x42, 0x2c, 0x01,  # array 0
    0xcb, 0x32, 0x20, 0xf3, 0xcf, 0x65, 0xbc,  # array 1  
    0x13, 0x79, 0xb2, 0x29, 0x74, 0x61, 0xe7,  # array 2
    0xa7, 0x68, 0x76, 0x0a, 0x4e, 0x39, 0x43,  # array 3
    0xf1, 0xcd, 0x12, 0xb2, 0x7d, 0x0b, 0x2d   # array 4
]

def sub_401201(a1, a2):
    # return (unsigned __int8)((61 * a2) ^ ((unsigned __int8)((8 * a1) ^ a1) >> 5) ^ (8 * a1) ^ a1);
    temp = ((8 * a1) ^ a1) & 0xFF
    return ((61 * a2) ^ (temp >> 5) ^ temp) & 0xFF

def sub_401239(a1):
    # a1 is the index (0-31)
    v6 = 0
    arrays = []
    for i in range(5):
        arrays.append(data_at_402020[i*7:(i+1)*7])

    for i in range(5):
        v4 = arrays[i]  # pointer to array
        v3 = (a1 * (i + 1) + i * i + 3) % 7
        v6 ^= v4[v3]
        v6 = ((2 * v6) | (v6 >> 7)) & 0xFF

    return sub_401201(v6, a1)

def compute_target():
    # We need to find input[i] such that: sub_401239(i) ^ input[i] == byte_402060[i]
    # So input[i] = sub_401239(i) ^ byte_402060[i]
    flag = []
    for i in range(32):
        val = sub_401239(i)
        flag_char = val ^ byte_402060[i]
        flag.append(flag_char)

    return bytes(flag)

if __name__ == "__main__":
    flag = compute_target()
    print(f"Flag: {flag}")
    print(f"Flag (string): {flag.decode('ascii', errors='ignore')}")

    # Test by running through the algorithm
    print("\nTesting...")
    for i in range(32):
        val = sub_401239(i)
        computed = val ^ flag[i]
        if computed != byte_402060[i]:
            print(f"Mismatch at index {i}: {computed:02x} != {byte_402060[i]:02x}")
        else:
            print(f"Index {i}: OK")
```

Writeup written by AI agent:

# HuntMe2 CTF Challenge Solution

## Challenge Analysis

The binary `HuntMe2` is a 64-bit ELF executable that validates a 32-character input flag. The validation algorithm involves:

1. **Input Length Check**: The input must be exactly 32 characters.
2. **Complex Transformation**: Each character at position `i` (0-31) undergoes a transformation through `sub_401239(i)`.
3. **XOR Comparison**: The transformed value is XORed with the input character and compared against a hardcoded byte array `byte_402060`.

## Algorithm Details

### Main Validation (sub\_40132A)

- Checks input length == 32
- Calls `sub_401176()` (doesn't affect validation, just computes a value)
- For each position `i` (0-31):

  - Computes `sub_401239(i)`
  - Requires: `sub_401239(i) ^ input[i] == byte_402060[i]`
  - Therefore: `input[i] = sub_401239(i) ^ byte_402060[i]`

### Transformation Function (sub\_401239)

Takes index `i` and returns a byte:

1. Uses 5 arrays of 7 bytes each starting at `0x402020`
2. For each array `j` (0-4):

   - Computes index: `(i * (j+1) + j*j + 3) % 7`
   - XORs the byte at that index into accumulator `v6`
   - Rotates `v6` left by 1 bit: `v6 = (2 * v6) | (v6 >> 7)`
3. Passes result through `sub_401201(v6, i)`

### Final Transformation (sub\_401201)

- `return (61 * i) ^ (((8 * v6) ^ v6) >> 5) ^ ((8 * v6) ^ v6)`

## Solution Approach

The solution involves:

1. Extracting the hardcoded data from the binary:

   - `byte_402060` (32 bytes): target XOR results
   - Arrays at `0x402020` (35 bytes, organized as 5x7 arrays)
2. Implementing the transformation algorithm in Python
3. Computing the required input: `input[i] = sub_401239(i) ^ byte_402060[i]`

## Flag

`nexus{f0ll0w_7h3_ch4ng1ng_7r41l}`

## How to Test

```
echo -n "nexus{f0ll0w_7h3_ch4ng1ng_7r41l}" | ./HuntMe2
```

Output: "You adapt. The hunt continues."

## Tools Used

- Python for implementing the reverse algorithm
- Standard Linux tools (file, strings, etc.)
