Крестики (Krestiki)
Крестики (Krestiki)
Platform: hackerlab | Category: Reversing | Type: Challenge | Difficulty: Medium | OS: Windows | Author: XESXOR | Date: 2025-12-27 | Status: Solved Techniques: mathematical_equation_reversal, pe64_static_analysis, utf16_string_extraction, xor_add_sub_chain_solving
Summary
Task: Windows Forms crackme with mathematical validation. Solution: Reverse XOR/ADD/SUB equation chains to find 4 numbers for the flag format CODEBY{NNNN-NNNN-NNNN-NNNN}.
Крестики (Krestiki) — HackerLab
Description
"Сможешь решить классический крякми на крестиках и формочках? :)"
Classic C++ crackme with Windows Forms. The name "krestiki i formochki" (crosses and forms) is a hint at C++ (crosses/plus signs) and Windows Forms.
Analysis
File Identification
bash read-only • copy allowedfile krestiki.exe # PE32+ executable (GUI) x86-64, for MS Windows
64-bit Windows GUI application — typical crackme.
String Extraction
UTF-16 strings found in .rdata section:
bash read-only • copy allowedstrings -el krestiki.exe | head -20
Key findings:
Крестики— window titleИмя:— name fieldФлаг:— flag fieldПроверить— check buttonCODEBY{— flag prefixMASTER_OF_CODEBY— expected username- Success/failure messages in Russian
Validation Logic
From disassembly (0x1400013a0):
- Flag length check: exactly 27 characters (0x1b)
- Format check:
- Starts with
CODEBY{ - Ends with
} - Contains 4 groups of 4 digits, separated by
- - Format:
CODEBY{NNNN-NNNN-NNNN-NNNN}
- Starts with
- Name check: must be
MASTER_OF_CODEBY
Mathematical Checks
At address 0x1400015a1, found 4 equations for each number:
Number 1 (esi): (n1 ^ 0xdfaf7 + 0x151336e) ^ 0x23b97b == 0x17cab7e
Number 2 (ebx): ((n2 ^ 0x378) + 0x551) ^ 0xb84c == 0x9e14
Number 3 (ebp): (n3 - 0x2443) ^ 0xa808 == 0xffff4681
Number 4 (edx): ((n4 ^ 0xfd836) - 0x3338) ^ 0xbc3f == 0xf1584
Solution
Reverse Solving the Equations
For each number, perform operations in reverse order:
python read-only • copy allowed#!/usr/bin/env python3 """ Крестики (Krestiki) - HackerLab Reverse Engineering Challenge Reverse XOR/ADD/SUB equations to find the 4 numbers in the flag. Format: CODEBY{NNNN-NNNN-NNNN-NNNN} """ # Number 1: (n1 ^ 0xdfaf7 + 0x151336e) ^ 0x23b97b == 0x17cab7e # Reverse: n1 = ((0x17cab7e ^ 0x23b97b) - 0x151336e) ^ 0xdfaf7 result1 = 0x17cab7e ^ 0x23b97b # Undo final XOR result1 -= 0x151336e # Undo ADD result1 ^= 0xdfaf7 # Undo first XOR n1 = result1 print(f"Number 1: {n1}") # 9312 # Number 2: ((n2 ^ 0x378) + 0x551) ^ 0xb84c == 0x9e14 # Reverse: n2 = ((0x9e14 ^ 0xb84c) - 0x551) ^ 0x378 result2 = 0x9e14 ^ 0xb84c # Undo final XOR result2 -= 0x551 # Undo ADD result2 ^= 0x378 # Undo first XOR n2 = result2 print(f"Number 2: {n2}") # 8831 # Number 3: (n3 - 0x2443) ^ 0xa808 == 0xffff4681 # Reverse: n3 = (0xffff4681 ^ 0xa808) + 0x2443 # Note: 0xffff4681 is a 32-bit signed negative representation result3 = 0xffff4681 ^ 0xa808 # Undo XOR result3 = (result3 & 0xffffffff) # Keep 32-bit result3 += 0x2443 # Undo SUB n3 = result3 & 0xffff # Take lower 16 bits print(f"Number 3: {n3}") # 4812 # Number 4: ((n4 ^ 0xfd836) - 0x3338) ^ 0xbc3f == 0xf1584 # Reverse: n4 = ((0xf1584 ^ 0xbc3f) + 0x3338) ^ 0xfd836 result4 = 0xf1584 ^ 0xbc3f # Undo final XOR result4 += 0x3338 # Undo SUB result4 ^= 0xfd836 # Undo first XOR n4 = result4 print(f"Number 4: {n4}") # 1221 # Construct the flag flag = f"CODEBY{{{n1}-{n2}-{n3}-{n4}}}" print(f"\nFlag: {flag}")
Result
Number 1: 9312
Number 2: 8831
Number 3: 4812
Number 4: 1221
Flag: CODEBY{REDACTED}
Verification
To verify, substitute the numbers back into the equations:
python read-only • copy allowed# Verification def verify(n1, n2, n3, n4): check1 = ((n1 ^ 0xdfaf7) + 0x151336e) ^ 0x23b97b check2 = ((n2 ^ 0x378) + 0x551) ^ 0xb84c check3 = (n3 - 0x2443) ^ 0xa808 check4 = ((n4 ^ 0xfd836) - 0x3338) ^ 0xbc3f print(f"Check 1: {hex(check1)} == 0x17cab7e: {check1 == 0x17cab7e}") print(f"Check 2: {hex(check2)} == 0x9e14: {check2 == 0x9e14}") print(f"Check 3: {hex(check3 & 0xffffffff)} == 0xffff4681: {(check3 & 0xffffffff) == 0xffff4681}") print(f"Check 4: {hex(check4)} == 0xf1584: {check4 == 0xf1584}") verify(9312, 8831, 4812, 1221)
Notes
- Task name: "Крестики и формочки" (crosses and forms) — wordplay: "кресты" (crosses) = C++, "формочки" (forms) = Windows Forms
- MASTER_OF_CODEBY: Username that must be entered to pass validation
- Signed vs Unsigned: Number 3 uses 32-bit signed representation (0xffff4681), requiring careful handling
- Reverse Engineering Flow: XOR → ADD/SUB → XOR — typical obfuscation chain, solved in reverse order
- Static Analysis: Task is solved entirely statically, without running the binary