SQLmap

 


                                                                     SQLMAP

SQLMap is a free and open-source penetration testing tool written in Python that automates the process of detecting and exploiting SQL injection (SQLi) flaws. SQLMap has been continuously developed since 2006 and is still maintained today. SQLMap comes with a powerful detection engine, numerous features, and a broad range of options and switches for fine-tuning the many aspects of it, such as: 
Enumeration Optimization Protection detection and bypass using "tamper" scripts
Database content retrieval File system access Execution of the operating system (OS) commands. 

SQLMap has the largest support for DBMSes of any other SQL exploitation tool. SQLMap fully supports the following DBMSes:

MySQL  Oracle  PostgreSQL  Microsoft SQL Server
SQLite  IBM DB2  Microsoft Access  Firebird
Sybase  SAP MaxDB  Informix  MariaDB
HSQLDB  CockroachDB  TiDB  MemSQL
H2  MonetDB  Apache Derby  Amazon Redshift
Vertica, Mckoi  Presto  Altibase  MimerSQL
CrateDB  Greenplum  Drizzle  Apache Ignite
Cubrid  InterSystems Cache  IRIS  eXtremeDB
FrontBase

The SQLMap team also works to add and support new DBMSes periodically. SQLMap is the only penetration testing tool that can properly detect and exploit all known SQLi types. 

The technique characters BEUSTQ refers to the following:

  • B: Boolean-based blind: SQLMap exploits Boolean-based blind SQL Injection vulnerabilities through the differentiation of TRUE from FALSE query results, effectively retrieving 1 byte of information per request. The differentiation is based on comparing server responses to determine whether the SQL query returned TRUE or FALSE. This ranges from fuzzy comparisons of raw response content, HTTP codes, page titles, filtered text, and other factors.
    • TRUE results are generally based on responses having none or marginal difference to the regular server response.

    • FALSE results are based on responses having substantial differences from the regular server response.

    • Boolean-based blind SQL Injection is considered as the most common SQLi type in web applications.

  • E: Error-based: If the database management system (DBMS) errors are being returned as part of the server response for any database-related problems, then there is a probability that they can be used to carry the results for requested queries. In such cases, specialized payloads for the current DBMS are used, targeting the functions that cause known misbehaviors. SQLMap has the most comprehensive list of such related payloads and covers Error-based SQL Injection for the following DBMSes:
    MySQL PostgreSQL Oracle
    Microsoft SQL Server Sybase Vertica
    IBM DB2 Firebird MonetDB

    Error-based SQLi is considered as faster than all other types, except UNION query-based, because it can retrieve a limited amount (e.g., 200 bytes) of data called "chunks" through each request.

  • U: Union query-based: With the usage of UNION, it is generally possible to extend the original (vulnerable) query with the injected statements' results. This way, if the original query results are rendered as part of the response, the attacker can get additional results from the injected statements within the page response itself. This type of SQL injection is considered the fastest, as, in the ideal scenario, the attacker would be able to pull the content of the whole database table of interest with a single request.
  • S: Stacked queries: Stacking SQL queries, also known as the "piggy-backing," is the form of injecting additional SQL statements after the vulnerable one. In case that there is a requirement for running non-query statements (e.g. INSERT, UPDATE or DELETE), stacking must be supported by the vulnerable platform (e.g., Microsoft SQL Server and PostgreSQL support it by default). SQLMap can use such vulnerabilities to run non-query statements executed in advanced features (e.g., execution of OS commands) and data retrieval similarly to time-based blind SQLi types.
  • T: Time-based blind: The principle of Time-based blind SQL Injection is similar to the Boolean-based blind SQL Injection, but here the response time is used as the source for the differentiation between TRUE or FALSETime-based blind SQL Injection is considerably slower than the boolean-based blind SQLi, since queries resulting in TRUE would delay the server response. This SQLi type is used in cases where Boolean-based blind SQL Injection is not applicable.
  • Q: Inline queries: This type of injection embedded a query within the original query. Such SQL injection is uncommon, as it needs the vulnerable web app to be written in a certain way. Still, SQLMap supports this kind of SQLi as well.
  • Out-of-band SQL Injection: This is considered one of the most advanced types of SQLi, used in cases where all other types are either unsupported by the vulnerable web application or are too slow (e.g., time-based blind SQLi). SQLMap supports out-of-band SQLi through "DNS exfiltration," where requested queries are retrieved through DNS traffic.

                                               Getting Started with SQLMap

Upon starting using SQLMap, the first stop for new users is usually the program's help message. To help new users, there are two levels of help message listing: 
1.Basic Listing shows only the basic options and switches, sufficient in most cases (switch -h)
2.Advanced Listing shows all options and switches (switch -hh)


let's try and see how it works. 


 the switch '--batch' is used for skipping any required user-input, by automatically choosing using the default option. 

                                              SQLMap Output Description

if you scan you can see a lot of information that it showing up. This data is usually crucial to understand, as it guides us through the automated SQL injection process. This shows us exactly what kind of vulnerabilities SQLMap is exploiting, which helps us report what type of injection the web application has. This can also become handy if we wanted to manually exploit the web application once SQLMap determines the type of injection and vulnerable parameter. The following are some of the most common messages usually found during a scan of SQLMap: 
  • "target URL content is stable" , 
This means that there are no major changes between responses in case of continuous identical requests. 
  • "GET parameter 'id' appears to be dynamic"
It is always desired for the tested parameter to be "dynamic," as it is a sign that any changes made to its value would result in a change in the response; hence the parameter may be linked to a database. In case the output is "static" and does not change, it could be an indicator that the value of the tested parameter is not processed by the target, at least in the current context.
  • "GET parameter 'id' might be injectable" 
which indicates that the tested parameter could be SQLi injectable and that the target could be MySQL. It should be noted that this is not proof of SQLi, but just an indication that the detection mechanism has to be proven in the subsequent run. 

  • "parameter 'id' might be vulnerable to cross-site scripting (XSS) attacks"
While it is not its primary purpose, SQLMap also runs a quick heuristic test for the presence of an XSS vulnerability. In large-scale tests, where a lot of parameters are being tested with SQLMap, it is nice to have these kinds of fast heuristic checks, especially if there are no SQLi vulnerabilities found.
  • "it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n]"
In a normal run, SQLMap tests for all supported DBMSes. In case that there is a clear indication that the target is using the specific DBMS, we can narrow down the payloads to just that specific DBMS.
  • "for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n]"
This basically means running all SQL injection payloads for that specific DBMS, while if no DBMS were detected, only top payloads would be tested.
  • "GET parameter 'id' appears to be 'AND boolean-based blind - WHERE or HAVING clause' injectable (with --string="luther")"
This message indicates that the parameter appears to be injectable, though there is still a chance for it to be a false-positive finding.Additionally, with --string="luther" indicates that SQLMap recognized and used the appearance of constant string value luther in the response for distinguishing TRUE from FALSE responses. This is an important finding because in such cases, there is no need for the usage of advanced internal mechanisms, such as dynamicity/reflection removal or fuzzy comparison of responses, which cannot be considered as false-positive. 
  • "time-based comparison requires a larger statistical model, please wait........... (done)"
SQLMap uses a statistical model for the recognition of regular and (deliberately) delayed target responses. For this model to work, there is a requirement to collect a sufficient number of regular response times. This way, SQLMap can statistically distinguish between the deliberate delay even in the high-latency network environments.
  • "automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found"
UNION-query SQLi checks require considerably more requests for successful recognition of usable payload than other SQLi types.
  • "ORDER BY' technique appears to be usable. This should reduce the time needed to find the right number of query columns. Automatically extending the range for current UNION query injection technique test"

As a heuristic check for the UNION-query SQLi type, before the actual UNION payloads are sent, a technique known as ORDER BY is checked for usability. In case that it is usable, SQLMap can quickly recognize the correct number of required UNION columns by conducting the binary-search approach.

  • "GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N]"

This is one of the most important messages of SQLMap, as it means that the parameter was found to be vulnerable to SQL injections. In the regular cases, the user may only want to find at least one injection point (i.e., parameter) usable against the target. However, if we were running an extensive test on the web application and want to report all potential vulnerabilities, we can continue searching for all vulnerable parameters.

  • "sqlmap identified the following injection point(s) with a total of 46 HTTP(s) requests:"

Following after is a listing of all injection points with type, title, and payloads, which represents the final proof of successful detection and exploitation of found SQLi vulnerabilities. It should be noted that SQLMap lists only those findings which are provably exploitable (i.e., usable).

  • "fetched data logged to text files under '/home/user/.sqlmap/output/www.example.com'"
This indicates the local file system location used for storing all logs, sessions, and output data for a specific target - in this case, www.example.com. After such an initial run, where the injection point is successfully detected, all details for future runs are stored inside the same directory's session files.

                                       Running SQLMap on an HTTP Request

SQLMap has numerous options and switches that can be used to properly set up the (HTTP) request before its usage. In many cases, simple mistakes such as forgetting to provide proper cookie values, over-complicating setup with a lengthy command line, or improper declaration of formatted POST data, will prevent the correct detection and exploitation of the potential SQLi vulnerability.

  • Curl Commands: One of the best and easiest ways to properly set up an SQLMap request against the specific target is by utilizing Copy as cURL feature from within the Network (Monitor) panel inside  right click  the url and copy value and copy url to curl posix every browser is same  Chrome, Edge, or Firefox Developer Tools.

By pasting the clipboard content (Ctrl-V) into the command line, and changing the original command curl to sqlmap, we are able to use SQLMap with the identical curl command:

curl 'http://www.uni-1.com.hk/about_en.php?id=2' \
  -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:139.0) Gecko/20100101 Firefox/139.0' \
  -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' \
  -H 'Accept-Language: en-US,en;q=0.5' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Sec-GPC: 1' \
  -H 'Connection: keep-alive' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'DNT: 1' \
  -H 'Priority: u=0, i'
here just replace curl to sqlmap -u
  • GET/POST RequestsIn the most common scenario, GET parameters are provided with the usage of option -u/--url, as in the previous example. As for testing POST data, the --data flag can be used, as follows: sqlmap 'http://www.example.com/' --data 'uid=1&name=test'
  • In such cases, POST parameters uid and name will be tested for SQLi vulnerability. For example, if we have a clear indication that the parameter uid is prone to an SQLi vulnerability, we could narrow down the tests to only this parameter using -p uid. Otherwise, we could mark it inside the provided data with the usage of special marker * as follows: sqlmap 'http://www.example.com/' --data 'uid=1*&name=test'
Note: here & symbols means both of the part it will try but in the second * this sign means it will test only id part and secound will be ignored.

  • Full HTTP Requests: If we need to specify a complex HTTP request with lots of different header values and an elongated POST body, we can use the -r flag. With this option, SQLMap is provided with the "request file," containing the whole HTTP request inside a single textual file.  In a common scenario, such HTTP request can be captured from within a specialized proxy application (e.g. Burp) and written into the request file. An example of an HTTP request captured with Burp would look like: 
  • GET /about_en.php?id=2 HTTP/1.1
  • Host: www.uni-1.com.hk
  • Cache-Control: max-age=0
  • Upgrade-Insecure-Requests: 1
  • User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 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.7
  • Accept-Encoding: gzip, deflate, br
  • Accept-Language: en-US,en;q=0.9,bn;q=0.8
  • Connection: keep-alive

copy the request create a new text file in kali and past the request in the file . so now commands looks like:: sqlmap -r req.txt (here -r means request file)


  • Custom SQLMap Requests: If we wanted to craft complicated requests manually, there are numerous switches and options to fine-tune SQLMap. if there is a requirement to specify the (session) cookie value to. like 
  •  PHPSESSID:tsp9mv599geou4radthsh1s6r5 option --cookie would be used as follows: 

The same effect can be done with the usage of option -H/--header sqlmap ... -H='Cookie:PHPSESSID=ab4530f4a7d10448457fa8b0eadac29c' 

We can apply the same to options like --host, --referer, and -A/--user-agent, which are used to specify the same HTTP headers' values. Furthermore, there is a switch --random-agent designed to randomly select a User-agent header value from the included database of regular browser values.
Also, if we wanted to specify an alternative HTTP method, other than GET and POST (e.g., PUT), we can utilize the option --method, as follows:

sqlmap -u www.target.com --data='id=1' --method PUT

  • Custom HTTP Requests: Apart from the most common form-data POST body style (e.g. id=1), SQLMap also supports JSON formatted (e.g. {"id":1}) and XML formatted (e.g. <element><id>1</id></element>) HTTP requests.

                                               Handling SQLMap Errors

We may face many problems when setting up SQLMap or using it with HTTP requests. In this section, we will discuss the recommended mechanisms for finding the cause and properly fixing it. With this option, SQLMap will automatically print the DBMS error, thus giving us clarity on what the issue may be so that we can properly fix it. The -t option stores the whole traffic content to an output file: sqlmap -u "http://www.target.com/vuln.php?id=1" --batch -t /tmp/traffic.txt. As we can see from the above output, the /tmp/traffic.txt file now contains all sent and received HTTP requests. So, we can now manually investigate these requests to see where the issue is occurring. Another useful flag is the -v option, which raises the verbosity level of the console output:sqlmap -u "http://www.target.com/vuln.php?id=1" -v 6 --batch, As we can see, the -v 6 option will directly print all errors and full HTTP request to the terminal so that we can follow along with everything SQLMap is doing in real-time. Finally, we can utilize the --proxy option to redirect the whole traffic through a (MiTM) proxy (e.g., Burp). This will route all SQLMap traffic through Burp, so that we can later manually investigate all requests, repeat them, and utilize all features of Burp with these requests. 

                                                           Attack Tuning

In most cases, SQLMap should run out of the box with the provided target details.  Every payload sent to the target consists of:
  • vector (e.g., UNION ALL SELECT 1,2,VERSION()): central part of the payload, carrying the useful SQL code to be executed at the target.

  • boundaries (e.g. '<vector>-- -): prefix and suffix formations, used for proper injection of the vector into the vulnerable SQL statement.

There is a requirement for special prefix and suffix values in rare cases, not covered by the regular SQLMap run. For such runs, options --prefix and --suffix can be used as follows: sqlmap -u "www.example.com/?q=test" --prefix="%'))" --suffix="-- -" 
This will result in an enclosure of all vector values between the static prefix %')) and the suffix -- -.

By default, SQLMap combines a predefined set of most common boundaries (i.e., prefix/suffix pairs), along with the vectors having a high chance of success in case of a vulnerable target. by default (i.e. --level=1 --risk=1), the number of payloads used for testing a single parameter goes up to 72, while in the most detailed case (--level=5 --risk=3) the number of payloads increases to 7,865. As SQLMap is already tuned to check for the most common boundaries and vectors, regular users are advised not to touch these options because it will make the whole detection process considerably slower. Nevertheless, in special cases of SQLi vulnerabilities, where usage of OR payloads is a must (e.g., in case of login pages), we may have to raise the risk level ourselves. 

                                                    Database Enumeration

Enumeration represents the central part of an SQL injection attack, which is done right after the successful detection and confirmation of exploitability of the targeted SQLi vulnerability. It consists of lookup and retrieval (i.e., exfiltration) of all the available information from the vulnerable database.  SQLMap has a predefined set of queries for all supported DBMSes, where each entry represents the SQL that must be run at the target to retrieve the desired content. Usually, after a successful detection of an SQLi vulnerability, we can begin the enumeration of basic details from the database, such as the hostname of the vulnerable target (--hostname), current user's name (--current-user), current database name (--current-db), or password hashes (--passwords). SQLMap will skip SQLi detection if it has been identified earlier and directly start the DBMS enumeration process.

Enumeration usually starts with the retrieval of the basic information:

  • Database version banner (switch --banner)
  • Current user name (switch --current-user)
  • Current database name (switch --current-db)
  • Checking if the current user has DBA (administrator) rights (switch --is-dba)


Note: The 'root' user in the database context in the vast majority of cases does not have any relation with the OS user "root", other than that representing the privileged user within the DBMS context. This basically means that the DB user should not have any constraints within the database context, while OS privileges (e.g. file system writing to arbitrary location) should be minimalistic, at least in the recent deployments. The same principle applies for the generic 'DBA' role.

In most common scenarios, after finding the current database name (i.e. testdb), the retrieval of table names would be by using the --tables option and specifying the DB name with -D testdb, is as follows. 


After spotting the table name of interest, retrieval of its content can be done by using the --dump option and specifying the table name with -T users, as follows. --dump -T users -D testdb.


When dealing with large tables with many columns and/or rows, we can specify the columns (e.g., only name and surname columns) with the -C option, as follows. --dump -T users -D testdb -C name,surname. To narrow down the rows based on their ordinal number(s) inside the table, we can specify the rows with the --start and --stop options (e.g., start from 2nd up to 3rd entry), as follows. --dump -T users -D testdb --start=2 --stop=3. If there is a requirement to retrieve certain rows based on a known WHERE condition (e.g. name LIKE 'f%'), we can use the option --where, as follows: --dump -T users -D testdb --where="name LIKE 'f%'". As for the --dump-all switch, all the content from all the databases will be retrieved.

                                                   Advanced Database Enumeration

Now that we have covered the basics of database enumeration with SQLMap, we will cover more advanced techniques to enumerate data of interest further in this section. If we wanted to retrieve the structure of all of the tables so that we can have a complete overview of the database architecture, we could use the switch --schema:  sqlmap -u "http://www.example.com/?id=1" --schema. 

When dealing with complex database structures with numerous tables and columns, we can search for databases, tables, and columns of interest, by using the --search option. This option enables us to search for identifier names by using the LIKE operator. For example, if we are looking for all of the table names containing the keyword user, we can run SQLMap as follows: sqlmap -u "http://www.example.com/?id=1" --search -T user 

Once we identify a table containing passwords (e.g. master.users), we can retrieve that table with the -T option. -D master: Specifies the database. sqlmap -u "http://www.example.com/?id=1" --dump -D master -T users.

Tip: The '--all' switch in combination with the '--batch' switch, will automa(g)ically do the whole enumeration process on the target itself, and provide the entire enumeration details.

                                 Bypassing Web Application Protections

WAF Bypass: Whenever we run SQLMap, As part of the initial tests, SQLMap sends a predefined malicious looking payload using a non-existent parameter name (e.g. ?pfov=...) to test for the existence of a WAF (Web Application Firewall). There will be a substantial change in the response compared to the original in case of any protection between the user and the target. For example, if one of the most popular WAF solutions (ModSecurity) is implemented, there should be a 406 - Not Acceptable response after such a request.  In case of a positive detection, to identify the actual protection mechanism, SQLMap uses a third-party library identYwaf, containing the signatures of 80 different WAF solutions. If we wanted to skip this heuristical test altogether (i.e., to produce less noise), we can use switch --skip-waf--skip-waf --tamper=between,charencode --random-agent --dump. 

User-agent Blacklisting Bypass: In case of immediate problems (e.g., HTTP error code 5XX from the start) while running SQLMap, one of the first things we should think of is the potential blacklisting of the default user-agent used by SQLMap. This is trivial to bypass with the switch --random-agent, which changes the default user-agent with a randomly chosen value from a large pool of values used by browsers. 

IP Address Concealing: In case we want to conceal our IP address, or if a certain web application has a protection mechanism that blacklists our current IP address, we can try to use a proxy or the anonymity network Tor. A proxy can be set with the option --proxy. In addition to that, if we have a list of proxies, we can provide them to SQLMap with the option --proxy-file. This way, SQLMap will go sequentially through the list, in case of any problems (e.g., blacklisting of IP address), it will just skip from current to the next from the list. If we wanted to be sure that Tor is properly being used, to prevent unwanted behavior, we could use the switch --check-tor

                                                           OS Exploitation

Reading Local Files: SQLMap has the ability to utilize an SQL Injection to read and write files from the local system outside the DBMS. SQLMap can also attempt to give us direct command execution on the remote host if we had the proper privileges. The first part of OS Exploitation through an SQL Injection vulnerability is reading and writing data on the hosting server. Reading data is much more common than writing data, which is strictly privileged in modern DBMSes, as it can lead to system exploitation, as we will see. read local files, the DB user must have the privilege. While we do not necessarily need to have database administrator privileges (DBA) to read data, this is becoming more common in modern DBMSes. The same applies to other common databases. Still, if we do have DBA privileges, then it is much more probable that we have file-read privileges.

Checking for DBA Privileges: To check whether we have DBA privileges with SQLMap, we can use the --is-dba option. like this: sqlmap -u "http://www.uni-1.com.hk/about_en.php?id=2" --is-dba. As we can see, if we test that on one of the previous exercises, we get current user is DBA: False, meaning that we do not have DBA access.

 if it shows true this means we have DBA access. let's see one which has a access and DBA : true


now we have access let's try to read the local file. here you can see that dbms is windows. 


so let's windows payload. it's maybe fix. let's another. here you can see we successfully read the file .

We have successfully retrieved the remote file. 

Writing Local Files: When it comes to writing files to the hosting server, it becomes much more restricted in modern DMBSes, since we can utilize this to write a Web Shell on the remote server, and hence get code execution and take over the server. in MySql, the --secure-file-priv configuration must be manually disabled to allow writing data into local files using the INTO OUTFILE SQL query, in addition to any local access needed on the host server, like the privilege to write in the directory we need. Still, many web applications require the ability for DBMSes to write data into files, so it is worth testing whether we can write files to the remote server. To do that with SQLMap, we can use the --file-write and --file-dest options. First, let's prepare a basic PHP web shell and write it into a shell.php file: 


then 


                                            OS Command Execution

Now that we confirmed that we could write a PHP shell to get command execution, we can test SQLMap's ability to give us an easy OS shell without manually writing a remote shell. SQLMap utilizes various techniques to get a remote shell through SQL injection vulnerabilities, like writing a remote shell, as we just did, writing SQL functions that execute commands and retrieve output or even using some SQL queries that directly execute OS command, like xp_cmdshell in Microsoft SQL Server. To get an OS shell with SQLMap, we can use the --os-shell option, as follows:

the Error-based SQL Injection, which we can specify with --technique=E:


Note: SQLMap first asked us for the type of language used on this remote server, which we know is PHP. Then it asked us for the server web root directory, and we asked SQLMap to automatically find it using 'common location(s)'. Both of these options are the default options, and would have been automatically chosen if we added the '--batch' option to SQLMap.




















0 Comments