httpsec
httpsec
Platform: spbctf | Category: pwn | Type: Challenge | Difficulty: Medium | OS: NA | Author: XESXOR | Date: 2026-06-08 | Status: Solved Techniques: reverse_engineering, route_recovery, token_validation_reversal
Summary
Task: a network-exposed ELF implements a tiny custom HTTP server with a hidden protected route instead of an obvious crash bug. Solution: reverse the parser and auth logic, recover the required /secret/ path and valid 8-byte X-Auth token _kR8hVQS, then request the route to receive the flag.
httpsec — spbctf
Description
No organizer description was preserved in the task files.
The target service was http://109.233.56.90:11544/ and the provided binary was httpsec.elf. Initial probing showed GET / returning Welcome to our fast web-server, while unknown routes returned No such route.
Analysis
At first glance this looked like a small HTTP-facing pwn service: the ELF is amd64 PIE with NX enabled, no canary, and partial RELRO. That naturally suggests a parser bug, but reversing showed the intended solve was logic recovery rather than memory corruption.
The key functions were:
0x19f3— per-connection HTTP parser0x138d— main route and auth handler0x199e— header lookup helper0x1327— prefix-compare helper
The parser splits the request line with strtok() into global method, path, and version pointers. The path is truncated at ?, so query-string tricks do not change routing. Then up to 16 headers are parsed into a table of (name, value) pairs.
Route handling is simple:
- Exact
GET /returnsWelcome to our fast web-server. - Any path with prefix
/secret/and methodGETenters the secret handler. - Everything else returns
No such route.
The secret handler looks up the X-Auth header with the helper at 0x199e.
- Missing header ->
403 Forbidden/Missing auth token - Wrong length (
!= 8) ->403 Forbidden/Bad auth token - Correct length -> custom arithmetic/XOR validation
Reversing the checker showed that the token test is fully reversible. One valid token is:
text read-only • copy allowed_kR8hVQS
Sending GET /secret/ with X-Auth: _kR8hVQS returns:
text read-only • copy allowedFlag: spbctf{REDACTED}
So the important conclusion is that this was a hidden-route plus custom-auth reversing task packaged as a pwn service, not a memory-corruption exploit.
Brief dead ends worth noting:
- common route fuzzing found nothing beyond
/ Host-header and similar HTTP tricks did not affect routing- the initial memory-corruption hypothesis was killed by reversing the real control flow
Solution
- Probe the service and record the two visible behaviors:
/works and unknown paths returnNo such route. - Inspect
httpsec.elfwithchecksec; note the pwn-style mitigations but avoid assuming a bug exists. - Reverse the request parser at
0x19f3and the main handler at0x138d. - Recover the hidden route condition: method must be
GETand path must have prefix/secret/. - Reverse the secret handler and identify the required
X-Authheader. - Follow the 8-byte arithmetic/XOR checker and solve it, yielding
_kR8hVQS. - Send a valid request and read the flag from the response.
python read-only • copy allowed#!/usr/bin/env python3 import socket HOST = "109.233.56.90" PORT = 11544 TOKEN = "_kR8hVQS" request = ( "GET /secret/ HTTP/1.1\r\n" f"Host: {HOST}:{PORT}\r\n" f"X-Auth: {TOKEN}\r\n" "Connection: close\r\n" "\r\n" ) with socket.create_connection((HOST, PORT), timeout=5) as sock: sock.sendall(request.encode()) data = b"" while True: chunk = sock.recv(4096) if not chunk: break data += chunk print(data.decode(errors="replace"))
Expected response:
text read-only • copy allowedHTTP/1.1 200 OK Flag: spbctf{REDACTED}