Nineveh Walkthrough: Steganalysis, LFI to RCE, and Port Knocking

Max Register
15 min readNov 8, 2020

This machine was fun to work through as it had some ‘Capture the Flag’ Esq attributes. Steganalysis is something that I have always wanted to play around with, and this box was the perfect excuse to dedicate some time to explore this interesting technique. Without further ado, let’s get into this walkthrough:

Initial Enumeration

Starting off with the regular Nmap scan yields the following:

kali@kali:~/Documents/htb/nineveh$ nmap -sC -sV 10.10.10.43
Starting Nmap 7.80 ( https://nmap.org ) at 2020-11-07 12:15 EST
Nmap scan report for nineveh.htb (10.10.10.43)
Host is up (0.051s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
443/tcp open ssl/http Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: Site doesn't have a title (text/html).
| ssl-cert: Subject: commonName=nineveh.htb/organizationName=HackTheBox Ltd/stateOrProvinceName=Athens/countryName=GR
| Not valid before: 2017-07-01T15:03:30
|_Not valid after: 2018-07-01T15:03:30
|_ssl-date: TLS randomness does not represent time
| tls-alpn:
|_ http/1.1
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 22.28 seconds

Looks like there is an Apache server running on port 80 and 443, and we get the common name nineveh.htb as well.

Firstly, let’s add this common name to our /etc/hosts file so we can use that in the browser and further scanning. We do this by using any text editor such as vi or nano and opening the file with root privileges. You must use sudo or else you won’t write privileges in this file.

Add the IP and the common name as shown above. Save this file using :wq and we can pull up the servers in the browser.

Web Server Enumeration

In the browser pull up both http://nineveh.htb and https://nineveh.htb as shown:

Nothing too interesting on either site, let’s keep digging. We can enumerate directories of the server running on port 80 with a tool called gobuster using the following command:

kali@kali:~/$gobuster dir -u http://nineveh.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt

For the server running on port 443, we will need to add the flag -k to ignore TLS checks since this site has self-signed certificates. This command is as follows:

kali@kali:~$ gobuster dir -u https://nineveh.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k

After some time, we get the following results from the scans of nineveh.htb and https://nineveh.htb respectfully:

http://nineveh.htb

kali@kali:~$ gobuster dir -u nineveh.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: http://nineveh.htb
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/10/31 18:32:23 Starting gobuster
===============================================================
/department (Status: 301)
/server-status (Status: 403)
===============================================================
2020/10/31 18:54:41 Finished
===============================================================
kali@kali:~$

https://nineveh.htb

kali@kali:~/Documents/htb/nineveh$ gobuster dir -u https://nineveh.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url: https://nineveh.htb
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes: 200,204,301,302,307,401,403
[+] User Agent: gobuster/3.0.1
[+] Timeout: 10s
===============================================================
2020/10/31 18:30:51 Starting gobuster
===============================================================
/db (Status: 301)
/server-status (Status: 403)
/secure_notes (Status: 301)
===============================================================
2020/10/31 18:53:32 Finished
===============================================================
kali@kali:~/Documents/htb/nineveh$

We found a few directories that seem to be interesting. We should investigate these by browsing them.

nineveh.htb/department

https://nineveh.htb/db

Right off the bat, we found login pages on either site. This could be our foothold on the system if we can crack the passwords. Before we do that, let’s look at the other directories we found through our gobuster scan.

https://nineveh.htb/secure_notes

This struck me as odd that there was only an image in the directory labeled ‘secure_notes’. This leads me to believe that the notes are stored inside of this image, using some steganography technique. We should download this image and take a look before we move on.

Download the image and save it to our working directory. Once this is complete I first like to start off with the strings command to pull out any printable strings before moving on to other tools. The command is simply: strings nineveh.png

We see that there is an RSA private key in the images as well as some jumbled mess surrounding it. To extract all of this in a more manageable fashion, let’s use the tool binwalk as follows:

Now we can see the files that are hidden inside of the image. There is a compressed file within the image that probably contains the SSH keys we saw from the strings output.

From the man page of binwalk we find that there are two options for extracting files that will be useful for us.

Flags -e and -M seem to be our best bet as they extract known files and then recursively scan extracted files, respectfully.

This turns out to be a great tool that provides us not only the extracted files but a nice description of each file to go along with it. Looking in our working directory we will find a directory with all of the extracted files from the binwalk.

Navigating to the secret directory, we will find the RSA public and private key.

We can try logging in to via SSH but if we remember from our initial Nmap scan port 22 is closed. This could mean there could be some interesting IP Tables rules on the machine. Now, back to the login pages on the web sites.

Cracking Login Pages using Hydra

Hydra is a fast and reliable tool for cracking logins of many different protocols. Today we will be using it on the login pages enumerated from our gobuster scan.

  • **It is not recommended to brute force on production machines as this may cause crashes and damage productivity. **

To set up our Hydra scan we will need two things, the way the credentials are passed to the server, and the error message that is displayed after a failed login attempt. We can easily see both of these by using Burp Suite’s Repeater function.

Firstly, open Burp Suite and turn the Proxy Intercept to ‘ON’.

Once the Proxy Intercept is turned on, we can navigate to our login screen and easily send the request through burp using the Firefox plugin ‘Foxy Proxy’.

We enter test credentials into username and password fields, then send the request through Burp Suite simply by clicking login. After clicking login, Burp Suite will pop-up with the intercepted request.

We can send this request to the ‘Repeater’ simply by using CTL+R:

Notice how the Repeater tab is now glowing orange. Navigate to the Repeater tab and forward the request to the server using the ‘send’ button.

This way we can see the request sent to the server, as well as the response from the server. Under the request tab, we see the following on the last line:

We will need the string username=admin&password=test to let Hydra know how to send the login request to the server. We will also need to see what an invalid login response is from the server. In the Response pane, look for a description of a failed login as shown:

The string Invalid Password! will let Hydra know that the attempt failed and to continue until it receives a different response.

Setting up our Hydra Command

With both the failed login attempt string and the method in which the login request is sent to the server, we can begin building our hydra command. Since there are many protocols that hydra supports, we will also need to specify that this login attempt is using the http-form-post service.

The complete hydra command will be as follows:

hydra -l admin -P /usr/share/seclists/Passwords/xato-net-10-million-passwords-10000.txt 10.10.10.43 http-post-form "/department/login.php:username=^USER^&password=^PASS^:Invalid" -t 64

The -l flag is for a single username, -P flag is for a password list, then we set the server, the service, the path to the login page connected to our login request string (using ^USER^ and ^PASS^ as variables in which the -l and -P flags fill in): the invalid response, and finally -t for the number of threads. If there is another application you would like to use hydra for please refer to the manual page using man hydra.

Running the command yields:

In the green, we get our valid login credentials for the http://ninveh.htb/department login page.

Now let us run hydra against the https://nineveh.htb/db/ login page. This one will be slightly different as there is no username. We will skip over retrieving the request string as that was covered in the previous section. The command is as follows:

kali@kali:~$ hydra -l '' -P /usr/share/seclists/Passwords/xato-net-10-million-passwords-10000.txt 10.10.10.43 https-post-form "/db/index.php:password=^PASS^&remember=yes&login=Log+In&proc_login=true:Incorrect" -t 64

Which yields the following results:

This password ended up being so easy we probably could have guessed it. Alas, we are logged in to both web interfaces.

Loggin into Web Interfaces

On the left we have the site running on port 80 and on the right we have the site running on or 443:

Starting with the nineveh.htb/department page, let’s explore the site and see what we find:

Under the Notes tab, we find this note left by the user ‘amrois’. I think we found his ‘secret’ folder mentioned in the notes already. The SSH keys were in it along with his username: amrois. If we look closer at the URL of this notes page it looks like we might be able to do some directory traversal.

We can assume that the manage.php file has a function notes which when called either uses the PHP file_get_contents() function or maybe the include function which would give us the ability to run PHP code on the machine. Let’s first look and see if we can navigate the filesystem by modifying the current file.

It appears that we cannot currently navigate the file system using directory traversal techniques such as:

There must be something filtering the results. Let’s try modifying the extension of the original NinevehNotes.txt file, and see if we get a different response.

We get an error message letting us know that we are in fact dealing with a PHP include() function. This means if we can get files on the server we can execute PHP code. This wouldn't have been possible if the function was file_get_contents. We must find a way to get files on this server. On that note, let’s check out the https://nineveh.htb/db page we got access to.

We see this page is running phpLiteAdmin v1.9 and it appears to be a simple web interface for the database. Using searchsploit we can look for known vulnerabilities in phpLiteAdmin.

We see two results with the version number that we know is running on the server. Firstly, let’s see what the Remote PHP code Injection is all about. We do this by the following command: searchsploit -x 24044 where 24044 is the exploit number to the right.

It looks like we have found a way to get PHP onto the server. Basically what this exploit is saying is if we create a database with the file extension of .PHP then we’re able to input PHP code as text into the table and navigate to that ‘PHP’ file on the server which will result in our PHP code running.

PHP Remote Code Injection

Using this proof of concept we can jump back into the phpLiteAdmin and create our database. In zexpher.php we add a table called zexpher and give it 1 number of fields.

Next, we must write our PHP code into the database field as TEXT. Our PHP code will be <?php echo system($_REQUEST["cmd"]);?>

Now we must rename the database to ‘ninevehNotes’ because there is something that searches for the string ninevehNotes in site that displays the notes.

Now we can navigate to this file in the department site and attempt code execution.

Using a series of /../ to move back a directory, and using &cmd=ls to call the request function we added to the database:system($_REQUEST[“cmd”]);, and lastly, we run the ls command on the system. We have code execution and a web shell!

Privilege Escalation

Now that we have code execution we can begin to look around the system for a means of either uploading a reverse shell or using the RSA keys that we found earlier in the enumeration phase.

Let’s just poke around in the file system to see if anything interesting sticks out to us.

From here we see an odd directory named report. Let’s look into this.

Here we see that there is some process creating report files every minute. Cat the output of one of these files gives us the following:

This appears to be some sort of exploit/vulnerability scanner checking the files on the system every minute. If we can find the CRON job that is activating this we can get a reverse shell back to our system.

At the bottom of this file, we see a few log files with the same three-letter prefix, “chk”. This could give us a clue as to what program is running this scan.

Using the following google search we find a PDF that looks like it might have what we need. From the description, the last line provides a program “chkrootkit”. Before diving in and reading the whole document we might as well see if we can find other files on the system with the name “chkrootkit”. Using the locate command should serve us well in this case.

Voila! We got lucky and found the program that is probably running a cron job creating our minutely reports. Let’s look into the documentation of this program and see if there is anything that we can take advantage of. Starting off with a simple searchsploit:

Looks like we have a method of privilege escalation. Let’s look into that:

Wow, we hit the jackpot with that hunch on the strange directory. We have a possible path to root by only creating a file in a certain directory.

We can easily write the file in the /tmp/ directory by first writing it in our host machine and then using wget to download the file to the server.

pentestmonkey’s reverse shell cheat sheet

I will be using the second Netcat shell and modifying it to our IP.

Now on our machine, we must make this file executable. This can be done easily with chmod +x update. Lastly, we host the file on our machine using a python SimpleHTTPServer.

Now back to our web shell, we simply download the file and wait for our connection back.

We can string together commands with the ; delimiter which will let us be able to move directories and then download the file into the /tmp directory as the proof of concept suggests.

We also need to make sure this file is executable by all users on the system. We can do this by using the following command: chmod +777 update.

Now all there is to do is wait one minute until the script runs again, and we should get a shell back as root.

We have gotten to root from a simple non-interactive web shell! This was an excellent exercise in using the Linux terminal commands in creative ways when you do not have access to an interactive shell.

Bonus: Port knocking and using found RSA Keys

You might have realized that we never really needed the RSA keys we found through steganalysis. If you were inclined to use those, here is a solution.

I find that you can learn a lot about a system by looking at the documentation provided in the /usr/share/docs directory or somewhere similar. Looking through this directory we find quite a few programs that have documentation.

To narrow down our search, we should consider that earlier when we tried the ssh keys, port 22 was closed. Coupling this information with the fact that another user provided the keys in a secret file. This means that the port has to have some way of the port opening so that the authorized users can gain access to it. A common way to achieve this is a method called Port Knocking. We know that we are dealing with a Linux machine, so let’s look at the most common port knocking programs and see if we find them, or any documentation of them on the server.

Trusty Google has provided us with the most commonly used service called knockd.

We can either search through the results of the documentation or directly search the system for knockd using the locate and which commands.

Firstly, let’s search for the documentation:

Using our browser's search function we quickly locate the knockd documentation.

Now, let’s search the system directly for knockd:

Checking /etc/init.d/knockd we find:

In the DEFAULTS_FILE we see a path for /etc/default/knockd. Opening that yields:

From here we are lead to /etc/knockd.conf in the PLEASE EDIT section. Once again, let’s see what is in there:

Here we are finally greeted with the key to open and close the SSH port. This is configured to open after the sequence of ports: 571, 290, 911 are hit with TCP SYN packets in the correct order. The easiest way to knock as a client is by downloading knockd using sudo apt-get install knockd.

After installation, simply use the following commands:

Now we simply log in using the found key.

Thank you for reading!

Happy Hacking

-zexpher

--

--