Портовая куртизанка (Port Courtesan)
Портовая куртизанка (Port Courtesan)
Platform: bug-makers | Category: Network | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2026-05-27 | Status: Solved Techniques: decoy_page_identification, full_port_scan, parallel_http_probing, tcpwrapped_filtering
Summary
Task: server with all 65535 TCP ports open (tcpwrapped via iptables), one port hides an HTTP service with the flag. Solution: parallel curl scan across all ports to find the single port (7281) serving different HTTP content.
Портовая куртизанка (Port Courtesan) — Bug Makers CTF
Description
Жемчужину скрывает только одна ракушка из десятков тысяч. Адрес: http://155.212.186.222
English summary: A server at 155.212.186.222 hides a flag ("pearl") on exactly one port ("shell") among tens of thousands. The goal is to find which port serves the flag.
Analysis
Initial reconnaissance
Visiting http://155.212.186.222 (port 80) returns a decoy nginx page:
html read-only • copy allowed<title>Welcome</title> <h1>Флага тут нет!</h1> <!-- No flag here! --> <p>Ты точно везде посмотрел?</p> <!-- Did you really look everywhere? -->
Port scan reveals the trick
Running nmap -p- shows all 65,535 TCP ports as open. The server uses iptables to ACCEPT all incoming TCP connections. Every port completes the TCP three-way handshake but most send no data — they are "tcpwrapped."
This is the core challenge: among 65,535 open ports, exactly ONE has a real HTTP service. The rest are decoys that accept connections but serve nothing.
Why nmap fails
nmap -sV(version detection) sends probes and waits for responses. With 65,535 tcpwrapped ports, each probe times out after several seconds. Scanning the full range would take hours.- The flag itself —
BugCTF{REDACTED}— confirms this was intentional.
Semantic clues
- "Портовая куртизанка" (Port Courtesan) → wordplay on "port" (network port)
- "Жемчужину скрывает только одна ракушка из десятков тысяч" (Only one shell among tens of thousands hides the pearl) → one port among 65,535 has the flag
- "ракушка" (shell) → also means a network service/shell on a port
Solution
Step 1: Confirm the decoy page
bash read-only • copy allowedcurl http://155.212.186.222 # Returns HTML: "Флага тут нет!" (No flag here!)
Step 2: Discover all ports are open
bash read-only • copy allowednmap -p- 155.212.186.222 # All 65535 ports show as open/tcpwrapped
Step 3: Failed approaches
nmap version detection — too slow for 65,535 tcpwrapped ports:
bash read-only • copy allowednmap -sV -p1-4000 155.212.186.222 # Takes 60+ seconds for just 4000 ports, never completes full range
Python socket scanner with banner detection — the hidden service doesn't send banners unprompted, so a passive recv() approach finds nothing.
Python HTTP scanner — works in theory but socket-level HTTP probing had timing/buffering issues at scale.
Step 4: Parallel curl scan (winning approach)
The key insight: curl handles HTTP properly (sends request, reads response, handles timeouts). Running it in parallel with xargs covers all 65,535 ports in minutes:
bash read-only • copy allowed#!/bin/bash # curl_scan.sh — Parallel curl scan for hidden HTTP service TARGET="155.212.186.222" START=${1:-1} END=${2:-65535} PARALLEL=100 scan_port() { local port=$1 if [ "$port" -eq 80 ] || [ "$port" -eq 22 ]; then return fi result=$(curl -s --connect-timeout 1 --max-time 2 \ "http://${TARGET}:${port}/" 2>/dev/null) if [ -n "$result" ] && [ ${#result} -gt 10 ]; then echo "[+] Port $port: ${result:0:100}" fi } export -f scan_port export TARGET echo "Curl scanning $TARGET ports $START-$END..." seq $START $END | xargs -P $PARALLEL -I {} bash -c 'scan_port {}' echo "Done."
This found port 7281 returning different HTML content.
Step 5: Retrieve the flag
bash read-only • copy allowedcurl http://155.212.186.222:7281/ # Returns HTML page with title "Secret" containing the flag
The page at port 7281 contains: BugCTF{REDACTED}