← Back to Writeups
CUSTOMEasyReversing

0xF20B

XESXOR9/2/20262 min read
#reversing#custom#easy#import_table_analysis#memfrob_inversion#stack_constant_recovery#xor_0x2a

0xF20B

Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: import_table_analysis, memfrob_inversion, stack_constant_recovery, xor_0x2a

Summary

Walkthrough of the CUSTOM Reversing 0xF20B. Task: 32-bit stripped PIE ELF flag checker. memfrob in the import table obfuscates input with XOR 0x2A before comparing to a stack-built constant. Solution: recover the 27-byte target via radare2 and

Description

How did I hide the flag? >:-)

A 32-bit PIE ELF 0xF20B.elf (Intel 80386, dynamically linked, stripped). It prints Enter flag to check: , reads a string, and answers either Correct! Submit as the flag. or Wrong.. The flag is submitted to the platform (rev-kids20.forkbomb.ru) via POST flag. Goal: recover the input that makes the checker print "Correct!".

Analysis

file confirms a 32-bit Intel 80386 PIE, dynamically linked and stripped. Since it is stripped, there are no symbols for main, so analysis is done in radare2: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

r2 -A 0xF20B.elf
afl            # list functions, identify entry → main
pdf @ main     # disassemble main
ii             # list imports

The giveaway is in the import table: the binary imports glibc's memfrob. memfrob(buf, n) XORs each of n bytes with 0x2A (42) — and it is its own inverse (applying it twice returns the original). The title "0xF20B" and the taunt "how did I hide the flag?" both point straight at this trivial XOR obfuscation (FROBNICATE is exactly what memfrob does). ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

main builds a 27-byte target constant byte-by-byte on the stack (mov byte [var_124h..], 0x5d/0x42/...), then:

  1. scanf("%s", input)
  2. strlen(input)
  3. memfrob(input, len) — XORs each input byte with 0x2A
  4. strcmp(target, frobbed_input) → equal means "Correct!"

The 27 target bytes recovered from the stack stores:

5d 42 1e 1d 75 5e 42 19 75 62 19 66 66 75 43 59 75 6c 78 1a 68 64 1b 69 6b 7e 6f

Solution

The check is memfrob(input) == target. Because memfrob is XOR with 0x2A and self-inverse, the correct flag is simply memfrob(target) = each target byte XOR 0x2A. No need to run the binary at all: ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

python
#!/usr/bin/env python3
target = [0x5d,0x42,0x1e,0x1d,0x75,0x5e,0x42,0x19,0x75,0x62,0x19,0x66,0x66,
          0x75,0x43,0x59,0x75,0x6c,0x78,0x1a,0x68,0x64,0x1b,0x69,0x6b,0x7e,0x6f]
flag = ''.join(chr(b ^ 0x2A) for b in target)
print(flag)   # REDACTED

Output: REDACTED — reads as "what the HELL is FROBNICATE". The platform accepted both the bare value and the flag{...} wrapped form. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Key Takeaways / Lessons

  • Mastering import_table_analysis, memfrob_inversion, stack_constant_recovery, xor_0x2a was key to this challenge.
  • Always check for common misconfigurations and verify assumptions.

Crafted by XESXOR Research • 2026-06-15 • CUSTOM • 0xF20B • Difficulty: Easy