mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-08-02 11:20:10 +03:00
Merge remote-tracking branch 'sqlmapproject/master'
This commit is contained in:
commit
a51645f783
104
doc/CHANGELOG.md
104
doc/CHANGELOG.md
|
@ -28,9 +28,9 @@
|
||||||
* Added switch `--check-waf` for checking of existence of WAF/IPS/IDS protection.
|
* Added switch `--check-waf` for checking of existence of WAF/IPS/IDS protection.
|
||||||
* Added switch `--schema` to enumerate DBMS schema: shows all columns of all databases' tables.
|
* 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.
|
* 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.
|
* Major improvements to switches `--tables` and `--columns`.
|
||||||
* Takeover switch --os-pwn improved: stealthier, faster and AV-proof.
|
* Takeover switch `--os-pwn` improved: stealthier, faster and AV-proof.
|
||||||
* Added switch --mobile to imitate a mobile device through HTTP User-Agent header.
|
* Added switch `--mobile` to imitate a mobile device through HTTP User-Agent header.
|
||||||
|
|
||||||
# Version 0.9 (2011-04-10)
|
# Version 0.9 (2011-04-10)
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
* Extended old `--dump -C` functionality to be able to search for specific database(s), table(s) and column(s), option `--search`.
|
* Extended old `--dump -C` functionality to be able to search for specific database(s), table(s) and column(s), option `--search`.
|
||||||
* Added support to tamper injection data with option `--tamper`.
|
* Added support to tamper injection data with option `--tamper`.
|
||||||
* Added automatic recognition of password hashes format and support to crack them with a dictionary-based attack.
|
* Added automatic recognition of password hashes format and support to crack them with a dictionary-based attack.
|
||||||
* Added support to enumerate roles on Oracle, --roles switch.
|
* Added support to enumerate roles on Oracle, `--roles` switch.
|
||||||
* Added support for SOAP based web services requests.
|
* Added support for SOAP based web services requests.
|
||||||
* Added support to fetch unicode data.
|
* Added support to fetch unicode data.
|
||||||
* Added support to use persistent HTTP(s) connection for speed improvement, switch `--keep-alive`.
|
* Added support to use persistent HTTP(s) connection for speed improvement, switch `--keep-alive`.
|
||||||
|
@ -94,12 +94,12 @@
|
||||||
|
|
||||||
# Version 0.8 release candidate (2009-09-21)
|
# Version 0.8 release candidate (2009-09-21)
|
||||||
|
|
||||||
* Major enhancement to the Microsoft SQL Server stored procedure heap-based buffer overflow exploit (--os-bof) to automatically bypass DEP memory protection.
|
* Major enhancement to the Microsoft SQL Server stored procedure heap-based buffer overflow exploit (`--os-bof`) to automatically bypass DEP memory protection.
|
||||||
* Added support for MySQL and PostgreSQL to execute Metasploit shellcode via UDF 'sys_bineval' (in-memory, anti-forensics technique) as an option instead of uploading the standalone payload stager executable.
|
* Added support for MySQL and PostgreSQL to execute Metasploit shellcode via UDF 'sys_bineval' (in-memory, anti-forensics technique) as an option instead of uploading the standalone payload stager executable.
|
||||||
* Added options for MySQL, PostgreSQL and Microsoft SQL Server to read/add/delete Windows registry keys.
|
* Added options for MySQL, PostgreSQL and Microsoft SQL Server to read/add/delete Windows registry keys.
|
||||||
* Added options for MySQL and PostgreSQL to inject custom user-defined functions.
|
* Added options for MySQL and PostgreSQL to inject custom user-defined functions.
|
||||||
* Added support for --first and --last so the user now has even more granularity in what to enumerate in the query output.
|
* Added support for `--first` and `--last` so the user now has even more granularity in what to enumerate in the query output.
|
||||||
* Minor enhancement to save the session by default in 'output/hostname/session' file if -s option is not specified.
|
* Minor enhancement to save the session by default in 'output/hostname/session' file if `-s` option is not specified.
|
||||||
* Minor improvement to automatically remove sqlmap created temporary files from the DBMS underlying file system.
|
* Minor improvement to automatically remove sqlmap created temporary files from the DBMS underlying file system.
|
||||||
* Minor bugs fixed.
|
* Minor bugs fixed.
|
||||||
* Major code refactoring.
|
* Major code refactoring.
|
||||||
|
@ -108,13 +108,13 @@
|
||||||
|
|
||||||
* Adapted Metasploit wrapping functions to work with latest 3.3 development version too.
|
* Adapted Metasploit wrapping functions to work with latest 3.3 development version too.
|
||||||
* Adjusted code to make sqlmap 0.7 to work again on Mac OSX too.
|
* Adjusted code to make sqlmap 0.7 to work again on Mac OSX too.
|
||||||
* Reset takeover OOB features (if any of --os-pwn, --os-smbrelay or --os-bof is selected) when running under Windows because msfconsole and msfcli are not supported on the native Windows Ruby interpreter. This make sqlmap 0.7 to work again on Windows too.
|
* Reset takeover OOB features (if any of `--os-pwn`, `--os-smbrelay` or `--os-bof` is selected) when running under Windows because msfconsole and msfcli are not supported on the native Windows Ruby interpreter. This make sqlmap 0.7 to work again on Windows too.
|
||||||
* Minor improvement so that sqlmap tests also all parameters with no value (eg. par=).
|
* Minor improvement so that sqlmap tests also all parameters with no value (eg. par=).
|
||||||
* HTTPS requests over HTTP proxy now work on either Python 2.4, 2.5 and 2.6+.
|
* HTTPS requests over HTTP proxy now work on either Python 2.4, 2.5 and 2.6+.
|
||||||
* Major bug fix to sql-query/sql-shell features.
|
* Major bug fix to sql-query/sql-shell features.
|
||||||
* Major bug fix in --read-file option.
|
* Major bug fix in `--read-file` option.
|
||||||
* Major silent bug fix to multi-threading functionality.
|
* Major silent bug fix to multi-threading functionality.
|
||||||
* Fixed the web backdoor functionality (for MySQL) when (usually) stacked queries are not supported and --os-shell is provided.
|
* Fixed the web backdoor functionality (for MySQL) when (usually) stacked queries are not supported and `--os-shell` is provided.
|
||||||
* Fixed MySQL 'comment injection' version fingerprint.
|
* Fixed MySQL 'comment injection' version fingerprint.
|
||||||
* Fixed basic Microsoft SQL Server 2000 fingerprint.
|
* Fixed basic Microsoft SQL Server 2000 fingerprint.
|
||||||
* Many minor bug fixes and code refactoring.
|
* Many minor bug fixes and code refactoring.
|
||||||
|
@ -136,32 +136,32 @@
|
||||||
* Major enhancement to make the comparison algorithm work properly also on url not stables automatically by using the difflib Sequence Matcher object;
|
* Major enhancement to make the comparison algorithm work properly also on url not stables automatically by using the difflib Sequence Matcher object;
|
||||||
* Major enhancement to support SQL data definition statements, SQL data manipulation statements, etc from user in SQL query and SQL shell if stacked queries are supported by the web application technology;
|
* Major enhancement to support SQL data definition statements, SQL data manipulation statements, etc from user in SQL query and SQL shell if stacked queries are supported by the web application technology;
|
||||||
* Major speed increase in DBMS basic fingerprint;
|
* Major speed increase in DBMS basic fingerprint;
|
||||||
* Minor enhancement to support an option (--is-dba) to show if the current user is a database management system administrator;
|
* Minor enhancement to support an option (`--is-dba`) to show if the current user is a database management system administrator;
|
||||||
* Minor enhancement to support an option (--union-tech) to specify the technique to use to detect the number of columns used in the web application SELECT statement: NULL bruteforcing (default) or ORDER BY clause bruteforcing;
|
* Minor enhancement to support an option (`--union-tech`) to specify the technique to use to detect the number of columns used in the web application SELECT statement: NULL bruteforcing (default) or ORDER BY clause bruteforcing;
|
||||||
* Added internal support to forge CASE statements, used only by --is-dba query at the moment;
|
* Added internal support to forge CASE statements, used only by `--is-dba` query at the moment;
|
||||||
* Minor layout adjustment to the --update output;
|
* Minor layout adjustment to the `--update` output;
|
||||||
* Increased default timeout to 30 seconds;
|
* Increased default timeout to 30 seconds;
|
||||||
* Major bug fix to correctly handle custom SQL "limited" queries on Microsoft SQL Server and Oracle;
|
* Major bug fix to correctly handle custom SQL "limited" queries on Microsoft SQL Server and Oracle;
|
||||||
* Major bug fix to avoid tracebacks when multiple targets are specified and one of them is not reachable;
|
* Major bug fix to avoid tracebacks when multiple targets are specified and one of them is not reachable;
|
||||||
* Minor bug fix to make the Partial UNION query SQL injection technique work properly also on Oracle and Microsoft SQL Server;
|
* Minor bug fix to make the Partial UNION query SQL injection technique work properly also on Oracle and Microsoft SQL Server;
|
||||||
* Minor bug fix to make the --postfix work even if --prefix is not provided;
|
* Minor bug fix to make the `--postfix` work even if `--prefix` is not provided;
|
||||||
* Updated documentation.
|
* Updated documentation.
|
||||||
|
|
||||||
# Version 0.6.3 (2008-12-18)
|
# Version 0.6.3 (2008-12-18)
|
||||||
|
|
||||||
* Major enhancement to get list of targets to test from Burp proxy (http://portswigger.net/suite/) requests log file path or WebScarab proxy (http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project) 'conversations/' folder path by providing option -l <filepath>;
|
* Major enhancement to get list of targets to test from Burp proxy (http://portswigger.net/suite/) requests log file path or WebScarab proxy (http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project) 'conversations/' folder path by providing option -l <filepath>;
|
||||||
* Major enhancement to support Partial UNION query SQL injection technique too;
|
* Major enhancement to support Partial UNION query SQL injection technique too;
|
||||||
* Major enhancement to test if the web application technology supports stacked queries (multiple statements) by providing option --stacked-test which will be then used someday also by takeover functionality;
|
* Major enhancement to test if the web application technology supports stacked queries (multiple statements) by providing option `--stacked-test` which will be then used someday also by takeover functionality;
|
||||||
* Major enhancement to test if the injectable parameter is affected by a time based blind SQL injection technique by providing option --time-test;
|
* Major enhancement to test if the injectable parameter is affected by a time based blind SQL injection technique by providing option `--time-test`;
|
||||||
* Minor enhancement to fingerprint the web server operating system and the web application technology by parsing some HTTP response headers;
|
* Minor enhancement to fingerprint the web server operating system and the web application technology by parsing some HTTP response headers;
|
||||||
* Minor enhancement to fingerprint the back-end DBMS operating system by parsing the DBMS banner value when -b option is provided;
|
* Minor enhancement to fingerprint the back-end DBMS operating system by parsing the DBMS banner value when -b option is provided;
|
||||||
* Minor enhancement to be able to specify the number of seconds before timeout the connection by providing option --timeout #, default is set to 10 seconds and must be 3 or higher;
|
* Minor enhancement to be able to specify the number of seconds before timeout the connection by providing option `--timeout #`, default is set to 10 seconds and must be 3 or higher;
|
||||||
* Minor enhancement to be able to specify the number of seconds to wait between each HTTP request by providing option --delay #;
|
* Minor enhancement to be able to specify the number of seconds to wait between each HTTP request by providing option `--delay #`;
|
||||||
* Minor enhancement to be able to get the injection payload --prefix and --postfix from user;
|
* Minor enhancement to be able to get the injection payload `--prefix` and `--postfix` from user;
|
||||||
* Minor enhancement to be able to enumerate table columns and dump table entries, also when the database name is not provided, by using the current database on MySQL and Microsoft SQL Server, the 'public' scheme on PostgreSQL and the 'USERS' TABLESPACE_NAME on Oracle;
|
* Minor enhancement to be able to enumerate table columns and dump table entries, also when the database name is not provided, by using the current database on MySQL and Microsoft SQL Server, the 'public' scheme on PostgreSQL and the 'USERS' TABLESPACE_NAME on Oracle;
|
||||||
* Minor enhancemet to support also --regexp, --excl-str and --excl-reg options rather than only --string when comparing HTTP responses page content;
|
* Minor enhancemet to support also `--regexp`, `--excl-str` and `--excl-reg` options rather than only `--string` when comparing HTTP responses page content;
|
||||||
* Minor enhancement to be able to specify extra HTTP headers by providing option --headers. By default Accept, Accept-Language and Accept-Charset headers are set;
|
* Minor enhancement to be able to specify extra HTTP headers by providing option `--headers`. By default Accept, Accept-Language and Accept-Charset headers are set;
|
||||||
* Minor improvement to be able to provide CU (as current user) as user value (-U) when enumerating users privileges or users passwords;
|
* Minor improvement to be able to provide CU (as current user) as user value (`-U`) when enumerating users privileges or users passwords;
|
||||||
* Minor improvements to sqlmap Debian package files;
|
* Minor improvements to sqlmap Debian package files;
|
||||||
* Minor improvement to use Python psyco (http://psyco.sourceforge.net/) library if available to speed up the sqlmap algorithmic operations;
|
* Minor improvement to use Python psyco (http://psyco.sourceforge.net/) library if available to speed up the sqlmap algorithmic operations;
|
||||||
* Minor improvement to retry the HTTP request up to three times in case an exception is raised during the connection to the target url;
|
* Minor improvement to retry the HTTP request up to three times in case an exception is raised during the connection to the target url;
|
||||||
|
@ -175,10 +175,10 @@
|
||||||
|
|
||||||
# Version 0.6.2 (2008-11-02)
|
# Version 0.6.2 (2008-11-02)
|
||||||
|
|
||||||
* Major bug fix to correctly dump tables entries when --stop is not specified;
|
* Major bug fix to correctly dump tables entries when `--stop` is not specified;
|
||||||
* Major bug fix so that the users' privileges enumeration now works properly also on both MySQL < 5.0 and MySQL >= 5.0;
|
* Major bug fix so that the users' privileges enumeration now works properly also on both MySQL < 5.0 and MySQL >= 5.0;
|
||||||
* Major bug fix when the request is POST to also send the GET parameters if any have been provided;
|
* Major bug fix when the request is POST to also send the GET parameters if any have been provided;
|
||||||
* Major bug fix to correctly update sqlmap to the latest stable release with command line --update;
|
* Major bug fix to correctly update sqlmap to the latest stable release with command line `--update`;
|
||||||
* Major bug fix so that when the expected value of a query (count variable) is an integer and, for some reasons, its resumed value from the session file is a string or a binary file, the query is executed again and its new output saved to the session file;
|
* Major bug fix so that when the expected value of a query (count variable) is an integer and, for some reasons, its resumed value from the session file is a string or a binary file, the query is executed again and its new output saved to the session file;
|
||||||
* Minor bug fix in MySQL comment injection fingerprint technique;
|
* Minor bug fix in MySQL comment injection fingerprint technique;
|
||||||
* Minor improvement to correctly enumerate tables, columns and dump tables entries on Oracle and on PostgreSQL when the database name is not 'public' schema or a system database;
|
* Minor improvement to correctly enumerate tables, columns and dump tables entries on Oracle and on PostgreSQL when the database name is not 'public' schema or a system database;
|
||||||
|
@ -191,20 +191,20 @@
|
||||||
* Major bug fix to blind SQL injection bisection algorithm to handle an exception;
|
* Major bug fix to blind SQL injection bisection algorithm to handle an exception;
|
||||||
* Added a Metasploit Framework 3 auxiliary module to run sqlmap;
|
* Added a Metasploit Framework 3 auxiliary module to run sqlmap;
|
||||||
* Implemented possibility to test for and inject also on LIKE statements;
|
* Implemented possibility to test for and inject also on LIKE statements;
|
||||||
* Implemented --start and --stop options to set the first and the last table entry to dump;
|
* Implemented `--start` and `--stop` options to set the first and the last table entry to dump;
|
||||||
* Added non-interactive/batch-mode (--batch) option to make it easy to wrap sqlmap in Metasploit and any other tool;
|
* Added non-interactive/batch-mode (`--batch`) option to make it easy to wrap sqlmap in Metasploit and any other tool;
|
||||||
* Minor enhancement to save also the length of query output in the session file when retrieving the query output length for ETA or for resume purposes;
|
* Minor enhancement to save also the length of query output in the session file when retrieving the query output length for ETA or for resume purposes;
|
||||||
* Changed the order sqlmap dump table entries from column by column to row by row. Now it also dumps entries as they are stored in the tables, not forcing the entries' order alphabetically anymore;
|
* Changed the order sqlmap dump table entries from column by column to row by row. Now it also dumps entries as they are stored in the tables, not forcing the entries' order alphabetically anymore;
|
||||||
* Minor bug fix to correctly handle parameters' value with % character.
|
* Minor bug fix to correctly handle parameters' value with `%` character.
|
||||||
|
|
||||||
# Version 0.6 (2008-09-01)
|
# Version 0.6 (2008-09-01)
|
||||||
|
|
||||||
* Complete code refactor and many bugs fixed;
|
* Complete code refactor and many bugs fixed;
|
||||||
* Added multithreading support to set the maximum number of concurrent HTTP requests;
|
* Added multithreading support to set the maximum number of concurrent HTTP requests;
|
||||||
* Implemented SQL shell (--sql-shell) functionality and fixed SQL query (--sql-query, before called -e) to be able to run whatever SELECT statement and get its output in both inband and blind SQL injection attack;
|
* Implemented SQL shell (`--sql-shell`) functionality and fixed SQL query (`--sql-query`, before called `-e`) to be able to run whatever SELECT statement and get its output in both inband and blind SQL injection attack;
|
||||||
* Added an option (--privileges) to retrieve DBMS users privileges, it also notifies if the user is a DBMS administrator;
|
* Added an option (`--privileges`) to retrieve DBMS users privileges, it also notifies if the user is a DBMS administrator;
|
||||||
* Added support (-c) to read options from configuration file, an example of valid INI file is sqlmap.conf and support (--save) to save command line options on a configuration file;
|
* Added support (`-c`) to read options from configuration file, an example of valid INI file is sqlmap.conf and support (`--save`) to save command line options on a configuration file;
|
||||||
* Created a function that updates the whole sqlmap to the latest stable version available by running sqlmap with --update option;
|
* Created a function that updates the whole sqlmap to the latest stable version available by running sqlmap with `--update` option;
|
||||||
* Created sqlmap .deb (Debian, Ubuntu, etc.) and .rpm (Fedora, etc.) installation binary packages;
|
* Created sqlmap .deb (Debian, Ubuntu, etc.) and .rpm (Fedora, etc.) installation binary packages;
|
||||||
* Created sqlmap .exe (Windows) portable executable;
|
* Created sqlmap .exe (Windows) portable executable;
|
||||||
* Save a lot of more information to the session file, useful when resuming injection on the same target to not loose time on identifying injection, UNION fields and back-end DBMS twice or more times;
|
* Save a lot of more information to the session file, useful when resuming injection on the same target to not loose time on identifying injection, UNION fields and back-end DBMS twice or more times;
|
||||||
|
@ -216,8 +216,8 @@
|
||||||
* Improved XML files structure;
|
* Improved XML files structure;
|
||||||
* Implemented the possibility to change the HTTP Referer header;
|
* Implemented the possibility to change the HTTP Referer header;
|
||||||
* Added support to resume from session file also when running with inband SQL injection attack;
|
* Added support to resume from session file also when running with inband SQL injection attack;
|
||||||
* Added an option (--os-shell) to execute operating system commands if the back-end DBMS is MySQL, the web server has the PHP engine active and permits write access on a directory within the document root;
|
* Added an option (`--os-shell`) to execute operating system commands if the back-end DBMS is MySQL, the web server has the PHP engine active and permits write access on a directory within the document root;
|
||||||
* Added a check to assure that the provided string to match (--string) is within the page content;
|
* Added a check to assure that the provided string to match (`--string`) is within the page content;
|
||||||
* Fixed various queries in XML file;
|
* Fixed various queries in XML file;
|
||||||
* Added LIMIT, ORDER BY and COUNT queries to the XML file and adapted the library to parse it;
|
* Added LIMIT, ORDER BY and COUNT queries to the XML file and adapted the library to parse it;
|
||||||
* Fixed password fetching function, mainly for Microsoft SQL Server and reviewed the password hashes parsing function;
|
* Fixed password fetching function, mainly for Microsoft SQL Server and reviewed the password hashes parsing function;
|
||||||
|
@ -225,7 +225,7 @@
|
||||||
* Enhanced logging system: added three more levels of verbosity to show also HTTP sent and received traffic;
|
* Enhanced logging system: added three more levels of verbosity to show also HTTP sent and received traffic;
|
||||||
* Enhancement to handle Set-Cookie from target url and automatically re-establish the Session when it expires;
|
* Enhancement to handle Set-Cookie from target url and automatically re-establish the Session when it expires;
|
||||||
* Added support to inject also on Set-Cookie parameters;
|
* Added support to inject also on Set-Cookie parameters;
|
||||||
* Implemented TAB completion and command history on both --sql-shell and --os-shell;
|
* Implemented TAB completion and command history on both `--sql-shell` and `--os-shell`;
|
||||||
* Renamed some command line options;
|
* Renamed some command line options;
|
||||||
* Added a conversion library;
|
* Added a conversion library;
|
||||||
* Added code schema and reminders for future developments;
|
* Added code schema and reminders for future developments;
|
||||||
|
@ -237,19 +237,19 @@
|
||||||
# Version 0.5 (2007-11-04)
|
# Version 0.5 (2007-11-04)
|
||||||
|
|
||||||
* Added support for Oracle database management system
|
* Added support for Oracle database management system
|
||||||
* Extended inband SQL injection functionality (--union-use) to all other possible queries since it only worked with -e and --file on all DMBS plugins;
|
* Extended inband SQL injection functionality (`--union-use`) to all other possible queries since it only worked with `-e` and `--file` on all DMBS plugins;
|
||||||
* Added support to extract database users password hash on Microsoft SQL Server;
|
* Added support to extract database users password hash on Microsoft SQL Server;
|
||||||
* Added a fuzzer function with the aim to parse HTML page looking for standard database error messages consequently improving database fingerprinting;
|
* Added a fuzzer function with the aim to parse HTML page looking for standard database error messages consequently improving database fingerprinting;
|
||||||
* Added support for SQL injection on HTTP Cookie and User-Agent headers;
|
* Added support for SQL injection on HTTP Cookie and User-Agent headers;
|
||||||
* Reviewed HTTP request library (lib/request.py) to support the extended inband SQL injection functionality. Splitted getValue() into getInband() and getBlind();
|
* Reviewed HTTP request library (lib/request.py) to support the extended inband SQL injection functionality. Splitted getValue() into getInband() and getBlind();
|
||||||
* Major enhancements in common library and added checkForBrackets() method to check if the bracket(s) are needed to perform a UNION query SQL injection attack;
|
* Major enhancements in common library and added checkForBrackets() method to check if the bracket(s) are needed to perform a UNION query SQL injection attack;
|
||||||
* Implemented --dump-all functionality to dump entire DBMS data from all databases tables;
|
* Implemented `--dump-all` functionality to dump entire DBMS data from all databases tables;
|
||||||
* Added support to exclude DBMS system databases' when enumeration tables and dumping their entries (--exclude-sysdbs);
|
* Added support to exclude DBMS system databases' when enumeration tables and dumping their entries (`--exclude-sysdbs`);
|
||||||
* Implemented in Dump.dbTableValues() method the CSV file dumped data automatic saving in csv/ folder by default;
|
* Implemented in Dump.dbTableValues() method the CSV file dumped data automatic saving in csv/ folder by default;
|
||||||
* Added DB2, Informix and Sybase DBMS error messages and minor improvements in xml/errors.xml;
|
* Added DB2, Informix and Sybase DBMS error messages and minor improvements in xml/errors.xml;
|
||||||
* Major improvement in all three DBMS plugins so now sqlmap does not get entire databases' tables structure when all of database/table/ column are specified to be dumped;
|
* Major improvement in all three DBMS plugins so now sqlmap does not get entire databases' tables structure when all of database/table/ column are specified to be dumped;
|
||||||
* Important fixes in lib/option.py to make sqlmap properly work also with python 2.5 and handle the CSV dump files creation work also under Windows operating system, function __setCSVDir() and fixed also in lib/dump.py;
|
* Important fixes in lib/option.py to make sqlmap properly work also with python 2.5 and handle the CSV dump files creation work also under Windows operating system, function __setCSVDir() and fixed also in lib/dump.py;
|
||||||
* Minor enhancement in lib/injection.py to randomize the number requested to test the presence of a SQL injection affected parameter and implemented the possibilities to break (q) the for cycle when using the google dork option (-g);
|
* Minor enhancement in lib/injection.py to randomize the number requested to test the presence of a SQL injection affected parameter and implemented the possibilities to break (q) the for cycle when using the google dork option (`-g`);
|
||||||
* Minor fix in lib/request.py to properly encode the url to request in case the "fixed" part of the url has blank spaces;
|
* Minor fix in lib/request.py to properly encode the url to request in case the "fixed" part of the url has blank spaces;
|
||||||
* More minor layout enhancements in some libraries;
|
* More minor layout enhancements in some libraries;
|
||||||
* Renamed DMBS plugins;
|
* Renamed DMBS plugins;
|
||||||
|
@ -260,18 +260,18 @@
|
||||||
|
|
||||||
* Added DBMS fingerprint based also upon HTML error messages parsing defined in lib/parser.py which reads an XML file defining default error messages for each supported DBMS;
|
* Added DBMS fingerprint based also upon HTML error messages parsing defined in lib/parser.py which reads an XML file defining default error messages for each supported DBMS;
|
||||||
* Added Microsoft SQL Server extensive DBMS fingerprint checks based upon accurate '@@version' parsing matching on an XML file to get also the exact patching level of the DBMS;
|
* Added Microsoft SQL Server extensive DBMS fingerprint checks based upon accurate '@@version' parsing matching on an XML file to get also the exact patching level of the DBMS;
|
||||||
* Added support for query ETA (Estimated Time of Arrival) real time calculation (--eta);
|
* Added support for query ETA (Estimated Time of Arrival) real time calculation (`--eta`);
|
||||||
* Added support to extract database management system users password hash on MySQL and PostgreSQL (--passwords);
|
* Added support to extract database management system users password hash on MySQL and PostgreSQL (`--passwords`);
|
||||||
* Added docstrings to all functions, classes and methods, consequently released the sqlmap development documentation <http://sqlmap.org/dev/>;
|
* Added docstrings to all functions, classes and methods, consequently released the sqlmap development documentation <http://sqlmap.org/dev/>;
|
||||||
* Implemented Google dorking feature (-g) to take advantage of Google results affected by SQL injection to perform other command line argument on their DBMS;
|
* Implemented Google dorking feature (`-g`) to take advantage of Google results affected by SQL injection to perform other command line argument on their DBMS;
|
||||||
* Improved logging functionality: passed from banal 'print' to Python native logging library;
|
* Improved logging functionality: passed from banal 'print' to Python native logging library;
|
||||||
* Added support for more than one parameter in '-p' command line option;
|
* Added support for more than one parameter in `-p` command line option;
|
||||||
* Added support for HTTP Basic and Digest authentication methods (--basic-auth and --digest-auth);
|
* Added support for HTTP Basic and Digest authentication methods (`--basic-auth` and `--digest-auth`);
|
||||||
* Added the command line option '--remote-dbms' to manually specify the remote DBMS;
|
* Added the command line option `--remote-dbms` to manually specify the remote DBMS;
|
||||||
* Major improvements in union.UnionCheck() and union.UnionUse() functions to make it possible to exploit inband SQL injection also with database comment characters ('--' and '#') in UNION query statements;
|
* Major improvements in union.UnionCheck() and union.UnionUse() functions to make it possible to exploit inband SQL injection also with database comment characters (`--` and `#`) in UNION query statements;
|
||||||
* Added the possibility to save the output into a file while performing the queries (-o OUTPUTFILE) so it is possible to stop and resume the same query output retrieving in a second time (--resume);
|
* Added the possibility to save the output into a file while performing the queries (`-o OUTPUTFILE`) so it is possible to stop and resume the same query output retrieving in a second time (`--resume`);
|
||||||
* Added support to specify the database table column to enumerate (-C COL);
|
* Added support to specify the database table column to enumerate (`-C COL`);
|
||||||
* Added inband SQL injection (UNION query) support (--union-use);
|
* Added inband SQL injection (UNION query) support (`--union-use`);
|
||||||
* Complete code refactoring, a lot of minor and some major fixes in libraries, many minor improvements;
|
* Complete code refactoring, a lot of minor and some major fixes in libraries, many minor improvements;
|
||||||
* Reviewed the directory tree structure;
|
* Reviewed the directory tree structure;
|
||||||
* Splitted lib/common.py: inband injection functionalities now are moved to lib/union.py;
|
* Splitted lib/common.py: inband injection functionalities now are moved to lib/union.py;
|
||||||
|
@ -282,10 +282,10 @@
|
||||||
* Added module for MS SQL Server;
|
* Added module for MS SQL Server;
|
||||||
* Strongly improved MySQL dbms active fingerprint and added MySQL comment injection check;
|
* Strongly improved MySQL dbms active fingerprint and added MySQL comment injection check;
|
||||||
* Added PostgreSQL dbms active fingerprint;
|
* Added PostgreSQL dbms active fingerprint;
|
||||||
* Added support for string match (--string);
|
* Added support for string match (`--string`);
|
||||||
* Added support for UNION check (--union-check);
|
* Added support for UNION check (`--union-check`);
|
||||||
* Removed duplicated code, delegated most of features to the engine in common.py and option.py;
|
* Removed duplicated code, delegated most of features to the engine in common.py and option.py;
|
||||||
* Added support for --data command line argument to pass the string for POST requests;
|
* Added support for `--data` command line argument to pass the string for POST requests;
|
||||||
* Added encodeParams() method to encode url parameters before making http request;
|
* Added encodeParams() method to encode url parameters before making http request;
|
||||||
* Many bug fixes;
|
* Many bug fixes;
|
||||||
* Rewritten documentation files;
|
* Rewritten documentation files;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
COPYING -- Describes the terms under which sqlmap is distributed. A copy
|
COPYING -- Describes the terms under which sqlmap is distributed. A copy
|
||||||
of the GNU General Public License (GPL) is appended to this file.
|
of the GNU General Public License (GPL) is appended to this file.
|
||||||
|
|
||||||
sqlmap is (C) 2006-2015 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
|
sqlmap is (C) 2006-2016 Bernardo Damele Assumpcao Guimaraes, Miroslav Stampar.
|
||||||
|
|
||||||
This program is free software; you may redistribute and/or modify it under
|
This program is free software; you may redistribute and/or modify it under
|
||||||
the terms of the GNU General Public License as published by the Free
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"""
|
"""
|
||||||
beep.py - Make a beep sound
|
beep.py - Make a beep sound
|
||||||
|
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"""
|
"""
|
||||||
cloak.py - Simple file encryption/compression utility
|
cloak.py - Simple file encryption/compression utility
|
||||||
|
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"""
|
"""
|
||||||
dbgtool.py - Portable executable to ASCII debug script converter
|
dbgtool.py - Portable executable to ASCII debug script converter
|
||||||
|
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
"""
|
"""
|
||||||
safe2bin.py - Simple safe(hex) to binary format converter
|
safe2bin.py - Simple safe(hex) to binary format converter
|
||||||
|
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'doc/COPYING' for copying permission
|
# See the file 'doc/COPYING' for copying permission
|
||||||
|
|
||||||
# Removes duplicate entries in wordlist like files
|
# Removes duplicate entries in wordlist like files
|
||||||
|
|
0
extra/shutils/pyflakes.sh
Normal file → Executable file
0
extra/shutils/pyflakes.sh
Normal file → Executable file
2
extra/shutils/regressiontest.py
Executable file → Normal file
2
extra/shutils/regressiontest.py
Executable file → Normal file
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
# Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
# See the file 'doc/COPYING' for copying permission
|
# See the file 'doc/COPYING' for copying permission
|
||||||
|
|
||||||
import codecs
|
import codecs
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ from lib.core.common import getPublicTypeMembers
|
||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
from lib.core.common import getSortedInjectionTests
|
from lib.core.common import getSortedInjectionTests
|
||||||
from lib.core.common import getUnicode
|
from lib.core.common import getUnicode
|
||||||
|
from lib.core.common import hashDBRetrieve
|
||||||
|
from lib.core.common import hashDBWrite
|
||||||
from lib.core.common import intersect
|
from lib.core.common import intersect
|
||||||
from lib.core.common import listToStrValue
|
from lib.core.common import listToStrValue
|
||||||
from lib.core.common import parseFilePaths
|
from lib.core.common import parseFilePaths
|
||||||
|
@ -48,6 +50,7 @@ from lib.core.datatype import InjectionDict
|
||||||
from lib.core.decorators import cachedmethod
|
from lib.core.decorators import cachedmethod
|
||||||
from lib.core.dicts import FROM_DUMMY_TABLE
|
from lib.core.dicts import FROM_DUMMY_TABLE
|
||||||
from lib.core.enums import DBMS
|
from lib.core.enums import DBMS
|
||||||
|
from lib.core.enums import HASHDB_KEYS
|
||||||
from lib.core.enums import HEURISTIC_TEST
|
from lib.core.enums import HEURISTIC_TEST
|
||||||
from lib.core.enums import HTTP_HEADER
|
from lib.core.enums import HTTP_HEADER
|
||||||
from lib.core.enums import HTTPMETHOD
|
from lib.core.enums import HTTPMETHOD
|
||||||
|
@ -59,17 +62,19 @@ from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.exception import SqlmapSilentQuitException
|
from lib.core.exception import SqlmapSilentQuitException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
|
from lib.core.settings import CLOUDFLARE_SERVER_HEADER
|
||||||
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
||||||
from lib.core.settings import DUMMY_XSS_CHECK_APPENDIX
|
from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX
|
||||||
from lib.core.settings import FORMAT_EXCEPTION_STRINGS
|
from lib.core.settings import FORMAT_EXCEPTION_STRINGS
|
||||||
from lib.core.settings import HEURISTIC_CHECK_ALPHABET
|
from lib.core.settings import HEURISTIC_CHECK_ALPHABET
|
||||||
|
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
|
||||||
|
from lib.core.settings import IDS_WAF_CHECK_RATIO
|
||||||
|
from lib.core.settings import IDS_WAF_CHECK_TIMEOUT
|
||||||
|
from lib.core.settings import NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH
|
||||||
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
|
from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH
|
||||||
from lib.core.settings import SUPPORTED_DBMS
|
from lib.core.settings import SUPPORTED_DBMS
|
||||||
from lib.core.settings import URI_HTTP_HEADER
|
from lib.core.settings import URI_HTTP_HEADER
|
||||||
from lib.core.settings import UPPER_RATIO_BOUND
|
from lib.core.settings import UPPER_RATIO_BOUND
|
||||||
from lib.core.settings import IDS_WAF_CHECK_PAYLOAD
|
|
||||||
from lib.core.settings import IDS_WAF_CHECK_RATIO
|
|
||||||
from lib.core.settings import IDS_WAF_CHECK_TIMEOUT
|
|
||||||
from lib.core.threads import getCurrentThreadData
|
from lib.core.threads import getCurrentThreadData
|
||||||
from lib.request.connect import Connect as Request
|
from lib.request.connect import Connect as Request
|
||||||
from lib.request.inject import checkBooleanExpression
|
from lib.request.inject import checkBooleanExpression
|
||||||
|
@ -105,7 +110,7 @@ def checkSqlInjection(place, parameter, value):
|
||||||
# then attempt to identify with a simple DBMS specific boolean-based
|
# then attempt to identify with a simple DBMS specific boolean-based
|
||||||
# test what the DBMS may be
|
# test what the DBMS may be
|
||||||
if not injection.dbms and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data:
|
if not injection.dbms and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data:
|
||||||
if not Backend.getIdentifiedDbms() and kb.heuristicDbms is False:
|
if not Backend.getIdentifiedDbms() and kb.heuristicDbms is None:
|
||||||
kb.heuristicDbms = heuristicCheckDbms(injection)
|
kb.heuristicDbms = heuristicCheckDbms(injection)
|
||||||
|
|
||||||
# If the DBMS has already been fingerprinted (via DBMS-specific
|
# If the DBMS has already been fingerprinted (via DBMS-specific
|
||||||
|
@ -443,10 +448,19 @@ def checkSqlInjection(place, parameter, value):
|
||||||
truePage = threadData.lastComparisonPage or ""
|
truePage = threadData.lastComparisonPage or ""
|
||||||
|
|
||||||
if trueResult and not(truePage == falsePage and not kb.nullConnection):
|
if trueResult and not(truePage == falsePage and not kb.nullConnection):
|
||||||
|
# Perform the test's False request
|
||||||
falseResult = Request.queryPage(genCmpPayload(), place, raise404=False)
|
falseResult = Request.queryPage(genCmpPayload(), place, raise404=False)
|
||||||
|
|
||||||
# Perform the test's False request
|
|
||||||
if not falseResult:
|
if not falseResult:
|
||||||
|
if kb.negativeLogic:
|
||||||
|
boundPayload = agent.prefixQuery(kb.data.randomStr, prefix, where, clause)
|
||||||
|
boundPayload = agent.suffixQuery(boundPayload, comment, suffix, where)
|
||||||
|
errorPayload = agent.payload(place, parameter, newValue=boundPayload, where=where)
|
||||||
|
|
||||||
|
errorResult = Request.queryPage(errorPayload, place, raise404=False)
|
||||||
|
if errorResult:
|
||||||
|
continue
|
||||||
|
|
||||||
infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (paramType, parameter, title)
|
infoMsg = "%s parameter '%s' seems to be '%s' injectable " % (paramType, parameter, title)
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
@ -708,12 +722,12 @@ def heuristicCheckDbms(injection):
|
||||||
kb.injection = injection
|
kb.injection = injection
|
||||||
|
|
||||||
for dbms in getPublicTypeMembers(DBMS, True):
|
for dbms in getPublicTypeMembers(DBMS, True):
|
||||||
if not FROM_DUMMY_TABLE.get(dbms, ""):
|
|
||||||
continue
|
|
||||||
|
|
||||||
randStr1, randStr2 = randomStr(), randomStr()
|
randStr1, randStr2 = randomStr(), randomStr()
|
||||||
Backend.forceDbms(dbms)
|
Backend.forceDbms(dbms)
|
||||||
|
|
||||||
|
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 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 not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)):
|
||||||
retVal = dbms
|
retVal = dbms
|
||||||
|
@ -767,15 +781,19 @@ def checkFalsePositives(injection):
|
||||||
if PAYLOAD.TECHNIQUE.BOOLEAN not in injection.data:
|
if PAYLOAD.TECHNIQUE.BOOLEAN not in injection.data:
|
||||||
checkBooleanExpression("%d=%d" % (randInt1, randInt2))
|
checkBooleanExpression("%d=%d" % (randInt1, randInt2))
|
||||||
|
|
||||||
if checkBooleanExpression("%d=%d" % (randInt1, randInt3)):
|
if checkBooleanExpression("%d=%d" % (randInt1, randInt3)): # this must not be evaluated to True
|
||||||
retVal = None
|
retVal = None
|
||||||
break
|
break
|
||||||
|
|
||||||
elif checkBooleanExpression("%d=%d" % (randInt3, randInt2)):
|
elif checkBooleanExpression("%d=%d" % (randInt3, randInt2)): # this must not be evaluated to True
|
||||||
retVal = None
|
retVal = None
|
||||||
break
|
break
|
||||||
|
|
||||||
elif not checkBooleanExpression("%d=%d" % (randInt2, randInt2)):
|
elif not checkBooleanExpression("%d=%d" % (randInt2, randInt2)): # this must be evaluated to True
|
||||||
|
retVal = None
|
||||||
|
break
|
||||||
|
|
||||||
|
elif checkBooleanExpression("%d %d" % (randInt3, randInt2)): # this must not be evaluated to True (invalid statement)
|
||||||
retVal = None
|
retVal = None
|
||||||
break
|
break
|
||||||
|
|
||||||
|
@ -916,18 +934,26 @@ def heuristicCheckSqlInjection(place, parameter):
|
||||||
|
|
||||||
kb.heuristicMode = True
|
kb.heuristicMode = True
|
||||||
|
|
||||||
value = "%s%s%s" % (randomStr(), DUMMY_XSS_CHECK_APPENDIX, randomStr())
|
randStr1, randStr2 = randomStr(NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH), randomStr(NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH)
|
||||||
|
value = "%s%s%s" % (randStr1, DUMMY_NON_SQLI_CHECK_APPENDIX, randStr2)
|
||||||
payload = "%s%s%s" % (prefix, "'%s" % value, suffix)
|
payload = "%s%s%s" % (prefix, "'%s" % value, suffix)
|
||||||
payload = agent.payload(place, parameter, newValue=payload)
|
payload = agent.payload(place, parameter, newValue=payload)
|
||||||
page, _ = Request.queryPage(payload, place, content=True, raise404=False)
|
page, _ = Request.queryPage(payload, place, content=True, raise404=False)
|
||||||
|
|
||||||
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
|
paramType = conf.method if conf.method not in (None, HTTPMETHOD.GET, HTTPMETHOD.POST) else place
|
||||||
|
|
||||||
if value in (page or ""):
|
if value.lower() in (page or "").lower():
|
||||||
infoMsg = "heuristic (XSS) test shows that %s parameter " % paramType
|
infoMsg = "heuristic (XSS) test shows that %s parameter " % paramType
|
||||||
infoMsg += "'%s' might be vulnerable to XSS attacks" % parameter
|
infoMsg += "'%s' might be vulnerable to cross-site scripting attacks" % parameter
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
for match in re.finditer("(?i)[^\n]*(no such file|failed (to )?open)[^\n]*", page or ""):
|
||||||
|
if randStr1.lower() in match.group(0).lower():
|
||||||
|
infoMsg = "heuristic (FI) test shows that %s parameter " % paramType
|
||||||
|
infoMsg += "'%s' might be vulnerable to file inclusion attacks" % parameter
|
||||||
|
logger.info(infoMsg)
|
||||||
|
break
|
||||||
|
|
||||||
kb.heuristicMode = False
|
kb.heuristicMode = False
|
||||||
|
|
||||||
return kb.heuristicTest
|
return kb.heuristicTest
|
||||||
|
@ -1155,6 +1181,14 @@ def checkWaf():
|
||||||
if any((conf.string, conf.notString, conf.regexp, conf.dummy, conf.offline, conf.skipWaf)):
|
if any((conf.string, conf.notString, conf.regexp, conf.dummy, conf.offline, conf.skipWaf)):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
_ = hashDBRetrieve(HASHDB_KEYS.CHECK_WAF_RESULT, True)
|
||||||
|
if _ is not None:
|
||||||
|
if _:
|
||||||
|
warnMsg = "previous heuristics detected that the target "
|
||||||
|
warnMsg += "is protected by some kind of WAF/IPS/IDS"
|
||||||
|
logger.critical(warnMsg)
|
||||||
|
return _
|
||||||
|
|
||||||
infoMsg = "checking if the target is protected by "
|
infoMsg = "checking if the target is protected by "
|
||||||
infoMsg += "some kind of WAF/IPS/IDS"
|
infoMsg += "some kind of WAF/IPS/IDS"
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
@ -1193,6 +1227,8 @@ def checkWaf():
|
||||||
logger.warning("dropping timeout to %d seconds (i.e. '--timeout=%d')" % (IDS_WAF_CHECK_TIMEOUT, IDS_WAF_CHECK_TIMEOUT))
|
logger.warning("dropping timeout to %d seconds (i.e. '--timeout=%d')" % (IDS_WAF_CHECK_TIMEOUT, IDS_WAF_CHECK_TIMEOUT))
|
||||||
conf.timeout = IDS_WAF_CHECK_TIMEOUT
|
conf.timeout = IDS_WAF_CHECK_TIMEOUT
|
||||||
|
|
||||||
|
hashDBWrite(HASHDB_KEYS.CHECK_WAF_RESULT, retVal, True)
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def identifyWaf():
|
def identifyWaf():
|
||||||
|
@ -1230,7 +1266,7 @@ def identifyWaf():
|
||||||
found = function(_)
|
found = function(_)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "exception occurred while running "
|
errMsg = "exception occurred while running "
|
||||||
errMsg += "WAF script for '%s' ('%s')" % (product, ex)
|
errMsg += "WAF script for '%s' ('%s')" % (product, getSafeExString(ex))
|
||||||
logger.critical(errMsg)
|
logger.critical(errMsg)
|
||||||
|
|
||||||
found = False
|
found = False
|
||||||
|
@ -1251,7 +1287,7 @@ def identifyWaf():
|
||||||
if output and output[0] not in ("Y", "y"):
|
if output and output[0] not in ("Y", "y"):
|
||||||
raise SqlmapUserQuitException
|
raise SqlmapUserQuitException
|
||||||
else:
|
else:
|
||||||
warnMsg = "no WAF/IDS/IPS product has been identified"
|
warnMsg = "no WAF/IDS/IPS product has been identified (this doesn't mean that there is none)"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
kb.testType = None
|
kb.testType = None
|
||||||
|
@ -1328,7 +1364,7 @@ def checkConnection(suppressOutput=False):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
kb.originalPageTime = time.time()
|
kb.originalPageTime = time.time()
|
||||||
page, _ = Request.queryPage(content=True, noteResponseTime=False)
|
page, headers = Request.queryPage(content=True, noteResponseTime=False)
|
||||||
kb.originalPage = kb.pageTemplate = page
|
kb.originalPage = kb.pageTemplate = page
|
||||||
|
|
||||||
kb.errorIsNone = False
|
kb.errorIsNone = False
|
||||||
|
@ -1347,6 +1383,10 @@ def checkConnection(suppressOutput=False):
|
||||||
else:
|
else:
|
||||||
kb.errorIsNone = True
|
kb.errorIsNone = True
|
||||||
|
|
||||||
|
if headers and headers.get("Server", "") == CLOUDFLARE_SERVER_HEADER:
|
||||||
|
warnMsg = "CloudFlare response detected"
|
||||||
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
except SqlmapConnectionException, ex:
|
except SqlmapConnectionException, ex:
|
||||||
if conf.ipv6:
|
if conf.ipv6:
|
||||||
warnMsg = "check connection to a provided "
|
warnMsg = "check connection to a provided "
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ class Agent(object):
|
||||||
origValue = origValue.split(' ')[-1].split(':')[-1]
|
origValue = origValue.split(' ')[-1].split(':')[-1]
|
||||||
|
|
||||||
if value is None:
|
if value is None:
|
||||||
if where == PAYLOAD.WHERE.ORIGINAL or conf.prefix:
|
if where == PAYLOAD.WHERE.ORIGINAL:
|
||||||
value = origValue
|
value = origValue
|
||||||
elif where == PAYLOAD.WHERE.NEGATIVE:
|
elif where == PAYLOAD.WHERE.NEGATIVE:
|
||||||
if conf.invalidLogical:
|
if conf.invalidLogical:
|
||||||
|
@ -228,7 +228,7 @@ class Agent(object):
|
||||||
|
|
||||||
# If we are replacing (<where>) the parameter original value with
|
# If we are replacing (<where>) the parameter original value with
|
||||||
# our payload do not prepend with the prefix
|
# our payload do not prepend with the prefix
|
||||||
if where == PAYLOAD.WHERE.REPLACE and not conf.prefix:
|
if where == PAYLOAD.WHERE.REPLACE:
|
||||||
query = ""
|
query = ""
|
||||||
|
|
||||||
# If the technique is stacked queries (<stype>) do not put a space
|
# If the technique is stacked queries (<stype>) do not put a space
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
23
lib/core/common.py
Executable file → Normal file
23
lib/core/common.py
Executable file → Normal file
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -853,7 +853,7 @@ def dataToTrafficFile(data):
|
||||||
conf.trafficFP.flush()
|
conf.trafficFP.flush()
|
||||||
except IOError, ex:
|
except IOError, ex:
|
||||||
errMsg = "something went wrong while trying "
|
errMsg = "something went wrong while trying "
|
||||||
errMsg += "to write to the traffic file '%s' ('%s')" % (conf.trafficFile, ex)
|
errMsg += "to write to the traffic file '%s' ('%s')" % (conf.trafficFile, getSafeExString(ex))
|
||||||
raise SqlmapSystemException(errMsg)
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
def dataToDumpFile(dumpFile, data):
|
def dataToDumpFile(dumpFile, data):
|
||||||
|
@ -916,8 +916,7 @@ def readInput(message, default=None, checkBatch=True):
|
||||||
retVal = "%s,%s" % (retVal, getUnicode(item, UNICODE_ENCODING))
|
retVal = "%s,%s" % (retVal, getUnicode(item, UNICODE_ENCODING))
|
||||||
|
|
||||||
if retVal:
|
if retVal:
|
||||||
infoMsg = "%s%s" % (message, retVal)
|
dataToStdout("\r%s%s\n" % (message, retVal), forceOutput=True, bold=True)
|
||||||
logger.info(infoMsg)
|
|
||||||
|
|
||||||
debugMsg = "used the given answer"
|
debugMsg = "used the given answer"
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
@ -1276,7 +1275,7 @@ def parseTargetUrl():
|
||||||
try:
|
try:
|
||||||
urlSplit = urlparse.urlsplit(conf.url)
|
urlSplit = urlparse.urlsplit(conf.url)
|
||||||
except ValueError, ex:
|
except ValueError, ex:
|
||||||
errMsg = "invalid URL '%s' has been given ('%s'). " % (conf.url, ex)
|
errMsg = "invalid URL '%s' has been given ('%s'). " % (conf.url, getSafeExString(ex))
|
||||||
errMsg += "Please be sure that you don't have any leftover characters (e.g. '[' or ']') "
|
errMsg += "Please be sure that you don't have any leftover characters (e.g. '[' or ']') "
|
||||||
errMsg += "in the hostname part"
|
errMsg += "in the hostname part"
|
||||||
raise SqlmapGenericException(errMsg)
|
raise SqlmapGenericException(errMsg)
|
||||||
|
@ -1824,7 +1823,7 @@ def parseXmlFile(xmlFile, handler):
|
||||||
parse(stream, handler)
|
parse(stream, handler)
|
||||||
except (SAXParseException, UnicodeError), ex:
|
except (SAXParseException, UnicodeError), ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something seems to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (xmlFile, ex)
|
errMsg += "the file '%s' ('%s'). Please make " % (xmlFile, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
|
|
||||||
|
@ -1885,7 +1884,7 @@ def readCachedFileContent(filename, mode='rb'):
|
||||||
kb.cache.content[filename] = f.read()
|
kb.cache.content[filename] = f.read()
|
||||||
except (IOError, OSError, MemoryError), ex:
|
except (IOError, OSError, MemoryError), ex:
|
||||||
errMsg = "something went wrong while trying "
|
errMsg = "something went wrong while trying "
|
||||||
errMsg += "to read the content of file '%s' ('%s')" % (filename, ex)
|
errMsg += "to read the content of file '%s' ('%s')" % (filename, getSafeExString(ex))
|
||||||
raise SqlmapSystemException(errMsg)
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
return kb.cache.content[filename]
|
return kb.cache.content[filename]
|
||||||
|
@ -2004,7 +2003,7 @@ def getFileItems(filename, commentPrefix='#', unicode_=True, lowercase=False, un
|
||||||
retVal.append(line)
|
retVal.append(line)
|
||||||
except (IOError, OSError, MemoryError), ex:
|
except (IOError, OSError, MemoryError), ex:
|
||||||
errMsg = "something went wrong while trying "
|
errMsg = "something went wrong while trying "
|
||||||
errMsg += "to read the content of file '%s' ('%s')" % (filename, ex)
|
errMsg += "to read the content of file '%s' ('%s')" % (filename, getSafeExString(ex))
|
||||||
raise SqlmapSystemException(errMsg)
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
return retVal if not unique else retVal.keys()
|
return retVal if not unique else retVal.keys()
|
||||||
|
@ -2222,16 +2221,16 @@ def wasLastResponseDelayed():
|
||||||
# response times should be inside +-7*stdev([normal response times])
|
# response times should be inside +-7*stdev([normal response times])
|
||||||
# Math reference: http://www.answers.com/topic/standard-deviation
|
# Math reference: http://www.answers.com/topic/standard-deviation
|
||||||
|
|
||||||
deviation = stdev(kb.responseTimes)
|
deviation = stdev(kb.responseTimes.get(kb.responseTimeMode, []))
|
||||||
threadData = getCurrentThreadData()
|
threadData = getCurrentThreadData()
|
||||||
|
|
||||||
if deviation and not conf.direct:
|
if deviation and not conf.direct:
|
||||||
if len(kb.responseTimes) < MIN_TIME_RESPONSES:
|
if len(kb.responseTimes[kb.responseTimeMode]) < MIN_TIME_RESPONSES:
|
||||||
warnMsg = "time-based standard deviation method used on a model "
|
warnMsg = "time-based standard deviation method used on a model "
|
||||||
warnMsg += "with less than %d response times" % MIN_TIME_RESPONSES
|
warnMsg += "with less than %d response times" % MIN_TIME_RESPONSES
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
lowerStdLimit = average(kb.responseTimes) + TIME_STDEV_COEFF * deviation
|
lowerStdLimit = average(kb.responseTimes[kb.responseTimeMode]) + TIME_STDEV_COEFF * deviation
|
||||||
retVal = (threadData.lastQueryDuration >= max(MIN_VALID_DELAYED_RESPONSE, lowerStdLimit))
|
retVal = (threadData.lastQueryDuration >= max(MIN_VALID_DELAYED_RESPONSE, lowerStdLimit))
|
||||||
|
|
||||||
if not kb.testMode and retVal:
|
if not kb.testMode and retVal:
|
||||||
|
@ -3852,7 +3851,7 @@ def hashDBRetrieve(key, unserialize=False, checkConf=False):
|
||||||
|
|
||||||
_ = "%s%s%s" % (conf.url or "%s%s" % (conf.hostname, conf.port), key, HASHDB_MILESTONE_VALUE)
|
_ = "%s%s%s" % (conf.url or "%s%s" % (conf.hostname, conf.port), key, HASHDB_MILESTONE_VALUE)
|
||||||
retVal = conf.hashDB.retrieve(_, unserialize) if kb.resumeValues and not (checkConf and any((conf.flushSession, conf.freshQueries))) else None
|
retVal = conf.hashDB.retrieve(_, unserialize) if kb.resumeValues and not (checkConf and any((conf.flushSession, conf.freshQueries))) else None
|
||||||
if not kb.inferenceMode and not kb.fileReadMode and any(_ in (retVal or "") for _ in (PARTIAL_VALUE_MARKER, PARTIAL_HEX_VALUE_MARKER)):
|
if not kb.inferenceMode and not kb.fileReadMode and isinstance(retVal, basestring) and any(_ in retVal for _ in (PARTIAL_VALUE_MARKER, PARTIAL_HEX_VALUE_MARKER)):
|
||||||
retVal = None
|
retVal = None
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
import pickle
|
import pickle
|
||||||
|
import re
|
||||||
import StringIO
|
import StringIO
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
@ -159,6 +160,10 @@ def htmlunescape(value):
|
||||||
if value and isinstance(value, basestring):
|
if value and isinstance(value, basestring):
|
||||||
codes = (('<', '<'), ('>', '>'), ('"', '"'), (' ', ' '), ('&', '&'))
|
codes = (('<', '<'), ('>', '>'), ('"', '"'), (' ', ' '), ('&', '&'))
|
||||||
retVal = reduce(lambda x, y: x.replace(y[0], y[1]), codes, retVal)
|
retVal = reduce(lambda x, y: x.replace(y[0], y[1]), codes, retVal)
|
||||||
|
try:
|
||||||
|
retVal = re.sub(r"&#x([^;]+);", lambda match: unichr(int(match.group(1), 16)), retVal)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def singleTimeWarnMessage(message): # Cross-linked function
|
def singleTimeWarnMessage(message): # Cross-linked function
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -23,51 +23,51 @@ from lib.core.settings import DB2_ALIASES
|
||||||
from lib.core.settings import HSQLDB_ALIASES
|
from lib.core.settings import HSQLDB_ALIASES
|
||||||
|
|
||||||
FIREBIRD_TYPES = {
|
FIREBIRD_TYPES = {
|
||||||
"261": "BLOB",
|
261: "BLOB",
|
||||||
"14": "CHAR",
|
14: "CHAR",
|
||||||
"40": "CSTRING",
|
40: "CSTRING",
|
||||||
"11": "D_FLOAT",
|
11: "D_FLOAT",
|
||||||
"27": "DOUBLE",
|
27: "DOUBLE",
|
||||||
"10": "FLOAT",
|
10: "FLOAT",
|
||||||
"16": "INT64",
|
16: "INT64",
|
||||||
"8": "INTEGER",
|
8: "INTEGER",
|
||||||
"9": "QUAD",
|
9: "QUAD",
|
||||||
"7": "SMALLINT",
|
7: "SMALLINT",
|
||||||
"12": "DATE",
|
12: "DATE",
|
||||||
"13": "TIME",
|
13: "TIME",
|
||||||
"35": "TIMESTAMP",
|
35: "TIMESTAMP",
|
||||||
"37": "VARCHAR",
|
37: "VARCHAR",
|
||||||
}
|
}
|
||||||
|
|
||||||
SYBASE_TYPES = {
|
SYBASE_TYPES = {
|
||||||
"14": "floatn",
|
14: "floatn",
|
||||||
"8": "float",
|
8: "float",
|
||||||
"15": "datetimn",
|
15: "datetimn",
|
||||||
"12": "datetime",
|
12: "datetime",
|
||||||
"23": "real",
|
23: "real",
|
||||||
"28": "numericn",
|
28: "numericn",
|
||||||
"10": "numeric",
|
10: "numeric",
|
||||||
"27": "decimaln",
|
27: "decimaln",
|
||||||
"26": "decimal",
|
26: "decimal",
|
||||||
"17": "moneyn",
|
17: "moneyn",
|
||||||
"11": "money",
|
11: "money",
|
||||||
"21": "smallmoney",
|
21: "smallmoney",
|
||||||
"22": "smalldatetime",
|
22: "smalldatetime",
|
||||||
"13": "intn",
|
13: "intn",
|
||||||
"7": "int",
|
7: "int",
|
||||||
"6": "smallint",
|
6: "smallint",
|
||||||
"5": "tinyint",
|
5: "tinyint",
|
||||||
"16": "bit",
|
16: "bit",
|
||||||
"2": "varchar",
|
2: "varchar",
|
||||||
"18": "sysname",
|
18: "sysname",
|
||||||
"25": "nvarchar",
|
25: "nvarchar",
|
||||||
"1": "char",
|
1: "char",
|
||||||
"24": "nchar",
|
24: "nchar",
|
||||||
"4": "varbinary",
|
4: "varbinary",
|
||||||
"80": "timestamp",
|
80: "timestamp",
|
||||||
"3": "binary",
|
3: "binary",
|
||||||
"19": "text",
|
19: "text",
|
||||||
"20": "image",
|
20: "image",
|
||||||
}
|
}
|
||||||
|
|
||||||
MYSQL_PRIVS = {
|
MYSQL_PRIVS = {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -398,13 +398,7 @@ class Dump(object):
|
||||||
self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)
|
self._write(tableValues, content_type=CONTENT_TYPE.DUMP_TABLE)
|
||||||
return
|
return
|
||||||
|
|
||||||
_ = re.sub(r"[^\w]", "_", normalizeUnicode(unsafeSQLIdentificatorNaming(db)))
|
dumpDbPath = os.path.join(conf.dumpPath, unsafeSQLIdentificatorNaming(db))
|
||||||
if len(_) < len(db) or IS_WIN and db.upper() in WINDOWS_RESERVED_NAMES:
|
|
||||||
_ = unicodeencode(re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(db)))
|
|
||||||
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(unicodeencode(db)).hexdigest()[:8]))
|
|
||||||
warnFile = True
|
|
||||||
else:
|
|
||||||
dumpDbPath = os.path.join(conf.dumpPath, _)
|
|
||||||
|
|
||||||
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
|
if conf.dumpFormat == DUMP_FORMAT.SQLITE:
|
||||||
replication = Replication(os.path.join(conf.dumpPath, "%s.sqlite3" % unsafeSQLIdentificatorNaming(db)))
|
replication = Replication(os.path.join(conf.dumpPath, "%s.sqlite3" % unsafeSQLIdentificatorNaming(db)))
|
||||||
|
@ -412,7 +406,16 @@ class Dump(object):
|
||||||
if not os.path.isdir(dumpDbPath):
|
if not os.path.isdir(dumpDbPath):
|
||||||
try:
|
try:
|
||||||
os.makedirs(dumpDbPath, 0755)
|
os.makedirs(dumpDbPath, 0755)
|
||||||
except (OSError, IOError), ex:
|
except:
|
||||||
|
warnFile = True
|
||||||
|
|
||||||
|
_ = unicodeencode(re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(db)))
|
||||||
|
dumpDbPath = os.path.join(conf.dumpPath, "%s-%s" % (_, hashlib.md5(unicodeencode(db)).hexdigest()[:8]))
|
||||||
|
|
||||||
|
if not os.path.isdir(dumpDbPath):
|
||||||
|
try:
|
||||||
|
os.makedirs(dumpDbPath, 0755)
|
||||||
|
except Exception, ex:
|
||||||
try:
|
try:
|
||||||
tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
|
tempDir = tempfile.mkdtemp(prefix="sqlmapdb")
|
||||||
except IOError, _:
|
except IOError, _:
|
||||||
|
@ -423,17 +426,25 @@ class Dump(object):
|
||||||
raise SqlmapSystemException(errMsg)
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
warnMsg = "unable to create dump directory "
|
warnMsg = "unable to create dump directory "
|
||||||
warnMsg += "'%s' (%s). " % (dumpDbPath, ex)
|
warnMsg += "'%s' (%s). " % (dumpDbPath, getSafeExString(ex))
|
||||||
warnMsg += "Using temporary directory '%s' instead" % tempDir
|
warnMsg += "Using temporary directory '%s' instead" % tempDir
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
dumpDbPath = tempDir
|
dumpDbPath = tempDir
|
||||||
|
|
||||||
|
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (unsafeSQLIdentificatorNaming(table), conf.dumpFormat.lower()))
|
||||||
|
if not os.path.isfile(dumpFileName):
|
||||||
|
try:
|
||||||
|
openFile(dumpFileName, "w+b").close()
|
||||||
|
except SqlmapSystemException:
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
warnFile = True
|
||||||
|
|
||||||
_ = re.sub(r"[^\w]", "_", normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
|
_ = re.sub(r"[^\w]", "_", normalizeUnicode(unsafeSQLIdentificatorNaming(table)))
|
||||||
if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
|
if len(_) < len(table) or IS_WIN and table.upper() in WINDOWS_RESERVED_NAMES:
|
||||||
_ = unicodeencode(re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(table)))
|
_ = unicodeencode(re.sub(r"[^\w]", "_", unsafeSQLIdentificatorNaming(table)))
|
||||||
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(unicodeencode(table)).hexdigest()[:8], conf.dumpFormat.lower()))
|
dumpFileName = os.path.join(dumpDbPath, "%s-%s.%s" % (_, hashlib.md5(unicodeencode(table)).hexdigest()[:8], conf.dumpFormat.lower()))
|
||||||
warnFile = True
|
|
||||||
else:
|
else:
|
||||||
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
|
dumpFileName = os.path.join(dumpDbPath, "%s.%s" % (_, conf.dumpFormat.lower()))
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -164,8 +164,10 @@ class HTTP_HEADER:
|
||||||
CONTENT_RANGE = "Content-Range"
|
CONTENT_RANGE = "Content-Range"
|
||||||
CONTENT_TYPE = "Content-Type"
|
CONTENT_TYPE = "Content-Type"
|
||||||
COOKIE = "Cookie"
|
COOKIE = "Cookie"
|
||||||
SET_COOKIE = "Set-Cookie"
|
EXPIRES = "Expires"
|
||||||
HOST = "Host"
|
HOST = "Host"
|
||||||
|
IF_MODIFIED_SINCE = "If-Modified-Since"
|
||||||
|
LAST_MODIFIED = "Last-Modified"
|
||||||
LOCATION = "Location"
|
LOCATION = "Location"
|
||||||
PRAGMA = "Pragma"
|
PRAGMA = "Pragma"
|
||||||
PROXY_AUTHORIZATION = "Proxy-Authorization"
|
PROXY_AUTHORIZATION = "Proxy-Authorization"
|
||||||
|
@ -173,9 +175,10 @@ class HTTP_HEADER:
|
||||||
RANGE = "Range"
|
RANGE = "Range"
|
||||||
REFERER = "Referer"
|
REFERER = "Referer"
|
||||||
SERVER = "Server"
|
SERVER = "Server"
|
||||||
USER_AGENT = "User-Agent"
|
SET_COOKIE = "Set-Cookie"
|
||||||
TRANSFER_ENCODING = "Transfer-Encoding"
|
TRANSFER_ENCODING = "Transfer-Encoding"
|
||||||
URI = "URI"
|
URI = "URI"
|
||||||
|
USER_AGENT = "User-Agent"
|
||||||
VIA = "Via"
|
VIA = "Via"
|
||||||
X_POWERED_BY = "X-Powered-By"
|
X_POWERED_BY = "X-Powered-By"
|
||||||
|
|
||||||
|
@ -191,6 +194,7 @@ class OPTION_TYPE:
|
||||||
|
|
||||||
class HASHDB_KEYS:
|
class HASHDB_KEYS:
|
||||||
DBMS = "DBMS"
|
DBMS = "DBMS"
|
||||||
|
CHECK_WAF_RESULT = "CHECK_WAF_RESULT"
|
||||||
CONF_TMP_PATH = "CONF_TMP_PATH"
|
CONF_TMP_PATH = "CONF_TMP_PATH"
|
||||||
KB_ABS_FILE_PATHS = "KB_ABS_FILE_PATHS"
|
KB_ABS_FILE_PATHS = "KB_ABS_FILE_PATHS"
|
||||||
KB_BRUTE_COLUMNS = "KB_BRUTE_COLUMNS"
|
KB_BRUTE_COLUMNS = "KB_BRUTE_COLUMNS"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
|
|
||||||
if not(conf.scope and not re.search(conf.scope, url, re.I)):
|
if not(conf.scope and not re.search(conf.scope, url, re.I)):
|
||||||
if not kb.targets or url not in addedTargetUrls:
|
if not kb.targets or url not in addedTargetUrls:
|
||||||
kb.targets.add((url, method, data, cookie, tuple(headers)))
|
kb.targets.add((url, conf.method or method, data, cookie, tuple(headers)))
|
||||||
addedTargetUrls.add(url)
|
addedTargetUrls.add(url)
|
||||||
|
|
||||||
checkFile(reqFile)
|
checkFile(reqFile)
|
||||||
|
@ -341,7 +341,7 @@ def _feedTargetsDict(reqFile, addedTargetUrls):
|
||||||
content = f.read()
|
content = f.read()
|
||||||
except (IOError, OSError, MemoryError), ex:
|
except (IOError, OSError, MemoryError), ex:
|
||||||
errMsg = "something went wrong while trying "
|
errMsg = "something went wrong while trying "
|
||||||
errMsg += "to read the content of file '%s' ('%s')" % (reqFile, ex)
|
errMsg += "to read the content of file '%s' ('%s')" % (reqFile, getSafeExString(ex))
|
||||||
raise SqlmapSystemException(errMsg)
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
if conf.scope:
|
if conf.scope:
|
||||||
|
@ -386,7 +386,7 @@ def _loadQueries():
|
||||||
tree.parse(paths.QUERIES_XML)
|
tree.parse(paths.QUERIES_XML)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something seems to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (paths.QUERIES_XML, ex)
|
errMsg += "the file '%s' ('%s'). Please make " % (paths.QUERIES_XML, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ def _setCrawler():
|
||||||
status = "%d/%d links visited (%d%%)" % (i + 1, len(targets), round(100.0 * (i + 1) / len(targets)))
|
status = "%d/%d links visited (%d%%)" % (i + 1, len(targets), round(100.0 * (i + 1) / len(targets)))
|
||||||
dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status), True)
|
dataToStdout("\r[%s] [INFO] %s" % (time.strftime("%X"), status), True)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "problem occurred while crawling at '%s' ('%s')" % (target, ex)
|
errMsg = "problem occurred while crawling at '%s' ('%s')" % (target, getSafeExString(ex))
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
|
|
||||||
def _doSearch():
|
def _doSearch():
|
||||||
|
@ -639,7 +639,7 @@ def _findPageForms():
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
break
|
break
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "problem occurred while searching for forms at '%s' ('%s')" % (target, ex)
|
errMsg = "problem occurred while searching for forms at '%s' ('%s')" % (target, getSafeExString(ex))
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
|
|
||||||
def _setDBMSAuthentication():
|
def _setDBMSAuthentication():
|
||||||
|
@ -1028,7 +1028,7 @@ def _setSocketPreConnect():
|
||||||
return
|
return
|
||||||
|
|
||||||
def _():
|
def _():
|
||||||
while kb.threadContinue:
|
while kb.threadContinue and not conf.disablePrecon:
|
||||||
try:
|
try:
|
||||||
for key in socket._ready:
|
for key in socket._ready:
|
||||||
if len(socket._ready[key]) < SOCKET_PRE_CONNECT_QUEUE_SIZE:
|
if len(socket._ready[key]) < SOCKET_PRE_CONNECT_QUEUE_SIZE:
|
||||||
|
@ -1037,13 +1037,16 @@ def _setSocketPreConnect():
|
||||||
s._connect(address)
|
s._connect(address)
|
||||||
with kb.locks.socket:
|
with kb.locks.socket:
|
||||||
socket._ready[key].append(s._sock)
|
socket._ready[key].append(s._sock)
|
||||||
except socket.error:
|
except KeyboardInterrupt:
|
||||||
|
break
|
||||||
|
except:
|
||||||
pass
|
pass
|
||||||
finally:
|
finally:
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
def connect(self, address):
|
def connect(self, address):
|
||||||
found = False
|
found = False
|
||||||
|
|
||||||
key = (self.family, self.type, self.proto, address)
|
key = (self.family, self.type, self.proto, address)
|
||||||
with kb.locks.socket:
|
with kb.locks.socket:
|
||||||
if key not in socket._ready:
|
if key not in socket._ready:
|
||||||
|
@ -1051,6 +1054,7 @@ def _setSocketPreConnect():
|
||||||
if len(socket._ready[key]) > 0:
|
if len(socket._ready[key]) > 0:
|
||||||
self._sock = socket._ready[key].pop(0)
|
self._sock = socket._ready[key].pop(0)
|
||||||
found = True
|
found = True
|
||||||
|
|
||||||
if not found:
|
if not found:
|
||||||
self._connect(address)
|
self._connect(address)
|
||||||
|
|
||||||
|
@ -1094,7 +1098,7 @@ def _setHTTPHandlers():
|
||||||
try:
|
try:
|
||||||
_ = urlparse.urlsplit(conf.proxy)
|
_ = urlparse.urlsplit(conf.proxy)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "invalid proxy address '%s' ('%s')" % (conf.proxy, ex)
|
errMsg = "invalid proxy address '%s' ('%s')" % (conf.proxy, getSafeExString(ex))
|
||||||
raise SqlmapSyntaxException, errMsg
|
raise SqlmapSyntaxException, errMsg
|
||||||
|
|
||||||
hostnamePort = _.netloc.split(":")
|
hostnamePort = _.netloc.split(":")
|
||||||
|
@ -1682,7 +1686,7 @@ def _cleanupOptions():
|
||||||
conf.torType = conf.torType.upper()
|
conf.torType = conf.torType.upper()
|
||||||
|
|
||||||
if conf.outputDir:
|
if conf.outputDir:
|
||||||
paths.SQLMAP_OUTPUT_PATH = conf.outputDir
|
paths.SQLMAP_OUTPUT_PATH = os.path.realpath(os.path.expanduser(conf.outputDir))
|
||||||
setPaths()
|
setPaths()
|
||||||
|
|
||||||
if conf.string:
|
if conf.string:
|
||||||
|
@ -1891,7 +1895,9 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.reflectiveCounters = {REFLECTIVE_COUNTER.MISS: 0, REFLECTIVE_COUNTER.HIT: 0}
|
kb.reflectiveCounters = {REFLECTIVE_COUNTER.MISS: 0, REFLECTIVE_COUNTER.HIT: 0}
|
||||||
kb.requestCounter = 0
|
kb.requestCounter = 0
|
||||||
kb.resendPostOnRedirect = None
|
kb.resendPostOnRedirect = None
|
||||||
kb.responseTimes = []
|
kb.responseTimes = {}
|
||||||
|
kb.responseTimeMode = None
|
||||||
|
kb.responseTimePayload = None
|
||||||
kb.resumeValues = True
|
kb.resumeValues = True
|
||||||
kb.safeCharEncode = False
|
kb.safeCharEncode = False
|
||||||
kb.safeReq = AttribDict()
|
kb.safeReq = AttribDict()
|
||||||
|
@ -2053,7 +2059,7 @@ def _saveConfig():
|
||||||
config.write(confFP)
|
config.write(confFP)
|
||||||
except IOError, ex:
|
except IOError, ex:
|
||||||
errMsg = "something went wrong while trying "
|
errMsg = "something went wrong while trying "
|
||||||
errMsg += "to write to the configuration file '%s' ('%s')" % (conf.saveConfig, ex)
|
errMsg += "to write to the configuration file '%s' ('%s')" % (conf.saveConfig, getSafeExString(ex))
|
||||||
raise SqlmapSystemException(errMsg)
|
raise SqlmapSystemException(errMsg)
|
||||||
|
|
||||||
infoMsg = "saved command line options to the configuration file '%s'" % conf.saveConfig
|
infoMsg = "saved command line options to the configuration file '%s'" % conf.saveConfig
|
||||||
|
@ -2085,6 +2091,43 @@ def setVerbosity():
|
||||||
elif conf.verbose >= 5:
|
elif conf.verbose >= 5:
|
||||||
logger.setLevel(CUSTOM_LOGGING.TRAFFIC_IN)
|
logger.setLevel(CUSTOM_LOGGING.TRAFFIC_IN)
|
||||||
|
|
||||||
|
def _normalizeOptions(inputOptions):
|
||||||
|
"""
|
||||||
|
Sets proper option types
|
||||||
|
"""
|
||||||
|
|
||||||
|
types_ = {}
|
||||||
|
for group in optDict.keys():
|
||||||
|
types_.update(optDict[group])
|
||||||
|
|
||||||
|
for key in inputOptions:
|
||||||
|
if key in types_:
|
||||||
|
value = inputOptions[key]
|
||||||
|
if value is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
type_ = types_[key]
|
||||||
|
if type_ and isinstance(type_, tuple):
|
||||||
|
type_ = type_[0]
|
||||||
|
|
||||||
|
if type_ == OPTION_TYPE.BOOLEAN:
|
||||||
|
try:
|
||||||
|
value = bool(value)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
value = False
|
||||||
|
elif type_ == OPTION_TYPE.INTEGER:
|
||||||
|
try:
|
||||||
|
value = int(value)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
value = 0
|
||||||
|
elif type_ == OPTION_TYPE.FLOAT:
|
||||||
|
try:
|
||||||
|
value = float(value)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
value = 0.0
|
||||||
|
|
||||||
|
inputOptions[key] = value
|
||||||
|
|
||||||
def _mergeOptions(inputOptions, overrideOptions):
|
def _mergeOptions(inputOptions, overrideOptions):
|
||||||
"""
|
"""
|
||||||
Merge command line options with configuration file and default options.
|
Merge command line options with configuration file and default options.
|
||||||
|
@ -2096,6 +2139,7 @@ def _mergeOptions(inputOptions, overrideOptions):
|
||||||
if inputOptions.pickledOptions:
|
if inputOptions.pickledOptions:
|
||||||
try:
|
try:
|
||||||
inputOptions = base64unpickle(inputOptions.pickledOptions)
|
inputOptions = base64unpickle(inputOptions.pickledOptions)
|
||||||
|
_normalizeOptions(inputOptions)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
errMsg = "provided invalid value '%s' for option '--pickled-options'" % inputOptions.pickledOptions
|
errMsg = "provided invalid value '%s' for option '--pickled-options'" % inputOptions.pickledOptions
|
||||||
errMsg += " ('%s')" % ex if ex.message else ""
|
errMsg += " ('%s')" % ex if ex.message else ""
|
||||||
|
@ -2121,35 +2165,21 @@ def _mergeOptions(inputOptions, overrideOptions):
|
||||||
if hasattr(conf, key) and conf[key] is None:
|
if hasattr(conf, key) and conf[key] is None:
|
||||||
conf[key] = value
|
conf[key] = value
|
||||||
|
|
||||||
_ = {}
|
|
||||||
|
lut = {}
|
||||||
|
for group in optDict.keys():
|
||||||
|
lut.update((_.upper(), _) for _ in optDict[group])
|
||||||
|
|
||||||
|
envOptions = {}
|
||||||
for key, value in os.environ.items():
|
for key, value in os.environ.items():
|
||||||
if key.upper().startswith(SQLMAP_ENVIRONMENT_PREFIX):
|
if key.upper().startswith(SQLMAP_ENVIRONMENT_PREFIX):
|
||||||
_[key[len(SQLMAP_ENVIRONMENT_PREFIX):].upper()] = value
|
_ = key[len(SQLMAP_ENVIRONMENT_PREFIX):].upper()
|
||||||
|
if _ in lut:
|
||||||
types_ = {}
|
envOptions[lut[_]] = value
|
||||||
for group in optDict.keys():
|
|
||||||
types_.update(optDict[group])
|
|
||||||
|
|
||||||
for key in conf:
|
|
||||||
if key.upper() in _ and key in types_:
|
|
||||||
value = _[key.upper()]
|
|
||||||
|
|
||||||
if types_[key] == OPTION_TYPE.BOOLEAN:
|
|
||||||
try:
|
|
||||||
value = bool(value)
|
|
||||||
except ValueError:
|
|
||||||
value = False
|
|
||||||
elif types_[key] == OPTION_TYPE.INTEGER:
|
|
||||||
try:
|
|
||||||
value = int(value)
|
|
||||||
except ValueError:
|
|
||||||
value = 0
|
|
||||||
elif types_[key] == OPTION_TYPE.FLOAT:
|
|
||||||
try:
|
|
||||||
value = float(value)
|
|
||||||
except ValueError:
|
|
||||||
value = 0.0
|
|
||||||
|
|
||||||
|
if envOptions:
|
||||||
|
_normalizeOptions(envOptions)
|
||||||
|
for key, value in envOptions.items():
|
||||||
conf[key] = value
|
conf[key] = value
|
||||||
|
|
||||||
mergedOptions.update(conf)
|
mergedOptions.update(conf)
|
||||||
|
@ -2228,11 +2258,6 @@ def _setTorHttpProxySettings():
|
||||||
errMsg += "Polipo bundle installed for you to be able to "
|
errMsg += "Polipo bundle installed for you to be able to "
|
||||||
errMsg += "successfully use switch '--tor' "
|
errMsg += "successfully use switch '--tor' "
|
||||||
|
|
||||||
if IS_WIN:
|
|
||||||
errMsg += "(e.g. https://www.torproject.org/projects/vidalia.html.en)"
|
|
||||||
else:
|
|
||||||
errMsg += "(e.g. http://www.coresec.org/2011/04/24/sqlmap-with-tor/)"
|
|
||||||
|
|
||||||
raise SqlmapConnectionException(errMsg)
|
raise SqlmapConnectionException(errMsg)
|
||||||
|
|
||||||
if not conf.checkTor:
|
if not conf.checkTor:
|
||||||
|
@ -2252,9 +2277,6 @@ def _setTorSocksProxySettings():
|
||||||
socks.wrapmodule(urllib2)
|
socks.wrapmodule(urllib2)
|
||||||
|
|
||||||
def _checkWebSocket():
|
def _checkWebSocket():
|
||||||
infoMsg = "checking for WebSocket"
|
|
||||||
logger.debug(infoMsg)
|
|
||||||
|
|
||||||
if conf.url and (conf.url.startswith("ws:/") or conf.url.startswith("wss:/")):
|
if conf.url and (conf.url.startswith("ws:/") or conf.url.startswith("wss:/")):
|
||||||
try:
|
try:
|
||||||
from websocket import ABNF
|
from websocket import ABNF
|
||||||
|
@ -2365,14 +2387,14 @@ def _basicOptionValidation():
|
||||||
try:
|
try:
|
||||||
re.compile(conf.regexp)
|
re.compile(conf.regexp)
|
||||||
except re.error, ex:
|
except re.error, ex:
|
||||||
errMsg = "invalid regular expression '%s' ('%s')" % (conf.regexp, ex)
|
errMsg = "invalid regular expression '%s' ('%s')" % (conf.regexp, getSafeExString(ex))
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if conf.crawlExclude:
|
if conf.crawlExclude:
|
||||||
try:
|
try:
|
||||||
re.compile(conf.crawlExclude)
|
re.compile(conf.crawlExclude)
|
||||||
except re.error, ex:
|
except re.error, ex:
|
||||||
errMsg = "invalid regular expression '%s' ('%s')" % (conf.crawlExclude, ex)
|
errMsg = "invalid regular expression '%s' ('%s')" % (conf.crawlExclude, getSafeExString(ex))
|
||||||
raise SqlmapSyntaxException(errMsg)
|
raise SqlmapSyntaxException(errMsg)
|
||||||
|
|
||||||
if conf.dumpTable and conf.dumpAll:
|
if conf.dumpTable and conf.dumpAll:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -26,9 +26,8 @@ def profile(profileOutputFile=None, dotOutputFile=None, imageOutputFile=None):
|
||||||
import gtk
|
import gtk
|
||||||
import pydot
|
import pydot
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
errMsg = "profiling requires third-party libraries (%s). " % getUnicode(e, UNICODE_ENCODING)
|
errMsg = "profiling requires third-party libraries ('%s') " % getUnicode(e, UNICODE_ENCODING)
|
||||||
errMsg += "Quick steps:%s" % os.linesep
|
errMsg += "(Hint: 'sudo apt-get install python-pydot python-pyparsing python-profiler graphviz')"
|
||||||
errMsg += "1) sudo apt-get install python-pydot python-pyparsing python-profiler graphviz"
|
|
||||||
logger.error(errMsg)
|
logger.error(errMsg)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ from lib.core.revision import getRevisionNumber
|
||||||
# sqlmap version and site
|
# sqlmap version and site
|
||||||
VERSION = "1.0-dev"
|
VERSION = "1.0-dev"
|
||||||
REVISION = getRevisionNumber()
|
REVISION = getRevisionNumber()
|
||||||
VERSION_STRING = "sqlmap/%s%s" % (VERSION, "-%s" % REVISION if REVISION else "-nongit-%s%04x" % (time.strftime("%Y%m%d", time.gmtime(os.path.getmtime(__file__))), os.path.getsize(os.path.join(os.path.dirname(__file__), "common.py")) & 0xffff))
|
VERSION_STRING = "sqlmap/%s%s" % (VERSION, "-%s" % REVISION if REVISION else "-nongit-%s-%04x" % (time.strftime("%Y%m%d", time.gmtime(os.path.getmtime(__file__))), os.path.getsize(os.path.join(os.path.dirname(__file__), "common.py")) & 0xffff))
|
||||||
DESCRIPTION = "automatic SQL injection and database takeover tool"
|
DESCRIPTION = "automatic SQL injection and database takeover tool"
|
||||||
SITE = "http://sqlmap.org"
|
SITE = "http://sqlmap.org"
|
||||||
ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new"
|
ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new"
|
||||||
|
@ -61,6 +61,9 @@ URI_QUESTION_MARKER = "__QUESTION_MARK__"
|
||||||
ASTERISK_MARKER = "__ASTERISK_MARK__"
|
ASTERISK_MARKER = "__ASTERISK_MARK__"
|
||||||
REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
|
REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
|
||||||
|
|
||||||
|
RANDOM_INTEGER_MARKER = "[RANDINT]"
|
||||||
|
RANDOM_STRING_MARKER = "[RANDSTR]"
|
||||||
|
|
||||||
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
|
PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__"
|
||||||
CHAR_INFERENCE_MARK = "%c"
|
CHAR_INFERENCE_MARK = "%c"
|
||||||
PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]"
|
PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]"
|
||||||
|
@ -306,6 +309,9 @@ BURP_REQUEST_REGEX = r"={10,}\s+[^=]+={10,}\s(.+?)\s={10,}"
|
||||||
# Regex used for parsing XML Burp saved history items
|
# Regex used for parsing XML Burp saved history items
|
||||||
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.+?<request base64="true"><!\[CDATA\[([^]]+)'
|
BURP_XML_HISTORY_REGEX = r'<port>(\d+)</port>.+?<request base64="true"><!\[CDATA\[([^]]+)'
|
||||||
|
|
||||||
|
# Server header in CloudFlare responses
|
||||||
|
CLOUDFLARE_SERVER_HEADER = "cloudflare-nginx"
|
||||||
|
|
||||||
# Encoding used for Unicode data
|
# Encoding used for Unicode data
|
||||||
UNICODE_ENCODING = "utf8"
|
UNICODE_ENCODING = "utf8"
|
||||||
|
|
||||||
|
@ -545,8 +551,11 @@ DNS_BOUNDARIES_ALPHABET = re.sub("[a-fA-F]", "", string.ascii_letters)
|
||||||
# Alphabet used for heuristic checks
|
# Alphabet used for heuristic checks
|
||||||
HEURISTIC_CHECK_ALPHABET = ('"', '\'', ')', '(', ',', '.')
|
HEURISTIC_CHECK_ALPHABET = ('"', '\'', ')', '(', ',', '.')
|
||||||
|
|
||||||
# String used for dummy XSS check of a tested parameter value
|
# String used for dummy non-SQLi (e.g. XSS) heuristic checks of a tested parameter value
|
||||||
DUMMY_XSS_CHECK_APPENDIX = "<'\">"
|
DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">"
|
||||||
|
|
||||||
|
# Length of prefix and suffix used in non-SQLI heuristic checks
|
||||||
|
NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH = 6
|
||||||
|
|
||||||
# Connection chunk size (processing large responses in chunks to avoid MemoryError crashes - e.g. large table dump in full UNION injections)
|
# Connection chunk size (processing large responses in chunks to avoid MemoryError crashes - e.g. large table dump in full UNION injections)
|
||||||
MAX_CONNECTION_CHUNK_SIZE = 10 * 1024 * 1024
|
MAX_CONNECTION_CHUNK_SIZE = 10 * 1024 * 1024
|
||||||
|
@ -561,7 +570,7 @@ MAX_BISECTION_LENGTH = 50 * 1024 * 1024
|
||||||
LARGE_CHUNK_TRIM_MARKER = "__TRIMMED_CONTENT__"
|
LARGE_CHUNK_TRIM_MARKER = "__TRIMMED_CONTENT__"
|
||||||
|
|
||||||
# Generic SQL comment formation
|
# Generic SQL comment formation
|
||||||
GENERIC_SQL_COMMENT = "-- "
|
GENERIC_SQL_COMMENT = "-- -"
|
||||||
|
|
||||||
# Threshold value for turning back on time auto-adjustment mechanism
|
# Threshold value for turning back on time auto-adjustment mechanism
|
||||||
VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
||||||
|
@ -570,7 +579,7 @@ VALID_TIME_CHARS_RUN_THRESHOLD = 100
|
||||||
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
CHECK_ZERO_COLUMNS_THRESHOLD = 10
|
||||||
|
|
||||||
# Boldify all logger messages containing these "patterns"
|
# Boldify all logger messages containing these "patterns"
|
||||||
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved")
|
BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CloudFlare")
|
||||||
|
|
||||||
# Generic www root directory names
|
# Generic www root directory names
|
||||||
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
|
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www")
|
||||||
|
@ -593,6 +602,9 @@ EVENTVALIDATION_REGEX = r'(?i)(?P<name>__EVENTVALIDATION[^"]*)[^>]+value="(?P<re
|
||||||
# Number of rows to generate inside the full union test for limited output (mustn't be too large to prevent payload length problems)
|
# Number of rows to generate inside the full union test for limited output (mustn't be too large to prevent payload length problems)
|
||||||
LIMITED_ROWS_TEST_NUMBER = 15
|
LIMITED_ROWS_TEST_NUMBER = 15
|
||||||
|
|
||||||
|
# Default adapter to use for bottle server
|
||||||
|
RESTAPI_DEFAULT_ADAPTER = "wsgiref"
|
||||||
|
|
||||||
# Default REST-JSON API server listen address
|
# Default REST-JSON API server listen address
|
||||||
RESTAPI_DEFAULT_ADDRESS = "127.0.0.1"
|
RESTAPI_DEFAULT_ADDRESS = "127.0.0.1"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import time
|
||||||
import urlparse
|
import urlparse
|
||||||
|
|
||||||
from lib.core.common import Backend
|
from lib.core.common import Backend
|
||||||
|
from lib.core.common import getSafeExString
|
||||||
from lib.core.common import getUnicode
|
from lib.core.common import getUnicode
|
||||||
from lib.core.common import hashDBRetrieve
|
from lib.core.common import hashDBRetrieve
|
||||||
from lib.core.common import intersect
|
from lib.core.common import intersect
|
||||||
|
@ -658,7 +659,7 @@ def _createTargetDirs():
|
||||||
errMsg = "you don't have enough permissions "
|
errMsg = "you don't have enough permissions "
|
||||||
else:
|
else:
|
||||||
errMsg = "something went wrong while trying "
|
errMsg = "something went wrong while trying "
|
||||||
errMsg += "to write to the output directory '%s' (%s)" % (paths.SQLMAP_OUTPUT_PATH, ex)
|
errMsg += "to write to the output directory '%s' (%s)" % (paths.SQLMAP_OUTPUT_PATH, getSafeExString(ex))
|
||||||
|
|
||||||
raise SqlmapMissingPrivileges(errMsg)
|
raise SqlmapMissingPrivileges(errMsg)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
|
from lib.core.common import getSafeExString
|
||||||
from lib.core.exception import SqlmapDataException
|
from lib.core.exception import SqlmapDataException
|
||||||
from lib.core.exception import SqlmapInstallationException
|
from lib.core.exception import SqlmapInstallationException
|
||||||
from lib.core.settings import UNICODE_ENCODING
|
from lib.core.settings import UNICODE_ENCODING
|
||||||
|
@ -45,7 +46,7 @@ class Wordlist(object):
|
||||||
_ = zipfile.ZipFile(self.current, 'r')
|
_ = zipfile.ZipFile(self.current, 'r')
|
||||||
except zipfile.error, ex:
|
except zipfile.error, ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something seems to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (self.current, ex)
|
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
if len(_.namelist()) == 0:
|
if len(_.namelist()) == 0:
|
||||||
|
@ -71,7 +72,7 @@ class Wordlist(object):
|
||||||
retVal = self.iter.next().rstrip()
|
retVal = self.iter.next().rstrip()
|
||||||
except zipfile.error, ex:
|
except zipfile.error, ex:
|
||||||
errMsg = "something seems to be wrong with "
|
errMsg = "something seems to be wrong with "
|
||||||
errMsg += "the file '%s' ('%s'). Please make " % (self.current, ex)
|
errMsg += "the file '%s' ('%s'). Please make " % (self.current, getSafeExString(ex))
|
||||||
errMsg += "sure that you haven't made any changes to it"
|
errMsg += "sure that you haven't made any changes to it"
|
||||||
raise SqlmapInstallationException, errMsg
|
raise SqlmapInstallationException, errMsg
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -801,10 +801,10 @@ def cmdLineParser(argv=None):
|
||||||
|
|
||||||
# Dirty hack to display longer options without breaking into two lines
|
# Dirty hack to display longer options without breaking into two lines
|
||||||
def _(self, *args):
|
def _(self, *args):
|
||||||
_ = parser.formatter._format_option_strings(*args)
|
retVal = parser.formatter._format_option_strings(*args)
|
||||||
if len(_) > MAX_HELP_OPTION_LENGTH:
|
if len(retVal) > MAX_HELP_OPTION_LENGTH:
|
||||||
_ = ("%%.%ds.." % (MAX_HELP_OPTION_LENGTH - parser.formatter.indent_increment)) % _
|
retVal = ("%%.%ds.." % (MAX_HELP_OPTION_LENGTH - parser.formatter.indent_increment)) % retVal
|
||||||
return _
|
return retVal
|
||||||
|
|
||||||
parser.formatter._format_option_strings = parser.formatter.format_option_strings
|
parser.formatter._format_option_strings = parser.formatter.format_option_strings
|
||||||
parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser, type(parser))
|
parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser, type(parser))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
2
lib/request/basic.py
Executable file → Normal file
2
lib/request/basic.py
Executable file → Normal file
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ from lib.core.exception import SqlmapSyntaxException
|
||||||
from lib.core.exception import SqlmapTokenException
|
from lib.core.exception import SqlmapTokenException
|
||||||
from lib.core.exception import SqlmapValueException
|
from lib.core.exception import SqlmapValueException
|
||||||
from lib.core.settings import ASTERISK_MARKER
|
from lib.core.settings import ASTERISK_MARKER
|
||||||
|
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
|
||||||
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
|
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
|
||||||
from lib.core.settings import DEFAULT_CONTENT_TYPE
|
from lib.core.settings import DEFAULT_CONTENT_TYPE
|
||||||
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
|
from lib.core.settings import DEFAULT_COOKIE_DELIMITER
|
||||||
|
@ -97,6 +98,8 @@ from lib.core.settings import LARGE_CHUNK_TRIM_MARKER
|
||||||
from lib.core.settings import PAYLOAD_DELIMITER
|
from lib.core.settings import PAYLOAD_DELIMITER
|
||||||
from lib.core.settings import PERMISSION_DENIED_REGEX
|
from lib.core.settings import PERMISSION_DENIED_REGEX
|
||||||
from lib.core.settings import PLAIN_TEXT_CONTENT_TYPE
|
from lib.core.settings import PLAIN_TEXT_CONTENT_TYPE
|
||||||
|
from lib.core.settings import RANDOM_INTEGER_MARKER
|
||||||
|
from lib.core.settings import RANDOM_STRING_MARKER
|
||||||
from lib.core.settings import REPLACEMENT_MARKER
|
from lib.core.settings import REPLACEMENT_MARKER
|
||||||
from lib.core.settings import TEXT_CONTENT_TYPE_REGEX
|
from lib.core.settings import TEXT_CONTENT_TYPE_REGEX
|
||||||
from lib.core.settings import UNENCODED_ORIGINAL_VALUE
|
from lib.core.settings import UNENCODED_ORIGINAL_VALUE
|
||||||
|
@ -612,6 +615,9 @@ class Connect(object):
|
||||||
elif "forcibly closed" in tbMsg or "Connection is already closed" in tbMsg:
|
elif "forcibly closed" in tbMsg or "Connection is already closed" in tbMsg:
|
||||||
warnMsg = "connection was forcibly closed by the target URL"
|
warnMsg = "connection was forcibly closed by the target URL"
|
||||||
elif "timed out" in tbMsg:
|
elif "timed out" in tbMsg:
|
||||||
|
singleTimeWarnMessage("turning off pre-connect mechanism because of connection time out(s)")
|
||||||
|
conf.disablePrecon = True
|
||||||
|
|
||||||
if kb.testMode and kb.testType not in (None, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED):
|
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) is dropping 'suspicious' requests")
|
singleTimeWarnMessage("there is a possibility that the target (or WAF) is dropping 'suspicious' requests")
|
||||||
warnMsg = "connection timed out to the target URL"
|
warnMsg = "connection timed out to the target URL"
|
||||||
|
@ -760,7 +766,7 @@ class Connect(object):
|
||||||
|
|
||||||
value = agent.replacePayload(value, payload)
|
value = agent.replacePayload(value, payload)
|
||||||
|
|
||||||
logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload))
|
logger.log(CUSTOM_LOGGING.PAYLOAD, safecharencode(payload.replace('\\', BOUNDARY_BACKSLASH_MARKER)).replace(BOUNDARY_BACKSLASH_MARKER, '\\'))
|
||||||
|
|
||||||
if place == PLACE.CUSTOM_POST and kb.postHint:
|
if place == PLACE.CUSTOM_POST and kb.postHint:
|
||||||
if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML):
|
if kb.postHint in (POST_HINT.SOAP, POST_HINT.XML):
|
||||||
|
@ -982,7 +988,7 @@ class Connect(object):
|
||||||
if name != "__builtins__" and originals.get(name, "") != value:
|
if name != "__builtins__" and originals.get(name, "") != value:
|
||||||
if isinstance(value, (basestring, int)):
|
if isinstance(value, (basestring, int)):
|
||||||
found = False
|
found = False
|
||||||
value = unicode(value)
|
value = getUnicode(value)
|
||||||
|
|
||||||
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(delimiter), re.escape(name), re.escape(delimiter))
|
regex = r"((\A|%s)%s=).+?(%s|\Z)" % (re.escape(delimiter), re.escape(name), re.escape(delimiter))
|
||||||
if re.search(regex, (get or "")):
|
if re.search(regex, (get or "")):
|
||||||
|
@ -1020,34 +1026,37 @@ class Connect(object):
|
||||||
post = urlencode(post, spaceplus=kb.postSpaceToPlus)
|
post = urlencode(post, spaceplus=kb.postSpaceToPlus)
|
||||||
|
|
||||||
if timeBasedCompare:
|
if timeBasedCompare:
|
||||||
if len(kb.responseTimes) < MIN_TIME_RESPONSES:
|
if len(kb.responseTimes.get(kb.responseTimeMode, [])) < MIN_TIME_RESPONSES:
|
||||||
clearConsoleLine()
|
clearConsoleLine()
|
||||||
|
|
||||||
|
kb.responseTimes.setdefault(kb.responseTimeMode, [])
|
||||||
|
|
||||||
if conf.tor:
|
if conf.tor:
|
||||||
warnMsg = "it's highly recommended to avoid usage of switch '--tor' for "
|
warnMsg = "it's highly recommended to avoid usage of switch '--tor' for "
|
||||||
warnMsg += "time-based injections because of its high latency time"
|
warnMsg += "time-based injections because of its high latency time"
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
warnMsg = "[%s] [WARNING] time-based comparison requires " % time.strftime("%X")
|
warnMsg = "[%s] [WARNING] %stime-based comparison requires " % (time.strftime("%X"), "(case) " if kb.responseTimeMode else "")
|
||||||
warnMsg += "larger statistical model, please wait"
|
warnMsg += "larger statistical model, please wait"
|
||||||
dataToStdout(warnMsg)
|
dataToStdout(warnMsg)
|
||||||
|
|
||||||
while len(kb.responseTimes) < MIN_TIME_RESPONSES:
|
while len(kb.responseTimes[kb.responseTimeMode]) < MIN_TIME_RESPONSES:
|
||||||
Connect.queryPage(content=True)
|
value = kb.responseTimePayload.replace(RANDOM_INTEGER_MARKER, str(randomInt(6))).replace(RANDOM_STRING_MARKER, randomStr()) if kb.responseTimePayload else kb.responseTimePayload
|
||||||
|
Connect.queryPage(value=value, content=True, raise404=False)
|
||||||
dataToStdout('.')
|
dataToStdout('.')
|
||||||
|
|
||||||
dataToStdout("\n")
|
dataToStdout(" (done)\n")
|
||||||
|
|
||||||
elif not kb.testMode:
|
elif not kb.testMode:
|
||||||
warnMsg = "it is very important not to stress the network adapter "
|
warnMsg = "it is very important to not stress the network adapter "
|
||||||
warnMsg += "during usage of time-based payloads to prevent potential "
|
warnMsg += "during usage of time-based payloads to prevent potential "
|
||||||
warnMsg += "errors "
|
warnMsg += "disruptions "
|
||||||
singleTimeWarnMessage(warnMsg)
|
singleTimeWarnMessage(warnMsg)
|
||||||
|
|
||||||
if not kb.laggingChecked:
|
if not kb.laggingChecked:
|
||||||
kb.laggingChecked = True
|
kb.laggingChecked = True
|
||||||
|
|
||||||
deviation = stdev(kb.responseTimes)
|
deviation = stdev(kb.responseTimes[kb.responseTimeMode])
|
||||||
|
|
||||||
if deviation > WARN_TIME_STDEV:
|
if deviation > WARN_TIME_STDEV:
|
||||||
kb.adjustTimeDelay = ADJUST_TIME_DELAY.DISABLE
|
kb.adjustTimeDelay = ADJUST_TIME_DELAY.DISABLE
|
||||||
|
@ -1115,7 +1124,8 @@ class Connect(object):
|
||||||
if timeBasedCompare:
|
if timeBasedCompare:
|
||||||
return wasLastResponseDelayed()
|
return wasLastResponseDelayed()
|
||||||
elif noteResponseTime:
|
elif noteResponseTime:
|
||||||
kb.responseTimes.append(threadData.lastQueryDuration)
|
kb.responseTimes.setdefault(kb.responseTimeMode, [])
|
||||||
|
kb.responseTimes[kb.responseTimeMode].append(threadData.lastQueryDuration)
|
||||||
|
|
||||||
if not response and removeReflection:
|
if not response and removeReflection:
|
||||||
page = removeReflectiveValues(page, payload)
|
page = removeReflectiveValues(page, payload)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ class DNSQuery(object):
|
||||||
|
|
||||||
class DNSServer(object):
|
class DNSServer(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self._check_localhost()
|
||||||
self._requests = []
|
self._requests = []
|
||||||
self._lock = threading.Lock()
|
self._lock = threading.Lock()
|
||||||
self._socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
self._socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
@ -67,6 +68,19 @@ class DNSServer(object):
|
||||||
self._running = False
|
self._running = False
|
||||||
self._initialized = False
|
self._initialized = False
|
||||||
|
|
||||||
|
def _check_localhost(self):
|
||||||
|
response = ""
|
||||||
|
try:
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
s.connect(("", 53))
|
||||||
|
s.send("6509012000010000000000010377777706676f6f676c6503636f6d00000100010000291000000000000000".decode("hex")) # A www.google.com
|
||||||
|
response = s.recv(512)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
if response and "google" in response:
|
||||||
|
raise socket.error("another DNS service already running on *:53")
|
||||||
|
|
||||||
def pop(self, prefix=None, suffix=None):
|
def pop(self, prefix=None, suffix=None):
|
||||||
"""
|
"""
|
||||||
Returns received DNS resolution request (if any) that has given
|
Returns received DNS resolution request (if any) that has given
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -432,6 +432,8 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
||||||
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
|
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
|
||||||
|
|
||||||
if time and (isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED)) and not found:
|
if time and (isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED)) and not found:
|
||||||
|
kb.responseTimeMode = re.sub(r"(?i)[^a-z]", "", re.sub(r"'[^']+'", "", expression)) if re.search(r"(?i)SELECT.+FROM", expression) else None
|
||||||
|
|
||||||
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME):
|
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME):
|
||||||
kb.technique = PAYLOAD.TECHNIQUE.TIME
|
kb.technique = PAYLOAD.TECHNIQUE.TIME
|
||||||
else:
|
else:
|
||||||
|
@ -441,7 +443,6 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
||||||
value = _goBooleanProxy(booleanExpression)
|
value = _goBooleanProxy(booleanExpression)
|
||||||
else:
|
else:
|
||||||
value = _goInferenceProxy(query, fromUser, batch, unpack, charsetType, firstChar, lastChar, dump)
|
value = _goInferenceProxy(query, fromUser, batch, unpack, charsetType, firstChar, lastChar, dump)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
errMsg = "none of the injection types identified can be "
|
errMsg = "none of the injection types identified can be "
|
||||||
errMsg += "leveraged to retrieve queries output"
|
errMsg += "leveraged to retrieve queries output"
|
||||||
|
@ -449,6 +450,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
kb.resumeValues = True
|
kb.resumeValues = True
|
||||||
|
kb.responseTimeMode = None
|
||||||
|
|
||||||
conf.tbl = popValue()
|
conf.tbl = popValue()
|
||||||
conf.db = popValue()
|
conf.db = popValue()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ from lib.core.common import getPartRun
|
||||||
from lib.core.common import hashDBRetrieve
|
from lib.core.common import hashDBRetrieve
|
||||||
from lib.core.common import hashDBWrite
|
from lib.core.common import hashDBWrite
|
||||||
from lib.core.common import incrementCounter
|
from lib.core.common import incrementCounter
|
||||||
|
from lib.core.common import randomInt
|
||||||
from lib.core.common import safeStringFormat
|
from lib.core.common import safeStringFormat
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
from lib.core.data import conf
|
from lib.core.data import conf
|
||||||
|
@ -42,10 +44,13 @@ from lib.core.settings import INFERENCE_UNKNOWN_CHAR
|
||||||
from lib.core.settings import INFERENCE_GREATER_CHAR
|
from lib.core.settings import INFERENCE_GREATER_CHAR
|
||||||
from lib.core.settings import INFERENCE_EQUALS_CHAR
|
from lib.core.settings import INFERENCE_EQUALS_CHAR
|
||||||
from lib.core.settings import INFERENCE_NOT_EQUALS_CHAR
|
from lib.core.settings import INFERENCE_NOT_EQUALS_CHAR
|
||||||
|
from lib.core.settings import MIN_TIME_RESPONSES
|
||||||
from lib.core.settings import MAX_BISECTION_LENGTH
|
from lib.core.settings import MAX_BISECTION_LENGTH
|
||||||
from lib.core.settings import MAX_TIME_REVALIDATION_STEPS
|
from lib.core.settings import MAX_TIME_REVALIDATION_STEPS
|
||||||
|
from lib.core.settings import NULL
|
||||||
from lib.core.settings import PARTIAL_HEX_VALUE_MARKER
|
from lib.core.settings import PARTIAL_HEX_VALUE_MARKER
|
||||||
from lib.core.settings import PARTIAL_VALUE_MARKER
|
from lib.core.settings import PARTIAL_VALUE_MARKER
|
||||||
|
from lib.core.settings import RANDOM_INTEGER_MARKER
|
||||||
from lib.core.settings import VALID_TIME_CHARS_RUN_THRESHOLD
|
from lib.core.settings import VALID_TIME_CHARS_RUN_THRESHOLD
|
||||||
from lib.core.threads import getCurrentThreadData
|
from lib.core.threads import getCurrentThreadData
|
||||||
from lib.core.threads import runThreads
|
from lib.core.threads import runThreads
|
||||||
|
@ -258,14 +263,23 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
|
||||||
while len(charTbl) != 1:
|
while len(charTbl) != 1:
|
||||||
position = (len(charTbl) >> 1)
|
position = (len(charTbl) >> 1)
|
||||||
posValue = charTbl[position]
|
posValue = charTbl[position]
|
||||||
|
falsePayload = None
|
||||||
|
|
||||||
if "'%s'" % CHAR_INFERENCE_MARK not in payload:
|
if "'%s'" % CHAR_INFERENCE_MARK not in payload:
|
||||||
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx, posValue))
|
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx, posValue))
|
||||||
|
falsePayload = safeStringFormat(payload, (expressionUnescaped, idx, RANDOM_INTEGER_MARKER))
|
||||||
else:
|
else:
|
||||||
# e.g.: ... > '%c' -> ... > ORD(..)
|
# e.g.: ... > '%c' -> ... > ORD(..)
|
||||||
markingValue = "'%s'" % CHAR_INFERENCE_MARK
|
markingValue = "'%s'" % CHAR_INFERENCE_MARK
|
||||||
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue))
|
unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue))
|
||||||
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx)).replace(markingValue, unescapedCharValue)
|
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx)).replace(markingValue, unescapedCharValue)
|
||||||
|
falsePayload = safeStringFormat(payload, (expressionUnescaped, idx)).replace(markingValue, NULL)
|
||||||
|
|
||||||
|
if timeBasedCompare:
|
||||||
|
if kb.responseTimeMode:
|
||||||
|
kb.responseTimePayload = falsePayload
|
||||||
|
else:
|
||||||
|
kb.responseTimePayload = None
|
||||||
|
|
||||||
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
|
result = Request.queryPage(forgedPayload, timeBasedCompare=timeBasedCompare, raise404=False)
|
||||||
incrementCounter(kb.technique)
|
incrementCounter(kb.technique)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -74,12 +74,15 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
|
||||||
testChar = str(current % 10)
|
testChar = str(current % 10)
|
||||||
testQuery = "SELECT %s('%s',%d)" % ("REPEAT" if Backend.isDbms(DBMS.MYSQL) else "REPLICATE", testChar, current)
|
testQuery = "SELECT %s('%s',%d)" % ("REPEAT" if Backend.isDbms(DBMS.MYSQL) else "REPLICATE", testChar, current)
|
||||||
result = unArrayizeValue(_oneShotErrorUse(testQuery, chunkTest=True))
|
result = unArrayizeValue(_oneShotErrorUse(testQuery, chunkTest=True))
|
||||||
if result and testChar in result:
|
|
||||||
|
if (result or "").startswith(testChar):
|
||||||
if result == testChar * current:
|
if result == testChar * current:
|
||||||
kb.errorChunkLength = current
|
kb.errorChunkLength = current
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
current = len(result) - len(kb.chars.stop)
|
result = re.search(r"\A\w+", result).group(0)
|
||||||
|
candidate = len(result) - len(kb.chars.stop)
|
||||||
|
current = candidate if candidate != current else current - 1
|
||||||
else:
|
else:
|
||||||
current = current / 2
|
current = current / 2
|
||||||
|
|
||||||
|
@ -91,8 +94,8 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
|
||||||
if retVal is None or partialValue:
|
if retVal is None or partialValue:
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
check = "%s(?P<result>.*?)%s" % (kb.chars.start, kb.chars.stop)
|
check = r"%s(?P<result>.*?)%s" % (kb.chars.start, kb.chars.stop)
|
||||||
trimcheck = "%s(?P<result>[^<]*)" % (kb.chars.start)
|
trimcheck = r"%s(?P<result>[^<\n]*)" % (kb.chars.start)
|
||||||
|
|
||||||
if field:
|
if field:
|
||||||
nulledCastedField = agent.nullAndCastField(field)
|
nulledCastedField = agent.nullAndCastField(field)
|
||||||
|
@ -150,7 +153,7 @@ def _oneShotErrorUse(expression, field=None, chunkTest=False):
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
if not kb.testMode:
|
if not kb.testMode:
|
||||||
check = "(?P<result>.*?)%s" % kb.chars.stop[:2]
|
check = r"(?P<result>[^<>\n]*?)%s" % kb.chars.stop[:2]
|
||||||
output = extractRegexResult(check, trimmed, re.IGNORECASE)
|
output = extractRegexResult(check, trimmed, re.IGNORECASE)
|
||||||
|
|
||||||
if not output:
|
if not output:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ from lib.utils.progress import ProgressBar
|
||||||
from thirdparty.odict.odict import OrderedDict
|
from thirdparty.odict.odict import OrderedDict
|
||||||
|
|
||||||
def _oneShotUnionUse(expression, unpack=True, limited=False):
|
def _oneShotUnionUse(expression, unpack=True, limited=False):
|
||||||
retVal = hashDBRetrieve("%s%s" % (conf.hexConvert or False, expression), checkConf=True) # as union data is stored raw unconverted
|
retVal = hashDBRetrieve("%s%s" % (conf.hexConvert or False, expression), checkConf=True) # as UNION data is stored raw unconverted
|
||||||
|
|
||||||
threadData = getCurrentThreadData()
|
threadData = getCurrentThreadData()
|
||||||
threadData.resumed = retVal is not None
|
threadData.resumed = retVal is not None
|
||||||
|
@ -65,7 +65,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
||||||
# Prepare expression with delimiters
|
# Prepare expression with delimiters
|
||||||
injExpression = unescaper.escape(agent.concatQuery(expression, unpack))
|
injExpression = unescaper.escape(agent.concatQuery(expression, unpack))
|
||||||
|
|
||||||
# Forge the union SQL injection request
|
# Forge the UNION SQL injection request
|
||||||
vector = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector
|
vector = kb.injection.data[PAYLOAD.TECHNIQUE.UNION].vector
|
||||||
kb.unionDuplicates = vector[7]
|
kb.unionDuplicates = vector[7]
|
||||||
kb.forcePartialUnion = vector[8]
|
kb.forcePartialUnion = vector[8]
|
||||||
|
@ -78,7 +78,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
||||||
|
|
||||||
incrementCounter(PAYLOAD.TECHNIQUE.UNION)
|
incrementCounter(PAYLOAD.TECHNIQUE.UNION)
|
||||||
|
|
||||||
# Parse the returned page to get the exact union-based
|
# Parse the returned page to get the exact UNION-based
|
||||||
# SQL injection output
|
# SQL injection output
|
||||||
def _(regex):
|
def _(regex):
|
||||||
return reduce(lambda x, y: x if x is not None else y, (\
|
return reduce(lambda x, y: x if x is not None else y, (\
|
||||||
|
@ -98,7 +98,7 @@ def _oneShotUnionUse(expression, unpack=True, limited=False):
|
||||||
if retVal is not None:
|
if retVal is not None:
|
||||||
retVal = getUnicode(retVal, kb.pageEncoding)
|
retVal = getUnicode(retVal, kb.pageEncoding)
|
||||||
|
|
||||||
# Special case when DBMS is Microsoft SQL Server and error message is used as a result of union injection
|
# Special case when DBMS is Microsoft SQL Server and error message is used as a result of UNION injection
|
||||||
if Backend.isDbms(DBMS.MSSQL) and wasLastResponseDBMSError():
|
if Backend.isDbms(DBMS.MSSQL) and wasLastResponseDBMSError():
|
||||||
retVal = htmlunescape(retVal).replace("<br>", "\n")
|
retVal = htmlunescape(retVal).replace("<br>", "\n")
|
||||||
|
|
||||||
|
@ -152,9 +152,9 @@ def configUnion(char=None, columns=None):
|
||||||
|
|
||||||
def unionUse(expression, unpack=True, dump=False):
|
def unionUse(expression, unpack=True, dump=False):
|
||||||
"""
|
"""
|
||||||
This function tests for an union SQL injection on the target
|
This function tests for an UNION SQL injection on the target
|
||||||
URL then call its subsidiary function to effectively perform an
|
URL then call its subsidiary function to effectively perform an
|
||||||
union SQL injection on the affected URL
|
UNION SQL injection on the affected URL
|
||||||
"""
|
"""
|
||||||
|
|
||||||
initTechnique(PAYLOAD.TECHNIQUE.UNION)
|
initTechnique(PAYLOAD.TECHNIQUE.UNION)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ from lib.core.enums import PART_RUN_CONTENT_TYPES
|
||||||
from lib.core.exception import SqlmapConnectionException
|
from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.log import LOGGER_HANDLER
|
from lib.core.log import LOGGER_HANDLER
|
||||||
from lib.core.optiondict import optDict
|
from lib.core.optiondict import optDict
|
||||||
|
from lib.core.settings import RESTAPI_DEFAULT_ADAPTER
|
||||||
from lib.core.settings import IS_WIN
|
from lib.core.settings import IS_WIN
|
||||||
from lib.core.settings import RESTAPI_DEFAULT_ADDRESS
|
from lib.core.settings import RESTAPI_DEFAULT_ADDRESS
|
||||||
from lib.core.settings import RESTAPI_DEFAULT_PORT
|
from lib.core.settings import RESTAPI_DEFAULT_PORT
|
||||||
|
@ -176,9 +177,11 @@ class Task(object):
|
||||||
|
|
||||||
def engine_kill(self):
|
def engine_kill(self):
|
||||||
if self.process:
|
if self.process:
|
||||||
|
try:
|
||||||
self.process.kill()
|
self.process.kill()
|
||||||
return self.process.wait()
|
return self.process.wait()
|
||||||
else:
|
except:
|
||||||
|
pass
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def engine_get_id(self):
|
def engine_get_id(self):
|
||||||
|
@ -390,11 +393,10 @@ def task_flush(taskid):
|
||||||
"""
|
"""
|
||||||
Flush task spool (delete all tasks)
|
Flush task spool (delete all tasks)
|
||||||
"""
|
"""
|
||||||
if is_admin(taskid):
|
|
||||||
DataStore.tasks = dict()
|
|
||||||
else:
|
|
||||||
for key in list(DataStore.tasks):
|
for key in list(DataStore.tasks):
|
||||||
if DataStore.tasks[key].remote_addr == request.remote_addr:
|
if is_admin(taskid) or DataStore.tasks[key].remote_addr == request.remote_addr:
|
||||||
|
DataStore.tasks[key].engine_kill()
|
||||||
del DataStore.tasks[key]
|
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)" % (taskid, "admin" if is_admin(taskid) else request.remote_addr))
|
||||||
|
@ -637,7 +639,7 @@ def download(taskid, target, filename):
|
||||||
return jsonize({"success": False, "message": "File does not exist"})
|
return jsonize({"success": False, "message": "File does not exist"})
|
||||||
|
|
||||||
|
|
||||||
def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT):
|
def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT, adapter=RESTAPI_DEFAULT_ADAPTER):
|
||||||
"""
|
"""
|
||||||
REST-JSON API server
|
REST-JSON API server
|
||||||
"""
|
"""
|
||||||
|
@ -655,13 +657,24 @@ def server(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT):
|
||||||
|
|
||||||
# Run RESTful API
|
# Run RESTful API
|
||||||
try:
|
try:
|
||||||
run(host=host, port=port, quiet=True, debug=False)
|
if adapter == "gevent":
|
||||||
|
from gevent import monkey
|
||||||
|
monkey.patch_all()
|
||||||
|
elif adapter == "eventlet":
|
||||||
|
import eventlet
|
||||||
|
eventlet.monkey_patch()
|
||||||
|
logger.debug("Using adapter '%s' to run bottle" % adapter)
|
||||||
|
run(host=host, port=port, quiet=True, debug=False, server=adapter)
|
||||||
except socket.error, ex:
|
except socket.error, ex:
|
||||||
if "already in use" in getSafeExString(ex):
|
if "already in use" in getSafeExString(ex):
|
||||||
logger.error("Address already in use ('%s:%s')" % (host, port))
|
logger.error("Address already in use ('%s:%s')" % (host, port))
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
except ImportError:
|
||||||
|
errMsg = "Adapter '%s' is not available on this system" % adapter
|
||||||
|
if adapter in ("gevent", "eventlet"):
|
||||||
|
errMsg += " (e.g.: 'sudo apt-get install python-%s')" % adapter
|
||||||
|
logger.critical(errMsg)
|
||||||
|
|
||||||
def _client(url, options=None):
|
def _client(url, options=None):
|
||||||
logger.debug("Calling %s" % url)
|
logger.debug("Calling %s" % url)
|
||||||
|
@ -683,6 +696,14 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT):
|
||||||
"""
|
"""
|
||||||
REST-JSON API client
|
REST-JSON API client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
dbgMsg = "Example client access from command line:"
|
||||||
|
dbgMsg += "\n\t$ taskid=$(curl http://%s:%d/task/new 2>1 | grep -o -I '[a-f0-9]\{16\}') && echo $taskid" % (host, port)
|
||||||
|
dbgMsg += "\n\t$ curl -H \"Content-Type: application/json\" -X POST -d '{\"url\": \"http://testphp.vulnweb.com/artists.php?artist=1\"}' http://%s:%d/scan/$taskid/start" % (host, port)
|
||||||
|
dbgMsg += "\n\t$ curl http://%s:%d/scan/$taskid/data" % (host, port)
|
||||||
|
dbgMsg += "\n\t$ curl http://%s:%d/scan/$taskid/log" % (host, port)
|
||||||
|
logger.debug(dbgMsg)
|
||||||
|
|
||||||
addr = "http://%s:%d" % (host, port)
|
addr = "http://%s:%d" % (host, port)
|
||||||
logger.info("Starting REST-JSON API client to '%s'..." % addr)
|
logger.info("Starting REST-JSON API client to '%s'..." % addr)
|
||||||
|
|
||||||
|
@ -690,7 +711,7 @@ def client(host=RESTAPI_DEFAULT_ADDRESS, port=RESTAPI_DEFAULT_PORT):
|
||||||
_client(addr)
|
_client(addr)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
if not isinstance(ex, urllib2.HTTPError):
|
if not isinstance(ex, urllib2.HTTPError):
|
||||||
errMsg = "there has been a problem while connecting to the "
|
errMsg = "There has been a problem while connecting to the "
|
||||||
errMsg += "REST-JSON API server at '%s' " % addr
|
errMsg += "REST-JSON API server at '%s' " % addr
|
||||||
errMsg += "(%s)" % ex
|
errMsg += "(%s)" % ex
|
||||||
logger.critical(errMsg)
|
logger.critical(errMsg)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Copyright (c) 2006-2015 sqlmap developers (http://sqlmap.org/)
|
Copyright (c) 2006-2016 sqlmap developers (http://sqlmap.org/)
|
||||||
See the file 'doc/COPYING' for copying permission
|
See the file 'doc/COPYING' for copying permission
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user