Const
Const
Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: static_analysis, objdump_disassembly, constructor_identification, swap_tracing, init_array_analysis
Summary
Walkthrough of the CUSTOM Reversing Const. ELF 64-bit LSB PIE executable, x86-64, dynamically linked, not stripped. A task about understanding the constructor mechanism in C and analyzing data modification before main() execution.
Description
ELF 64-bit LSB PIE executable, x86-64, dynamically linked, not stripped. A task about understanding the constructor mechanism in C and analyzing data modification before main() execution.
Analysis
Initial Reconnaissance
bash read-only • copy allowedfile const.elf # ELF 64-bit LSB PIE executable, x86-64, dynamically linked, not stripped strings const.elf | grep -i flag # Flag{This_is_definetly_a_flag} # Decoy flag in .data nm const.elf # 0000000000000857 T main # 00000000000007e0 T swaps # 0000000000201050 D flag
Key Observation
The task name "Const" is a hint at C constructors (__attribute__((constructor))). The swaps function is registered in the .init_array section, meaning it executes before main().
Source file in debug info: constructor.c
Disassembly of swaps Function (Constructor)
The function performs 3 swap/rotate operations on the string "Flag{This_is_definetly_a_flag}":
1. Swap flag[5] ↔ flag[14]: T ↔ e
Result: Flag{ehis_is_dTfinetly_a_flag}
2. 3-way rotate flag[20] → flag[21] → flag[7] → flag[20]:
flag[20] receives flag[21] (y)
flag[21] receives flag[7] (i)
flag[7] receives old flag[20] (l)
Result: Flag{REDACTEDtyi_a_flag}
3. Swap flag[19] ↔ flag[20]: t ↔ y
Result: Flag{REDACTED}
Main Function
- Reads user input via
fgets(buf, 255, stdin) - Removes trailing newline
- Compares input with the (already modified)
flagviastrcmp - On match, outputs
"OK!"
Solution
python read-only • copy allowed#!/usr/bin/env python3 """ Const — spbctf reverse Emulating constructor swaps operations on the flag """ # Original (decoy) flag from .data section flag = list("Flag{This_is_definetly_a_flag}") print(f"Original: {''.join(flag)}") # Swap 1: flag[5] <-> flag[14] flag[5], flag[14] = flag[14], flag[5] print(f"After swap 1 (5<->14): {''.join(flag)}") # 3-way rotate: temp=flag[20], flag[20]=flag[21], flag[21]=flag[7], flag[7]=temp temp = flag[20] flag[20] = flag[21] flag[21] = flag[7] flag[7] = temp print(f"After rotate (20->21->7->20): {''.join(flag)}") # Swap 3: flag[19] <-> flag[20] flag[19], flag[20] = flag[20], flag[19] print(f"After swap 3 (19<->20): {''.join(flag)}") print(f"\nFinal flag: {''.join(flag)}")
Output:
Original: Flag{This_is_definetly_a_flag}
After swap 1 (5<->14): Flag{ehis_is_dTfinetly_a_flag}
After rotate (20->21->7->20): Flag{REDACTEDtyi_a_flag}
After swap 3 (19<->20): Flag{REDACTED}
Final flag: Flag{REDACTED}
Key Takeaways / Lessons
- Mastering static_analysis, objdump_disassembly, constructor_identification, swap_tracing, init_array_analysis was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2026-03-11 • CUSTOM • Const • Difficulty: Easy