s5.out
s5.out
Platform: spbctf | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: NA | Author: XESXOR | Date: 2026-03-25 | Status: Solved Techniques: disassembly, forward_solving, recurrence_relation, static_analysis
Summary
Task: 32-bit ELF serial validation crackme with recurrence relation. Solution: forward solve from known first character 'a' using input[i] = input[i-1] + i.
s5.out — SPbCTF Reverse Kids 2.0
Description
Language: C. Download binary: s5.out (ELF 32-bit) or s5.exe (PE32). Flag is the correct serial number.
A 32-bit ELF executable compiled from C++. Serial number validation crackme where the Check function uses a recurrence relation to validate characters.
Analysis
-
File reconnaissance:
file s5.outshows: ELF 32-bit LSB executable, Intel 80386, dynamically linked, not stripped (7492 bytes)s5.exe: PE32 executable (console) Intel 80386 (2048 bytes)- Key symbols from
nm:main,_Z5Checkv(Check()),_Z7PrintOKv,_Z10PrintErrorv - Source file: s5.cpp
-
main() function analysis:
- Prints "Enter serial number: "
- Reads input via
scanf("%s")into global buffer at 0x804a02c - Calls
Check()function - If Check() returns true → calls PrintOK() which prints "Serial number is correct!"
- If Check() returns false → calls PrintError() which prints "Error! Serial number is wrong!"
-
Check() function disassembly (at 0x8048523):
c read-only • copy allowedbool Check() { int len = strlen(input) - 1; if (len != 6) return false; // strlen must be 7 if (input[0] != 0x61) return false; // input[0] must be 'a' for (int i = 1; i < len; i++) { // i = 1, 2, 3, 4, 5 if (input[i] != input[i-1] + i) return false; } return true; }
- Validation logic:
- Length check:
strlen(input) - 1 == 6, so string must be 7 characters - First character must be 'a' (ASCII 0x61 = 97)
- Recurrence relation: each character equals previous character plus current index
- Loop runs for i = 1 to 5 (position 6 is unchecked)
- Length check:
Solution
Forward solve from the known first character using the recurrence relation:
python read-only • copy allowed#!/usr/bin/env python3 """ s5.out Check function: len = strlen(input) - 1 if len != 6: fail (so strlen == 7, string is 7 chars) if input[0] != 'a': fail for i in range(1, len): # i = 1..5 if input[i] != input[i-1] + i: fail return true Position 6 is unchecked by the loop. """ serial = [0] * 7 serial[0] = ord('a') # 97 for i in range(1, 6): serial[i] = serial[i-1] + i # Position 6 - not checked, but continuing the pattern serial[6] = serial[5] + 6 result = ''.join(chr(c) for c in serial) print(f"Serial: {result}") # Verification print(f"\nVerification:") for i in range(1, 7): print(f" serial[{i}]({serial[i]}='{chr(serial[i])}') == serial[{i-1}]({serial[i-1]}='{chr(serial[i-1])}') + {i} = {serial[i-1]+i}")
Computation table:
| Index | Calculation | ASCII | Character |
|---|---|---|---|
| 0 | given | 97 | 'a' |
| 1 | 97 + 1 | 98 | 'b' |
| 2 | 98 + 2 | 100 | 'd' |
| 3 | 100 + 3 | 103 | 'g' |
| 4 | 103 + 4 | 107 | 'k' |
| 5 | 107 + 5 | 112 | 'p' |
| 6 | 112 + 6 | 118 | 'v' |
Position 6 is unchecked by the loop (loop condition is i < 6), but continuing the arithmetic pattern gives 'v'.
Verification:
$ echo "REDACTED" | ./s5.out
Enter serial number: Serial number is correct!