s7.out
s7.out
Platform: CUSTOM | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: N/A | **Author: XESXOR Techniques: backward_solving, constraint_solving, decompilation, static_analysis
Summary
Walkthrough of the CUSTOM Reversing s7.out. Detailed walkthrough.
Description
Language: C. Download binary: s7.out (ELF 32-bit) or s7.exe (PE32). Flag is the correct serial number.
Classic keygen challenge: reverse engineer a serial validation function and find the correct input that passes all checks. The flag is the serial number itself (no wrapper).
Analysis
Binary Information
s7.out: ELF 32-bit LSB executable, Intel 80386, dynamically linked, not stripped (7444 bytes)s7.exe: PE32 executable (console) Intel 80386 (2560 bytes)- Not stripped — function names visible including
_Z5CheckPc(C++ mangled name forCheck(char*))
Check Function Logic
Decompilation of the Check function revealed three validation constraints:
c read-only • copy allowedvoid Check(char* input) { int len = strlen(input); // Constraint 1: length must be 6 if (len != 6) { fail; } // Constraint 2: last char must be 'x' (0x78) if (input[5] != 'x') { fail; } // Constraint 3: each char = previous char + index bool ok = true; for (int i = 1; i < len; i++) { if (input[i] != input[i-1] + i) { ok = false; break; } } PrintOK(ok); PrintError(!ok); }
Constraints Summary
- Length check:
strlen(input) == 6— serial must be exactly 6 characters - Last character check:
input[5] == 0x78— last character must be'x'(ASCII 120) - Recurrence relation: For i from 1 to 5:
input[i] == input[i-1] + i— each character equals the previous one plus its index
Solution
The recurrence relation input[i] = input[i-1] + i combined with the known last character allows us to work backwards:
python read-only • copy allowed#!/usr/bin/env python3 # Solve s7.out serial validation # Known: input[5] = 'x' (ASCII 120) # Relation: input[i] = input[i-1] + i # Therefore: input[i-1] = input[i] - i serial = [0] * 6 serial[5] = ord('x') # 120 # Work backwards for i in range(5, 0, -1): serial[i-1] = serial[i] - i # Convert to string result = ''.join(chr(c) for c in serial) print(f"Serial: {result}") # Verify print("\nVerification:") print(f"Length = {len(result)} (expected 6)") print(f"Last char = '{result[5]}' (expected 'x')") for i in range(1, 6): diff = ord(result[i]) - ord(result[i-1]) print(f"serial[{i}] - serial[{i-1}] = {ord(result[i])} - {ord(result[i-1])} = {diff} (expected {i})")
Manual Calculation
Working backwards from input[5] = 'x' (ASCII 120):
| Index | Calculation | ASCII | Character |
|---|---|---|---|
| 5 | given | 120 | 'x' |
| 4 | 120 - 5 | 115 | 's' |
| 3 | 115 - 4 | 111 | 'o' |
| 2 | 111 - 3 | 108 | 'l' |
| 1 | 108 - 2 | 106 | 'j' |
| 0 | 106 - 1 | 105 | 'i' |
Verification
All checks pass:
- Length = 6 ✓
- Last char = 'x' ✓
- serial[1] - serial[0] = 106 - 105 = 1 ✓
- serial[2] - serial[1] = 108 - 106 = 2 ✓
- serial[3] - serial[2] = 111 - 108 = 3 ✓
- serial[4] - serial[3] = 115 - 111 = 4 ✓
- serial[5] - serial[4] = 120 - 115 = 5 ✓
Key Takeaways / Lessons
- Mastering backward_solving, constraint_solving, decompilation, static_analysis was key to this challenge.
- Always check for common misconfigurations and verify assumptions.
Crafted by XESXOR Research • 2020-01-01 • CUSTOM • s7.out • Difficulty: Easy