GrossmanOri/vulnerable-http-server
GitHub: GrossmanOri/vulnerable-http-server
Stars: 0 | Forks: 0
# Vulnerable HTTP Server — Security Exploitation Demo
A deliberately vulnerable HTTP server written in C, built to demonstrate four classic vulnerability classes against a real running process on Apple Silicon (ARM64).
This project was built as part of a security engineering course at Shenkar College. Every exploit targets a genuine binary — no CTF scaffolding, no synthetic wrappers.
## Vulnerabilities Demonstrated
### 1. Variable Overflow — `check_auth`
A struct lays `char password_buffer[16]` immediately before `volatile int is_authenticated` in memory. The copy loop is bounded by `sizeof(struct)` (20) rather than the buffer size (16), so writing 17 bytes overwrites the authentication flag without ever knowing the password.
### 2. Stack Buffer Overflow — `do_login` / `write_creds`
`write_creds` performs an unbounded copy into a 16-byte stack buffer. Sending 48 bytes past the dummy strip overwrites the saved return address (`x30` on ARM64) on the stack.
### 3. Return Address Hijack → Backdoor Database Dump
### 4. Timing Side-Channel — `slow_strcmp`
The password comparison calls `usleep(2000)` for every matching character before continuing. This creates a ~2ms measurable RTT increase per correct character. The attack recovers the password one character at a time by measuring median response latency over 30 samples per candidate.
## Technical Details
**Target:** ARM64 Apple Silicon (macOS), compiled with Clang
**Stack frame verified by:** `otool -tV` disassembly + LLDB `disassemble --name do_login`
### `do_login` frame layout (confirmed by disassembly)
sub sp, sp, #0x40 ; 64-byte frame
stp x29, x30, [sp, #0x30] ; saved x29 at sp+48, x30 at sp+56
add x0, sp, #0x10 ; password_buf at sp+16
sp+16 .. sp+31 password_buf[16] ← overflow starts here
sp+32 .. sp+55 padding, stored args, x29
sp+56 .. sp+63 saved x30 (return addr) ← hijack target
Distance from `password_buf` → saved `x30`: **40 bytes**
Payload: `fill(16) + bridge(24) + addr(8)` = 48 bytes after dummy strip
### Why the protections are disabled
| Flag | Protection removed | Effect |
|---|---|---|
| `-fno-stack-protector` | Stack canary | Canary would catch the overflow before `ret` |
| `-mbranch-protection=none` | ARM64 PAC | PAC validates `x30` before `ret`; hijacked address would trap |
| `-O0` | Compiler optimization | Keeps stack layout deterministic |
## Build
make clean && make
Requires: `gcc`, `make`, macOS with Xcode Command Line Tools.
## Running the Attacks
### Attack 1 — Variable Overflow (auth bypass)
./server &
python3 attack1.py
# Expected: [+] ACCESS GRANTED
### Attack 2+3 — Return Address Hijack + Database Dump
# Terminal 1
lldb ./server
(lldb) settings set target.disable-aslr true
(lldb) run
(lldb) image lookup -n dump_user_database # note the address
(lldb) continue
# Terminal 2
python3 attack2.py
# Expected: [+] ACCESS GRANTED then === BACKDOOR: PASSWORD DATABASE DUMP ===
### Attack 4 — Timing Side-Channel
./server &
python3 timing_attack.py
# Recovers 'secret123' character by character (~5 minutes)
## How the Timing Attack Works
`slow_strcmp` sleeps 2ms per matching character. Measuring median RTT over 30 samples per candidate produces a consistent ~2ms gap for the correct character at each position:
Position 0: 's' 2.95 ms gap: +1.96 ms
Position 1: 'e' 5.47 ms gap: +2.11 ms
Position 2: 'c' 7.79 ms gap: +1.90 ms
Position 3: 'r' 10.11 ms gap: +2.22 ms
Position 4: 'e' 13.31 ms gap: +2.41 ms
Position 5: 't' 14.74 ms gap: +2.15 ms
Position 6: '1' 16.97 ms gap: +2.08 ms
Position 7: '2' 19.96 ms gap: +2.11 ms
→ [+] PASSWORD FOUND: 'secret123'
The script uses `statistics.median()` over 30 samples and a 1.2ms minimum gap threshold to reject OS jitter and prevent cascade failures from a single wrong character.
## Mitigations (what stops these in production)
| Attack | Mitigation |
|---|---|
| Variable overflow | Bound the copy loop to the buffer size, not `sizeof(struct)` |
| Stack buffer overflow | Use bounded copy functions (`strncpy`, `memcpy` with size check) |
| Return address hijack | Stack canary (`-fstack-protector`) + ARM64 PAC (`-mbranch-protection=standard`) |
| Timing side-channel | Constant-time comparison (`memcmp` on fixed-length buffers, or `CRYPTO_memcmp`) |
## Project Structure
├── main.c entry point
├── httpd.c fork-based server loop, HTTP dispatch
├── http_protocol.c HTTP parser
├── router.c route handlers + all four vulnerabilities
├── httpd.h shared types and macros
├── Makefile
├── passwords.txt sample credential store
├── attack1.py Attack 1 — variable overflow
├── attack2.py Attack 2+3 — return address hijack
└── timing_attack.py Attack 4 — timing side-channel
标签:客户端加密