Movfuscator
Movfuscator
Platform: spbctf | Category: Reversing | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-06-08 | Status: Solved Techniques: reverse_engineering, hidden_code_recovery, static_disassembly, transformation_inversion
Summary
Task: a static stripped ELF pretends to contain only repeated mov rcx, imm64 instructions, hiding the real checker inside immediate payload bytes. Solution: start disassembly at the hidden entrypoint, recover the in-place buf[i] -= i transform and embedded target bytes, then invert the transform to obtain the accepted input and final flag.
Movfuscator — spbctf
Description
Have you heard about the MoVfuscator? It turns any code into a set of just mov instructions! It's kinda magic!
The binary is a 64-bit ELF that looks intentionally misleading: normal disassembly only shows endless mov rcx, imm64 instructions. The goal is to recover the hidden checker logic and derive the accepted input.
Analysis
The first useful clue is the file layout: the ELF is static, stripped, and effectively exposes only a .text section. A naive disassembly is almost useless because it keeps decoding the file as repeated mov rcx, imm64 instructions.
That is the trick. The real code does not start at the obvious instruction boundaries. It starts at 0x400082, which lands inside the immediate bytes of the first movabs rcx, imm64. From that offset, recursive disassembly reveals a normal x86-64 checker.
The recovered logic is straightforward:
- Print the prompt
Enter string to check >. - Read up to
0x3fbytes into a stack buffer. - NUL-terminate the input and remove a trailing newline if present.
- Transform the buffer in place with:
c read-only • copy allowedbuf[i] = buf[i] - i;
- Compare the transformed bytes against an embedded constant stored on the stack:
text read-only • copy allowed74 32 66 5c 69 44 41 41 6c 50 55 62 24 62 41 21 66 22 33 5f 3e 00
This is a 21-byte target plus the terminating NUL. Therefore the original input must satisfy:
text read-only • copy allowedinput[i] - i = target[i] input[i] = target[i] + i
Applying that inversion yields:
text read-only • copy allowedREDACTED
The success path restores the modified buffer and prints it inside the flag format, so the final flag is spbctf{REDACTED}.
Solution
- Ignore the fake top-level
mov rcx, imm64disassembly. - Start disassembling from the hidden entrypoint at
0x400082. - Recover the input handling and the transformation loop
buf[i] -= i. - Extract the embedded comparison bytes.
- Invert the transform by adding the index back to each byte.
- Submit the recovered string; the program prints
spbctf{<input>}on success.
python read-only • copy allowed#!/usr/bin/env python3 target = bytes.fromhex( "74 32 66 5c 69 44 41 41 6c 50 55 62 24 62 41 21 66 22 33 5f 3e" ) candidate = ''.join(chr(b + i) for i, b in enumerate(target)) print(candidate) print(f"spbctf{{{candidate}}}")
Output:
text read-only • copy allowedREDACTED spbctf{REDACTED}