← Back to Writeups
CUSTOMEasyNetwork

Портовая куртизанка (Port Courtesan)

XESXOR9/2/20263 min read
#network#custom#easy#decoy_page_identification#full_port_scan#parallel_http_probing#tcpwrapped_filtering#linux

Портовая куртизанка (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
<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
curl http://155.212.186.222
# Returns HTML: "Флага тут нет!" (No flag here!)

Step 2: Discover all ports are open

‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

bash
nmap -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
nmap -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
#!/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
curl http://155.212.186.222:7281/
# Returns HTML page with title "Secret" containing the flag

The page at port 7281 contains: BugCTF{REDACTED} ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍