← Back to Writeups
CUSTOMEasyReversing

Signalization Eight

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

Signalization Eight

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

Summary

Task: a 64-bit non-stripped Linux ELF divides two numbers and hides the flag behind a signal handler. Solution: map signal 8 to SIGFPE, force a divide-by-zero via idiv, and reconstruct the final flag from the handler's patched stack string.

Signalization Eight — ctfsbp

Description

This program divides two numbers. Figure out how to make it print the flag in Linux

We are given a 64-bit ELF binary and told that the goal is not normal arithmetic output, but making it print the flag on Linux.

Summary

The binary registers a handler with signal(8, handler), reads two integers with scanf, and performs a signed division with idiv ecx. On Linux, signal 8 is SIGFPE, so setting the divisor to zero triggers the custom handler. Static analysis of that handler shows it starts from Flag{This Is Simple} and overwrites several bytes before calling puts(), producing REDACTED. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Analysis

Initial recon already gives useful hints:

  • the file is a 64-bit non-stripped ELF,
  • strings contain suspicious split fragments such as Flag{ThiH, s Is SimH, and ple},
  • the challenge text specifically asks how to make the program print the flag in Linux.

Decompiling main reveals the intended path:

  1. signal(8, handler) registers a custom signal handler.
  2. Two scanf calls read the operands.
  3. The code executes signed division via idiv ecx.

The important Linux detail is that signal number 8 is SIGFPE. Despite the name, this signal is commonly raised for arithmetic exceptions such as integer divide-by-zero. That means the intended trigger is to provide any numerator and 0 as the divisor. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Inside the handler, the program builds a stack string from the base text:

text
Flag{This Is Simple}

Before printing it with puts(), several bytes are changed:

  • index 4: { → 7
  • index 6: h → z
  • index 7: i → T
  • index 10: I → _
  • index 11: s → 4
  • index 12: → h

Applying those edits yields the final printed string:

text
REDACTED

Dynamic execution was not available in this environment because the binary failed with an exec format error, so the solve relied entirely on static analysis. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Solution

The shortest solution path is:

  1. Open the binary in a disassembler.
  2. Notice signal(8, handler) in main.
  3. Map Linux signal 8 to SIGFPE.
  4. Observe the idiv ecx after two integer inputs.
  5. Conclude that a zero divisor triggers the handler.
  6. Inspect the handler and reconstruct the modified stack string.

So on a compatible Linux system, the intended input would be any integer divided by zero, for example:

text
1
0

Minimal reconstruction script:

python
#!/usr/bin/env python3
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

flag = list("Flag{This Is Simple}")
flag[4] = '7'
flag[6] = 'z'
flag[7] = 'T'
flag[10] = '_'
flag[11] = '4'
flag[12] = 'h'

print(''.join(flag))

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