This is the write-up for the first machine I pwned for my OSCP preparation. So, with that said let’s get into it!
Host Discovery and Port Scanning
The first step is to find out what is our target machine’s IP address. We can do that by doing a host scan on our network.
sudo nmap -sn 192.168.181.0/24 -oN nmap_discovery
Knowing 192.168.181.132
is our attacker machine’s IP address, we can identify that 192.168.181.134
is our target. Once our target has been identified, we can now perform port scanning on our target with the following:
sudo nmap -sC -sV -Pn 192.168.181.134 -oN nmap_port_scan
-sC
: load default nmap scripts-sV
: Version scan-Pn
: Assume all hosts are up-oN
: Outputs file in normal format
The results show that the target machine allows ssh
on port 22, but it is filtered indicating there might be a knockd
service running on it. A web server is also running on the target machine on port 80. With that, let’s take a look at the web server.
Footprinting Website
Entering the IP address of the target machine into the browser’s address bar shows the main page of the website.
Display All Records shows all the records of staff members working for Example.com.
Users are able to search for specific staff members in Search.
Users are able to type in the first or last name of the staff and the website will return the staff member’s data. This may be a good entry point for a SQL injection.
Manage requires the user to log in to access its contents.
SQL Injection
After viewing all the functions the website gives the user, let’s engage the Search page as mentioned before, it may be a good entry point for a SQL injection. We can test the entry point with BurpSuite and FoxyProxy.
FoxyProxy is used to route HTTP requests to BurpSuite before sending the requests to the server.
This is the default request headers and data sent to the server. We can modify the search value to see whether the input field is vulnerable to a SQL injection.
To prove that SQL injections work on the input field, the following input is entered:
mary';--%00
mary’ ;
is to end the SQL statement--
is to comment out the rest of the SQL statements after;
%00
the null byte is added as some database engines may not always treat comments as a way to terminate a SQL statement
Doing so reveals the same output as the one returned before. Therefore, proving that the SQL statement is successful. With that, let’s enumerate the server’s database!
Using the following statement, until it produces the same result as the last time with the addition of the name of the current database, allows the attacker to determine the structure of the server’s database.
mary' UNION ALL SELECT database();--%00
mary' UNION ALL SELECT 1,database();--%00
mary' UNION ALL SELECT 1,2,database();--%00
mary' UNION ALL SELECT 1,2,3,database();--%00
mary' UNION ALL SELECT 1,2,3,4,database();--%00
mary' UNION ALL SELECT 1,2,3,4,5,database();--%00
concat()
gets the specified column, which returns multiple rows and is put into one stringinformation_schema
contains information about all the databases and tables.tables
will give you all the tables with these column names
TABLE_CATALOG
TABLE_SCHEMA
TABLE_NAME
TABLE_TYPE
.columns
will give you all the columns- Similar table with
.tables
butCOLUMN_NAME
is present
Using the following statement reveals the databases available on the server.
mary' UNION ALL SELECT 1,2,3,4,5,concat(schema_name) FROM information_schema.schemata;--%00
Using the following statement reveals the tables in the Staff database.
mary' UNION ALL SELECT 1,2,3,4,5,concat(table_name) FROM information_schema.tables WHERE table_schema='Staff';--%00
Using the following statement reveals the columns in the Users table.
mary' UNION ALL SELECT 1,2,3,4,5,concat(column_name) FROM information_schema.columns WHERE table_name='Users';--%00
Using the following statement reveals the records in the Users table. The only record available is the admin’s record.
Username: admin
Password: 856f5de590ef37314e7c3bdf6f8a66dc
Looking at the password, it seems to be a hash value. Placing that into CrackStation reveals that the password is transorbital1
.
Remember that there are two databases, “StaffDetails” and “users”. The same process is done for the “users” database.
There is only one table in the users database, UserDetails.
There are 2 columns that an attacker would find interesting, username and password.
The records reveal the usernames as well as passwords of each user working for Example.com.
Local File Inclusion
Now that we know the admin’s password as well as the usernames and passwords for the server, let’s start by logging into the admin’s account. Logging into the admin’s account, the “Manage” and “Add Record” directories show that we are already logged in as admin and that a file does not exist. This may be a clue to a Local File Inclusion (LFI) vulnerability.
According to (Demir, 2023), one of the common parameters that are used for testing LFI is file
. Using that parameter, and searching for the /etc/passwd
file, the following parameter value allows us to reach that file:
file=../../../../../../../etc/passwd
Remember that the server might have knockd
configured, let’s try to find the configuration file. The default location for the configuration file is /etc/knockd.conf
.
Finding the file reveals that knockd
is configured and that opening the ssh
requires the attacker to ping ports 7469, 8475, and 9842, in that order.
Opening SSH
-c
: tells hping3 how many times to ping to the specific port-p
: is the port that the attacker wants to ping to-S
: stands for syn packets to be delivered
Pinging to those ports mentioned allows the attacker to ssh into the server. Using the usernames and passwords retrieved from the database, allows us to log in as one of the server’s users.
Note: Some of the users’ passwords are incorrect
Privilege Escalation
Now that the attacker has access to the server, let’s enumerate the system for privilege escalation vectors.
A python HTTP server is started so that linpeas.sh
can be downloaded from the target machine with wget
. However, running linpeas.sh
reveals nothing of use.
However, one file directory that linpeas.sh
did not scan is the /opt
directory. Within that directory, there are scripts and development-related files. The scripts directory is not accessible, but the devstuff
directory is accessible.
Within the devstuff
directory, the source code of a binary is discovered as the dist and build folder is present.
The source code reveals that it will read a file and copy its contents and append or add its contents to another file. This allows us to write the /etc/password
file with a new user with root privileges.
A hash value of the password password123
that is used by /etc/passwd
will be generated by openssl
to be inserted into /etc/passwd
.
The new record will be placed in newuser.txt
in the /tmp
directory for later use.
The location of the binary is located in /opt/devstuff/dist/test
. However, executing the following will fail as accessing /etc/passwd
requires root privileges, which the binary does not.
Logging into other user accounts, I found that the user janitor
has a hidden directory named .secrets-for-putin
.
The directory contains the file passwords-found-on-post-it-notes.txt
.
Brute-Forcing Passwords with Hydra
With the usernames gained from the database and the new passwords found. Hydra can be used to brute-force the list of users found with the list of passwords. Doing so reveals that the user fredf
has the password B4-Tru3–001
which is different from the password in the database.
Using sudo -l
to view sudo privileges show the attacker that the user can use sudo on the binary that we found.
Executing the command shown above adds a new user to the server.
Switching the user with the su
command and the username newuser
and entering the password password123
allows the attacker to log in as the user mentioned. The whoami
command is executed to show that the attacker now has root privileges.
Going to the /root
directory shows us the flag file, which concludes this challenge.
In conclusion, this challenge is pretty simple for most people. However, I find difficulty in it as I need to know everything that I execute. Specifically, why do we need to add a null byte within the SQL injection when there is already a comment present? Also, why is the file
parameter used instead of an a
or f
? Nevertheless, I managed to complete the challenge and come out with refreshed and new knowledge.
References
Demir, B. (2023, January 4). A Pentester’s Guide to File Inclusion | Cobalt. https://www.cobalt.io/blog/a-pentesters-guide-to-file-inclusion