← Back to Writeups
CUSTOMEasyReversing

s3.out

XESXOR9/10/20263 min read
#reversing#custom#easy#brute_force#disassembly#modular_arithmetic_solving#static_analysis#windows

s3.out

Platform: rev-kids20.forkbomb.ru | Category: Reversing | Type: Challenge | Difficulty: Easy | OS: Windows | Author: XESXOR | Date: 2026-03-25 | Status: Solved Techniques: brute_force, disassembly, modular_arithmetic_solving, static_analysis

Summary

A 32-bit ELF binary (also provided as PE32 for Windows). Password checker that uses modular arithmetic to validate input. Unlike simple byte-by-byte comparisons, this challenge requires understanding the mathematical constraint.

s3.out — Reverse Kids 2.0

Description

Download binary: s3.out / s3.exe. Flag is the correct password that satisfies the formula. There are many valid flags.

A 32-bit ELF binary (also provided as PE32 for Windows). Password checker that uses modular arithmetic to validate input. Unlike simple byte-by-byte comparisons, this challenge requires understanding the mathematical constraint.

Analysis

  1. File reconnaissance:

    • file s3.out shows it's a 32-bit ELF, not stripped
    • Compiled from s3.cpp (C++ source)
    • strings reveals standard password prompt messages ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍
  2. Disassembly of main(): The password validation algorithm:

    c
    acc = 0x75;  // 117
    for (i = 0; i < strlen(password); i++) {
        acc = (acc * (password[i] + 1)) % 256;
    }
    if (acc == 0x76) {  // 118
        puts("You are welcome! Now you can use this app.");
    } else {
        puts("Go out of here!");
    }
  3. Mathematical constraint:

    • Initial value: acc = 117
    • Target value: acc = 118
    • Formula: 117 × ∏(c_i + 1) ≡ 118 (mod 256)
  4. Key insight: The modulo 256 operation creates many valid solutions. Any password where the product of (char + 1) values, multiplied by 117, equals 118 mod 256 is valid. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Solution

python
#!/usr/bin/env python3
"""
s3.out password solver
Constraint: 117 * product((c+1) for c in password) ≡ 118 (mod 256)
"""

def check_password(password):
    """Verify if password satisfies the constraint"""
    acc = 117
    for c in password:
        acc = (acc * (ord(c) + 1)) % 256
    return acc == 118

def find_2char_passwords():
    """Find all 2-character printable passwords"""
    solutions = []
    for c1 in range(32, 127):  # printable ASCII
        for c2 in range(32, 127):
            acc = 117
            acc = (acc * (c1 + 1)) % 256
            acc = (acc * (c2 + 1)) % 256
            if acc == 118:
                solutions.append(chr(c1) + chr(c2))
    return solutions
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

# Find solutions
passwords = find_2char_passwords()
print(f"Found {len(passwords)} 2-character solutions:")
print(passwords[:10])  # First 10

# Verify one solution
password = "REDACTED"
print(f"\nVerification for '{password}':")
print(f"  '!' (ASCII 33): 117 * 34 mod 256 = {(117 * 34) % 256}")
print(f"  '~' (ASCII 126): 138 * 127 mod 256 = {(138 * 127) % 256}")
print(f"  Valid: {check_password(password)}")

Output:

Found 34 2-character solutions:
['REDACTED', '%4', ')r', '-h', '0=', '1F', '4%', '5<', '9z', '<5']
‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Verification for 'REDACTED':
  '!' (ASCII 33): 117 * 34 mod 256 = 138
  '~' (ASCII 126): 138 * 127 mod 256 = 118
  Valid: True

Manual verification for REDACTED:

  • Initial acc = 117
  • char '!' (ASCII 33): acc = 117 × 34 mod 256 = 3978 mod 256 = 138
  • char '~' (ASCII 126): acc = 138 × 127 mod 256 = 17526 mod 256 = 118
  • Final acc = 118 = target ✓ ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍