Merge remote-tracking branch 'sqlmapproject/master'

This commit is contained in:
cxh852456 2016-02-18 23:49:52 +08:00
commit a51645f783
308 changed files with 943 additions and 655 deletions

View File

@ -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;

View File

@ -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

View 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
""" """

View 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
""" """

View File

@ -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
""" """

View 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
""" """

View File

@ -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
""" """

View 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
""" """

View File

@ -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
""" """

View 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
""" """

View 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
""" """

View File

@ -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
""" """

View 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
# Removes duplicate entries in wordlist like files # Removes duplicate entries in wordlist like files

0
extra/shutils/pyflakes.sh Normal file → Executable file
View File

2
extra/shutils/regressiontest.py Executable file → Normal file
View 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

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """
@ -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 "

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """
@ -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

View 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
""" """

23
lib/core/common.py Executable file → Normal file
View 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

View File

@ -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 = (('&lt;', '<'), ('&gt;', '>'), ('&quot;', '"'), ('&nbsp;', ' '), ('&amp;', '&')) codes = (('&lt;', '<'), ('&gt;', '>'), ('&quot;', '"'), ('&nbsp;', ' '), ('&amp;', '&'))
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

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """
@ -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 = {

View 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
""" """
@ -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()))

View 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
""" """
@ -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"

View 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
""" """

View 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
""" """

View 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
""" """
@ -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:

View 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
""" """

View 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
""" """
@ -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

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """
@ -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"

View 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
""" """

View 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
""" """

View 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
""" """
@ -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)

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View File

@ -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:

View 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
""" """

View 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
""" """

View 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
""" """
@ -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))

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

2
lib/request/basic.py Executable file → Normal file
View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """
@ -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)

View 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
""" """

View 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
""" """
@ -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

View 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
""" """

View 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
""" """
@ -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()

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View File

@ -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)

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """

View 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
""" """
@ -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:

View 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
""" """

View 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
""" """

View 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
""" """
@ -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)

View 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
""" """

View File

@ -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)

View 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
""" """

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