task1.out (re2)
task1.out (re2)
Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: decoy_detection, hash_collision, static_disassembly, xor_decryption
Summary
Walkthrough of the CUSTOM Reversing task1.out (re2). A 32-bit ELF binary with a decoy flag string. The program validates input through a custom XOR-based hash function and decrypts the real flag when the correct hash is provided.
Description
Language: C. Download binary: task1.out (ELF 32-bit) / task1.exe (PE32). The task expects a string as command line argument, and checks it. Complete the checks, and app will print the flag.
A 32-bit ELF binary with a decoy flag string. The program validates input through a custom XOR-based hash function and decrypts the real flag when the correct hash is provided.
Analysis
Step 1 - Reconnaissance
bash read-only • copy allowed$ file task1.out task1.out: ELF 32-bit LSB executable, Intel 80386, dynamically linked, not stripped $ strings task1.out FLAG{123REALFLAG!!!} # Decoy! What? Ok, you are wrong Not enough!
Symbol table reveals 4 custom functions: main, decode, hashf, dwords_count.
Step 2 - Function Analysis
dwords_count(str): Returns strlen(str) / 4 — number of 32-bit dwords in the string.
hashf(str): Custom XOR hash function:
- Starts with seed
hash = 0xCAFEDEAD - XORs each 4-byte dword of the string into the accumulator
hash = 0xCAFEDEAD ^ dword[0] ^ dword[1] ^ ... ^ dword[n-1]
decode(buf, key): XOR-decodes each dword of buf with the 32-bit key value in-place.
main(argc, argv):
- Checks
argc > 1, otherwise prints "Not enough!" and exits - Checks
strlen(argv[1]) % 4 == 0, otherwise prints "What?" and exits - Compares
argv[1]with decoy string"FLAG{123REALFLAG!!!}"usingstrcmp- If equal: prints "Ok, you are wrong" and exits (trap!)
- If input is not equal to decoy, computes
hashf(input)andhashf("FLAG{123REALFLAG!!!") - If hashes match: loads encrypted flag bytes, calls
decode(), prints result
Step 3 - The Decoy Trap
The key insight is that the obvious answer "FLAG{123REALFLAG!!!}" is explicitly rejected! The program wants an input that:
- Has length divisible by 4
- Is NOT equal to the decoy string
- Has the SAME XOR hash as the decoy
Since XOR is commutative and associative, swapping any two 4-byte chunks produces the same hash.
Solution
Static Decryption
Compute hashf("FLAG{123REALFLAG!!!"):
| Chunk | Bytes | Dword (LE) |
|---|---|---|
| "FLAG" | 46 4C 41 47 | 0x47414C46 |
| "{123" | 7B 31 32 33 | 0x3332317B |
| "REAL" | 52 45 41 4C | 0x4C414552 |
| "FLAG" | 46 4C 41 47 | 0x47414C46 |
| "!!!}" | 21 21 21 7D | 0x7D212121 |
| |
hash = 0xCAFEDEAD ^ 0x47414C46 ^ 0x3332317B ^ 0x4C414552 ^ 0x47414C46 ^ 0x7D212121
hash = 0xC8AC8BA5
XOR encrypted dwords with hash to get flag:
| Encrypted | XOR 0xC8AC8BA5 | ASCII |
|---|---|---|
| 0x8FEDC7E3 | 0x47414C46 | "FLAG" |
| 0x81E4DFDE | 0x4948547B | "{THI" |
| 0x9BE5D4F6 | 0x53495F53 | "S_IS" |
| 0x97F5C6FA | 0x5F594D5F | "MY" |
| 0xB5F5CEEE | 0x7D59454B | "KEY}" |
python read-only • copy allowed#!/usr/bin/env python3 import struct # hashf("FLAG{123REALFLAG!!!}") reference = b"FLAG{123REALFLAG!!!}" hash_val = 0xCAFEDEAD for i in range(len(reference) // 4): dword = struct.unpack('<I', reference[i*4:(i+1)*4])[0] hash_val ^= dword print(f"Hash: 0x{hash_val:08X}") # 0xC8AC8BA5 # Encrypted flag dwords from binary encrypted_dwords = [0x8FEDC7E3, 0x81E4DFDE, 0x9BE5D4F6, 0x97F5C6FA, 0xB5F5CEEE] # Decode by XORing with hash flag_bytes = b'' for d in encrypted_dwords: flag_bytes += struct.pack('<I', d ^ hash_val) print(f"Flag: {flag_bytes.decode()}") # FLAG{REDACTED}
Dynamic Verification (Alternative)
To run the binary and get the flag dynamically, provide an input with the same hash but different string. Swap two dwords:
bash read-only • copy allowed# Swap "FLAG" and "{123" chunks ./task1.out '{123FLAGREALFLAG!!!}' # Prints: FLAG{REDACTED}
Key Takeaways / Lessons
- Mastering decoy_detection, hash_collision, static_disassembly, xor_decryption was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-03-09 • CUSTOM • task1.out (re2) • Difficulty: Easy