← Back to Writeups
CUSTOMEasyReversing

Const

XESXOR9/2/20262 min read
#reversing#custom#easy#static_analysis#objdump_disassembly#constructor_identification#swap_tracing#init_array_analysis

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
file 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

  1. Reads user input via fgets(buf, 255, stdin)
  2. Removes trailing newline
  3. Compares input with the (already modified) flag via strcmp
  4. On match, outputs "OK!"

Solution

python
#!/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