Page cover

Drive

Hack the Box machine writeup

Now that is cloud storage

Summary

Drive was a box on the easier side of the hard difficulty. It involves some pretty straightforward steps and a little bit of reversing. Many of the steps center around finding plain text creds and none of it is overly technical until Root. To obtain user.txt first the attacker will enumerate an IDOR vulnerability that will let them read other users' files on the web application. One of these files contains creds that can be used to login with SSH and obtain a foothold shell as Martin. Next a tunnel to port 3000 must be established to bypass port filtering and access a Gitea instance. The attacker can reuse Martins creds here to discover a repository that contains a backup.sh script and a hardcoded password. Going back to the drive.htb server the attacker can find a bunch of backup 7z archives that can be unzipped with the discovered password. These archives contain password hashes that can be cracked to obtain a shell with the Tom user over SSH.

The root step mainly involved the reversing of an ELF executable. In doing so an SQL injection is discovered that when combined with the run-time loadable extensions function of sqlite allows for arbitrary C code to be run. Abusing this then allows for escalation to root as the ELF executable is run with suid permissions.

The cloud man. Its always the cloud.

User

Recon

Nmap scan

Starting off with an nmap scan reveals SSH open on port 22, an nginx web server redirecting to http://drive.htb on 80 and a filtered port 3000.

I will then add drive.htb to my /etc/hosts file for DNS resolution.

Fuzz for subdomains

Whenever I discover a domain I like to fuzz for other subdomains or virtual hosts that might exist. In this case there was nothing to be discovered

Enumerate Webserver

Navigating to drive.htb displays a generic company page for a web application called Doodle Grive. There are tabs for Home, About, Services, Team, and Contact Us. About, services and team are all simply anchored to points on the main page.

I wonder what the name could be referencing?

Contact us is a generic contact form.

Contact forms are often a good place to check for XSS

Sending this through burp and looking at the server response headers does not reveal anything of value like a framework. It will also print a message about contacting us soon.

Always good to check out headers
I don't think they actually will :(

Home links to /home/ which appears to be the doodle gdrive web application. At this directory there is a file called Welcome_to_Doodle_Gdrive that links to a login form, /login. This form can also be reached by the login button found in the top right.

Its a pretty snazzy web application IMO.

Guessing some basic stuff like admin:admin doesn't get anywhere and it does not appear like the error message will allow us to enumerate usernames. There is a register link at the bottom however and using this to register a new account we can then login.

Always good to also check custom login forms for SQLI
It's good to always use the victim domain when creating an account

Upon logging in we are redirected back to the home page. Clicking dashboard will bring us back to /home/ and we are now able to view the message in the Welcome file.

Another reference to some kind of bot interacting with the contact-us page?

Going back and clicking upload we are directed to /upload. Here we can upload a file to the service that is the ASCII text mime type.

MIME checking involves looking at the first couple bytes of the file

Uploading the file we are redirected to /home/ and can see the new file. Clicking on it we are given the new options of change properties, delete and edit content. delete and edit content do what you would think.

Always good to enumerate functionality as much as possible

Change properties redirects to /112/update where the name of the file can be changed.

Maybe the file name is vulnerable to XSS if it is echoed to html somewhere?

Reports generate a log of activity on the service.

We can control the user field. This could also be a possible XSS vector

Lastly there is groups that will allow the user to create groups and upload files to the group.

It do be like that

Fuzzing for IDOR

At this point it becomes clear that there is some kind of object referencing going on in the urls. For example we have: /112/update, /112/getFileDetail/ and /112/editContent. It is possible that we can change the 112 to reference another file and exploit an Indirect Object Reference through the URL. To test this we can use /getFileDetail as it will likely allow us to read other files. Testing with /0/getfiledetails simply returns a json internal server error that states no file matches the given query. At this point it is a good idea to attempt to fuzz the value. For this we will use Wfuzz and pass it the csrf token and session id cookies from an intercepted burp request in order to authenticate the Wfuzz requests.

Grabbing the csrf token and the sessionid

I will also use the --hh 82 flag to filter out the default responses with chars length 82 like we did when fuzzing for subdomains.

This returns our known 112 test file but also 100 which is the Welcome_to_Doodle_Grive! file. The other values return a 401 unauthorized response, likely because these are owned by other users. Thinking that perhaps one of the functions that references the files: /block, /update or /edit Content might not correctly apply the authorization filtering I fuzzed those with the value 079 from the unauthorized above. /079/block/ returns a file titled announce_to_the_software_Enginner and with it we have found and confirmed an IDOR vulnerability that allows us to look at other peoples files we should not have access to.

All your files are belong to us

Viewing this file, announce_to_the_software_Engineering_team, we can find credentials for a user martin with the password Xk4@KjyrYv8t194L!.

storing passwords in plaintext is never a good idea
Just dont do it!

Using the same IDOR to view the other files 101 reveals a message about a scheduled database backup plan. it also gives us a couple more users of jamesMason and Cris.

Usernames everywhere!

098 just gives us a generic message and another user of crisDiesl. 99 just reveals a message about there being security issues in the middleware.

Shell as Martin

Using the creds we found martin:Xk4@KjyrYv8t194L! we can SSH into the drive.htb host.

Qbert password strikes again!

As we do not yet have user.txt we can check the home directory and see that we likely will need to move laterally to the cris or tom users. We can also see a git user, signaling that the filtered port 3000 was likely a git hosting service.

Using netstat we can see the 3000 port listening on all addresses. we can also see there is a mysql server listening locally on port 3306 and likely port 33060.

Tunnel to access Gitea

Using curl to access the port 3000 server from the localhost we can see that the port filtering is bypassed and we are returned to the Gitea website. From here I used SSH to set up port forwarding for the 3000 port. In this way we can use the tunnel to access the website from our attacking hosts browser and bypass the filtering.

I could go for a cuppa

Because the frogs like tea, that's why!

Using explore we cannot find any repositories and we are only shown user accounts we already know. We can try logging in with martins creds. While this does not work with username martin, it does let us in with martin@drive.htb. We can now see the DoodleGrive repository in explore.

I love me some source code repositories

In this repository there is the db_backup.sh script that was mentioned in one of the files on the web application we discovered. This script file contains the hardcoded password H@ckThisP@ssW0rDIfY0uC@n:) which is used to create the backup zip files. If we find these backups we can likely use this password to decrypt them.

You didn't make it very hard by storing it in clear text!

Exploring backups

The note about the backup script also mentioned the /var/backups directory we can check it out. Here we can see a DoodleGdrive.zip folder owned by www-data that we cannot read, meaning we likely have to get a shell as www-data at some point.

Checking out /var/www there is a backups directory here as well. In /var/www/backups there are a bunch of .7z backups we can read this time as well as a db.sqlite3 file.

To quickly transfer all these back to my attacking machine I will abuse the python3 installed on drive.htb to create a simple http server on port 42069. I will then use wget with the recursive -r flag to pull all the files from the newly created web server directory.

I decided to check out the db.sqlite3 database first since it was unencrypted. Browsing this database it appears to be connected to the web application as we can find the files we had previously discovered in the myApp_file table.

In the accounts_customuser table we can find 5 password hashes for different user accounts. adding all these hashes to a file and using hashcat we can crack the password for the tomHands user to john316

Take after this man! use complex passwords

Sadly this password does not work for SSH or anything else. From here it was time to use the previously discovered password to decrypt and unzip all the backup .7z archives.

These databases are much like the previous one already went through. We will do the same process as before , copying all the hashes to a text file and running that through hashcat. The database for December contains a different hash type that will take forever to crack, as such I will not add these ones to the list. This will result in 2 more passwords for the tom user and the one we already discovered.

In this case it was a backup

Shell as Tom

Spraying these 2 new passwords against SSH we get in with johnmayer7. We can then grab user.txt and move on to exploiting root.

Who the heck is john Mayer?

Root

Enumeration

In tom's home directory we can find a suid binary called doodleGrive-cli. we can see that the file is an ELF binary. Running it we are asked for a username and a password.

Finding password for binary

Finding the password and username for the binary was as easy as running as strings command, which will print out all the ascii strings, and then grepping for the password. Assuming the check is either right before or after the password prompt we can add the --before 5 and --after flag to print 5 line before and after the match.

We can see from this command that the user name is Moriarty and the password is findMeIfY0uC@nMr.Holmz!. Running the binary with these credentials results in an interactive application with a menu of 6 options. I played around with this a bit but without reversing the application it is hard to know what exactly is going on.

Gronk memes are top tier

Reversing doodleGrive-cli

The first thing to do was to transfer the application back to my host machine. I will do this the same way as before using a python simple http server.

Next I opened the executable in Ghidra, disassembled and analyzed the file. Doing so we can see the main_menu function. This contains the 5 choices we saw before as a switch statement which each calls a separate function.

Looking at these functions we can see that they are all making SQL queries with sqlite3 and returning the data. In case 5 calling the activate_user_acount function we appear to have the first case of interactivity with the SQL and an apparent SQL injection as we are able to control input into the query. There is a santize_string that attempts to prevent us from doing this however which we can see directly before the SQL query.

Looking at the santize_string function we can see that it is doing some checks on the passed value.

Decoding the hex we can see that local_29 is a set of bad chars {/| '. we can also see that local_21 is a ;. We can assume that these are bad chars we will need to avoid while creating the SQL injection.

Your filtering is no match for our l337 hax0r skillz

Creating SQLITE injection

Looking back at the SQL query we can see that sqlite3 is being used. This is good because it allows us to execute arbitrary code through a function called run-time loadable extensions. This effectively allows us to execute external .so scripts with the load_extension commandarrow-up-right. arrow-up-rightThe ability to run code in this way though external scripts is not unique to sqlite3 and is also present in things such as Microsoft SQL server as an important note.

Therefore we can use an input such as "+load_extension(script to run)--" to inject arbitrary code into the SQL statement to be executed. In order to do this we will need a .so file however. We can create one now and upload it to the same directory as the doodleGrive-cli binary. By keeping it in the same directory location we can reference it simply as ./nameoffile.

This code will attach suid permissions to the /bin/bash binary, allowing anyone to run it with the -p flag to obtain root permissions. Next we need to compile it with GCC.

This will make our SQL injection look as follows, using + to avoid spaces as SQLite treats + as whitespace.

There is a problem though as the / character won't get past the sanitation. To get around this we can use the char sqlite3 function to pass in a series of char ascii digits instead. To make this even easier on ourselves we will rename hack.so to a.so so we require less chars. One final thing that helps us out is that when sqlite uses the load_exension function it automatically applies the .so at the end. Due to this we only need the char values of . / and a. We can use an online chartarrow-up-right for this. arrow-up-rightPutting this all together you can see the final version of the injection string below with 46 being . 47 being / and 97 being a.

This is why I have trouble with ASCII encoding

Use run-time loadable extensions

We now have everything setup and configured as needed to execute the SQL injection and abuse run-time loadable extensions to execute our a.so code and achieve root.

We can now check that the /bin/bash binary was given suid privileges and run it with the -p flag to read root.txt and complete the box.

Nice going on completing another hard machine!

Additional Resources

Ippsec video walkthrough

Last updated