← Back to Writeups
CUSTOMEasyReversing

Signalization Two

XESXOR9/10/20262 min read
#reversing#custom#easy#signal_handler_analysis#stack_string_reconstruction#static_analysis#linux

Signalization Two

Platform: spbctf | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-03-26 | Status: Solved Techniques: signal_handler_analysis, stack_string_reconstruction, static_analysis

Summary

Task: a 64-bit Linux ELF registers a signal handler and then waits for input, hiding the flag path behind SIGINT. Solution: identify signal 2 as SIGINT, inspect the handler, and reconstruct the stack string after three intentional byte overwrites.

Signalization Two — spbctf

Description

ELF64 Linux binary from rev-kids20 that reacts to a signal instead of normal input.

The challenge binary does not reveal the flag through the regular input path. Instead, the useful logic is hidden in a signal handler that runs only when the process receives the correct signal.

Summary

The binary calls signal(2, handler) in main, then blocks in fgets(). On Linux, signal number 2 is SIGINT, so pressing Ctrl+C triggers the handler, which builds a flag-like string on the stack and prints it with puts(). Static analysis shows the template Flag{This Is Simple} is intentionally modified at three positions, producing the real output Flag{REDACTED}. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Analysis

The important control flow is very small:

  1. main registers a handler with signal(2, handler).
  2. The program then waits in fgets().
  3. While it is blocked, sending SIGINT runs the custom handler.

On Linux, signal number 2 is SIGINT, which is exactly what Ctrl+C sends to a foreground terminal process. That makes this a signal-triggered flag reveal instead of a normal input-validation task.

Inside the handler, the binary constructs a string on the stack and prints it via puts(). The base string is clearly: ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

text
Flag{This Is Simple}

But three bytes are overwritten before printing:

  • h → *
  • I → 1
  • s → 4

Applying those changes gives the final printed string:

text
Flag{REDACTED}

Solution

Dynamic idea

On a Linux machine, the intended behavior can be reproduced directly:

bash
chmod +x signalization2.elf
./signalization2.elf
# press Ctrl+C

Because the program is waiting in fgets(), Ctrl+C delivers SIGINT and transfers execution into the registered handler, which prints the flag. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Static solution path

If you solve it statically:

  1. Open main in a disassembler.
  2. Notice the call to signal(2, handler).
  3. Map signal 2 to SIGINT on Linux.
  4. Inspect handler and reconstruct the stack string.
  5. Account for the three byte overwrites.

Minimal reconstruction script:

python
#!/usr/bin/env python3

flag = list("Flag{This Is Simple}")
flag[6] = '*'   # h -> *
flag[10] = '1'  # I -> 1
flag[11] = '4'  # s -> 4

print(''.join(flag))

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍