mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-22 01:26:42 +03:00
Minor enhancemet to support also --regexp, --excl-str and --excl-reg
options rather than only --string when comparing HTTP responses page content
This commit is contained in:
parent
78e8a83c11
commit
38c9627700
|
@ -1,26 +1,34 @@
|
||||||
sqlmap (0.6.3-1) stable; urgency=low
|
sqlmap (0.6.3-1) stable; urgency=low
|
||||||
|
|
||||||
* Major enhancement to support stacked queries when the web application
|
|
||||||
supports it which will be used in the long run by takeover
|
|
||||||
functionality;
|
|
||||||
* Major enhancement to get list of targets to test from Burp proxy
|
* Major enhancement to get list of targets to test from Burp proxy
|
||||||
(http://portswigger.net/suite/) requests log file path or WebScarab
|
(http://portswigger.net/suite/) requests log file path or WebScarab
|
||||||
proxy (http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project)
|
proxy (http://www.owasp.org/index.php/Category:OWASP_WebScarab_Project)
|
||||||
'conversations/' folder path;
|
'conversations/' folder path by providing option -l <filepath>;
|
||||||
|
* Major enhancement to support stacked queries (multiple staatements)
|
||||||
|
when the web application supports them which is useful for time based
|
||||||
|
blind sql injection test and will be used someday also by takeover
|
||||||
|
functionality;
|
||||||
* Minor enhancement to test if the injectable parameter is affected by
|
* Minor enhancement to test if the injectable parameter is affected by
|
||||||
a time based blind SQL injection technique;
|
a time based blind SQL injection technique by providing option
|
||||||
|
--time-test;
|
||||||
* Minor enhancement to fingerprint the web server operating system and
|
* Minor enhancement to fingerprint the web server operating system and
|
||||||
the web application technology by parsing some HTTP response headers;
|
the web application technology by parsing some HTTP response headers;
|
||||||
* Minor enhancement to fingerprint the back-end DBMS operating system by
|
* Minor enhancement to fingerprint the back-end DBMS operating system by
|
||||||
parsing the DBMS banner value when -b option is provided;
|
parsing the DBMS banner value when -b option is provided;
|
||||||
* Minor enhancement to be able to specify the number of seconds before
|
* Minor enhancement to be able to specify the number of seconds before
|
||||||
timeout the connection, default is set to 10 seconds;
|
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
|
* Minor enhancement to be able to specify the number of seconds to wait
|
||||||
between each HTTP request providing option --delay #;
|
between each HTTP request by providing option --delay #;
|
||||||
* Minor enhancement to be able to enumerate table columns and dump table
|
* Minor enhancement to be able to enumerate table columns and dump table
|
||||||
entries, also when the database name is not provided, by using the
|
entries, also when the database name is not provided, by using the
|
||||||
current database on MySQL and Microsoft SQL Server, the 'public'
|
current database on MySQL and Microsoft SQL Server, the 'public'
|
||||||
scheme on PostgreSQL and the 'USERS' TABLESPACE_NAME on Oracle;
|
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 improvement to be able to provide CU as user value (-U) when
|
||||||
|
enumerating users privileges or users passwords;
|
||||||
* Minor improvement to set by default in all HTTP requests the standard
|
* Minor improvement to set by default in all HTTP requests the standard
|
||||||
client HTTP headers (Accept, Accept-Encoding, etc);
|
client HTTP headers (Accept, Accept-Encoding, etc);
|
||||||
* Minor improvements to sqlmap Debian package files: sqlmap uploaded
|
* Minor improvements to sqlmap Debian package files: sqlmap uploaded
|
||||||
|
|
|
@ -5,6 +5,9 @@ Chip Andrews <chip@sqlsecurity.com>
|
||||||
at SQLSecurity.com and permission to implement the update feature
|
at SQLSecurity.com and permission to implement the update feature
|
||||||
taking data from his site
|
taking data from his site
|
||||||
|
|
||||||
|
Jack Butler <fattredd@hotmail.com>
|
||||||
|
for providing me with the sqlmap site favicon
|
||||||
|
|
||||||
Karl Chen <quarl@cs.berkeley.edu>
|
Karl Chen <quarl@cs.berkeley.edu>
|
||||||
for providing with the multithreading patch for the inference
|
for providing with the multithreading patch for the inference
|
||||||
algorithm
|
algorithm
|
||||||
|
|
|
@ -49,8 +49,11 @@ optDict = {
|
||||||
|
|
||||||
"Injection": {
|
"Injection": {
|
||||||
"testParameter": "string",
|
"testParameter": "string",
|
||||||
"string": "string",
|
|
||||||
"dbms": "string",
|
"dbms": "string",
|
||||||
|
"string": "string",
|
||||||
|
"regexp": "string",
|
||||||
|
"eString": "string",
|
||||||
|
"eRegexp": "string",
|
||||||
},
|
},
|
||||||
|
|
||||||
"Techniques": {
|
"Techniques": {
|
||||||
|
|
|
@ -53,7 +53,7 @@ def __updateMSSQLXML():
|
||||||
logger.info(infoMsg)
|
logger.info(infoMsg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mssqlVersionsHtmlString = Request.getPage(url=MSSQL_VERSIONS_URL, direct=True)
|
mssqlVersionsHtmlString, _ = Request.getPage(url=MSSQL_VERSIONS_URL, direct=True)
|
||||||
except sqlmapConnectionException, _:
|
except sqlmapConnectionException, _:
|
||||||
__mssqlPath = urlparse.urlsplit(MSSQL_VERSIONS_URL)
|
__mssqlPath = urlparse.urlsplit(MSSQL_VERSIONS_URL)
|
||||||
__mssqlHostname = __mssqlPath[1]
|
__mssqlHostname = __mssqlPath[1]
|
||||||
|
@ -231,7 +231,7 @@ def __updateSqlmap():
|
||||||
logger.debug(debugMsg)
|
logger.debug(debugMsg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sqlmapNewestVersion = Request.getPage(url=SQLMAP_VERSION_URL, direct=True)
|
sqlmapNewestVersion, _ = Request.getPage(url=SQLMAP_VERSION_URL, direct=True)
|
||||||
except sqlmapConnectionException, _:
|
except sqlmapConnectionException, _:
|
||||||
__sqlmapPath = urlparse.urlsplit(SQLMAP_VERSION_URL)
|
__sqlmapPath = urlparse.urlsplit(SQLMAP_VERSION_URL)
|
||||||
__sqlmapHostname = __sqlmapPath[1]
|
__sqlmapHostname = __sqlmapPath[1]
|
||||||
|
@ -271,7 +271,7 @@ def __updateSqlmap():
|
||||||
sqlmapBinaryStringUrl = SQLMAP_SOURCE_URL % sqlmapNewestVersion
|
sqlmapBinaryStringUrl = SQLMAP_SOURCE_URL % sqlmapNewestVersion
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sqlmapBinaryString = Request.getPage(url=sqlmapBinaryStringUrl, direct=True)
|
sqlmapBinaryString, _ = Request.getPage(url=sqlmapBinaryStringUrl, direct=True)
|
||||||
except sqlmapConnectionException, _:
|
except sqlmapConnectionException, _:
|
||||||
__sqlmapPath = urlparse.urlsplit(sqlmapBinaryStringUrl)
|
__sqlmapPath = urlparse.urlsplit(sqlmapBinaryStringUrl)
|
||||||
__sqlmapHostname = __sqlmapPath[1]
|
__sqlmapHostname = __sqlmapPath[1]
|
||||||
|
|
|
@ -109,12 +109,24 @@ def cmdLineParser():
|
||||||
injection.add_option("-p", dest="testParameter",
|
injection.add_option("-p", dest="testParameter",
|
||||||
help="Testable parameter(s)")
|
help="Testable parameter(s)")
|
||||||
|
|
||||||
|
injection.add_option("--dbms", dest="dbms",
|
||||||
|
help="Force back-end DBMS to this value")
|
||||||
|
|
||||||
injection.add_option("--string", dest="string",
|
injection.add_option("--string", dest="string",
|
||||||
help="String to match in page when the "
|
help="String to match in page when the "
|
||||||
"query is valid")
|
"query is valid")
|
||||||
|
|
||||||
injection.add_option("--dbms", dest="dbms",
|
injection.add_option("--regexp", dest="regexp",
|
||||||
help="Force back-end DBMS to this value")
|
help="Regexp to match in page when the "
|
||||||
|
"query is valid")
|
||||||
|
|
||||||
|
injection.add_option("--excl-str", dest="eString",
|
||||||
|
help="String to be excluded before calculating "
|
||||||
|
"page hash")
|
||||||
|
|
||||||
|
injection.add_option("--excl-reg", dest="eRegexp",
|
||||||
|
help="Regexp matches to be excluded before "
|
||||||
|
"calculating page hash")
|
||||||
|
|
||||||
# Techniques options
|
# Techniques options
|
||||||
techniques = OptionGroup(parser, "Techniques", "These options can "
|
techniques = OptionGroup(parser, "Techniques", "These options can "
|
||||||
|
|
69
lib/request/comparison.py
Normal file
69
lib/request/comparison.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
$Id$
|
||||||
|
|
||||||
|
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||||
|
|
||||||
|
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||||
|
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||||
|
|
||||||
|
sqlmap is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU General Public License as published by the Free
|
||||||
|
Software Foundation version 2 of the License.
|
||||||
|
|
||||||
|
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||||
|
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import md5
|
||||||
|
import re
|
||||||
|
|
||||||
|
from lib.core.data import conf
|
||||||
|
from lib.core.data import kb
|
||||||
|
from lib.core.data import logger
|
||||||
|
|
||||||
|
|
||||||
|
def comparison(page, headers=None, content=False):
|
||||||
|
regExpResults = None
|
||||||
|
|
||||||
|
if conf.eString and conf.eString in page:
|
||||||
|
index = page.index(conf.eString)
|
||||||
|
length = len(conf.eString)
|
||||||
|
pageWithoutString = page[:index]
|
||||||
|
pageWithoutString += page[index+length:]
|
||||||
|
page = pageWithoutString
|
||||||
|
|
||||||
|
if conf.eRegexp:
|
||||||
|
regExpResults = re.findall(conf.eRegexp, page, re.I | re.M)
|
||||||
|
|
||||||
|
if conf.eRegexp and regExpResults:
|
||||||
|
for regExpResult in regExpResults:
|
||||||
|
index = page.index(regExpResult)
|
||||||
|
length = len(regExpResult)
|
||||||
|
pageWithoutRegExp = page[:index]
|
||||||
|
pageWithoutRegExp += page[index+length:]
|
||||||
|
page = pageWithoutRegExp
|
||||||
|
|
||||||
|
if conf.string:
|
||||||
|
if conf.string in page:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif conf.regexp:
|
||||||
|
if re.search(conf.regexp, page, re.I | re.M):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
else:
|
||||||
|
return md5.new(page).hexdigest()
|
|
@ -42,7 +42,7 @@ from lib.core.exception import sqlmapConnectionException
|
||||||
from lib.core.settings import RETRIES
|
from lib.core.settings import RETRIES
|
||||||
from lib.request.basic import forgeHeaders
|
from lib.request.basic import forgeHeaders
|
||||||
from lib.request.basic import parseResponse
|
from lib.request.basic import parseResponse
|
||||||
|
from lib.request.comparison import comparison
|
||||||
|
|
||||||
|
|
||||||
class Connect:
|
class Connect:
|
||||||
|
@ -190,15 +190,15 @@ class Connect:
|
||||||
warnMsg += "status code, try to force the HTTP User-Agent "
|
warnMsg += "status code, try to force the HTTP User-Agent "
|
||||||
warnMsg += "header with option --user-agent or -a"
|
warnMsg += "header with option --user-agent or -a"
|
||||||
|
|
||||||
|
if "BadStatusLine" not in tbMsg:
|
||||||
|
warnMsg += " or proxy"
|
||||||
|
|
||||||
if conf.multipleTargets:
|
if conf.multipleTargets:
|
||||||
warnMsg += ", skipping to next url"
|
warnMsg += ", skipping to next url"
|
||||||
logger.warn(warnMsg)
|
logger.warn(warnMsg)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if "BadStatusLine" not in tbMsg:
|
|
||||||
warnMsg += " or proxy"
|
|
||||||
|
|
||||||
if conf.retries < RETRIES:
|
if conf.retries < RETRIES:
|
||||||
conf.retries += 1
|
conf.retries += 1
|
||||||
|
|
||||||
|
@ -207,6 +207,7 @@ class Connect:
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
return Connect.__getPageProxy(get=get, post=post, cookie=cookie, ua=ua, direct=direct, multipart=multipart)
|
return Connect.__getPageProxy(get=get, post=post, cookie=cookie, ua=ua, direct=direct, multipart=multipart)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise sqlmapConnectionException, warnMsg
|
raise sqlmapConnectionException, warnMsg
|
||||||
|
|
||||||
|
@ -220,7 +221,7 @@ class Connect:
|
||||||
|
|
||||||
logger.log(8, responseMsg)
|
logger.log(8, responseMsg)
|
||||||
|
|
||||||
return page
|
return page, responseHeaders
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -263,15 +264,9 @@ class Connect:
|
||||||
else:
|
else:
|
||||||
ua = conf.parameters["User-Agent"]
|
ua = conf.parameters["User-Agent"]
|
||||||
|
|
||||||
page = Connect.getPage(get=get, post=post, cookie=cookie, ua=ua)
|
page, headers = Connect.getPage(get=get, post=post, cookie=cookie, ua=ua)
|
||||||
|
|
||||||
# TODO: create a comparison library and move these checks there
|
|
||||||
if content:
|
if content:
|
||||||
return page
|
return page
|
||||||
elif conf.string:
|
|
||||||
if conf.string in page:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
else:
|
else:
|
||||||
return md5.new(page).hexdigest()
|
return comparison(page, headers, content)
|
||||||
|
|
|
@ -450,7 +450,7 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||||
|
|
||||||
baseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
|
baseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
|
||||||
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
|
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
|
||||||
page = Request.getPage(url=uploaderUrl, direct=True)
|
page, _ = Request.getPage(url=uploaderUrl, direct=True)
|
||||||
|
|
||||||
if "sqlmap backdoor uploader" not in page:
|
if "sqlmap backdoor uploader" not in page:
|
||||||
warnMsg = "unable to upload the uploader "
|
warnMsg = "unable to upload the uploader "
|
||||||
|
@ -470,7 +470,7 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||||
"uploadDir": directory,
|
"uploadDir": directory,
|
||||||
}
|
}
|
||||||
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
|
uploaderUrl = "%s/%s" % (baseUrl, uploaderName)
|
||||||
page = Request.getPage(url=uploaderUrl, multipart=multipartParams)
|
page, _ = Request.getPage(url=uploaderUrl, multipart=multipartParams)
|
||||||
|
|
||||||
if "Backdoor uploaded" not in page:
|
if "Backdoor uploaded" not in page:
|
||||||
warnMsg = "unable to upload the backdoor through "
|
warnMsg = "unable to upload the backdoor through "
|
||||||
|
@ -522,7 +522,7 @@ class MySQLMap(Fingerprint, Enumeration, Filesystem, Takeover):
|
||||||
break
|
break
|
||||||
|
|
||||||
cmdUrl = "%s?cmd=%s" % (backdoorUrl, command)
|
cmdUrl = "%s?cmd=%s" % (backdoorUrl, command)
|
||||||
page = Request.getPage(url=cmdUrl, direct=True)
|
page, _ = Request.getPage(url=cmdUrl, direct=True)
|
||||||
output = re.search("<pre>(.+?)</pre>", page, re.I | re.S)
|
output = re.search("<pre>(.+?)</pre>", page, re.I | re.S)
|
||||||
|
|
||||||
if output:
|
if output:
|
||||||
|
|
33
sqlmap.conf
33
sqlmap.conf
|
@ -99,19 +99,38 @@ timeout = 10
|
||||||
# parameters and HTTP User-Agent are tested by sqlmap.
|
# parameters and HTTP User-Agent are tested by sqlmap.
|
||||||
testParameter =
|
testParameter =
|
||||||
|
|
||||||
# String to match in page when the query is valid, only needed if the
|
|
||||||
# page content dynamically changes at each refresh, consequently changing
|
|
||||||
# the MD5 of the page which is the method used by default to determine
|
|
||||||
# if a query was valid or not. Read the documentation for further
|
|
||||||
# details.
|
|
||||||
string =
|
|
||||||
|
|
||||||
# Force back-end DBMS to this value. If this option is set, the back-end
|
# Force back-end DBMS to this value. If this option is set, the back-end
|
||||||
# DBMS identification process will be minimized as needed.
|
# DBMS identification process will be minimized as needed.
|
||||||
# If not set, sqlmap will detect back-end DBMS automatically by default.
|
# If not set, sqlmap will detect back-end DBMS automatically by default.
|
||||||
# Valid: mssql, mysql, mysql 4, mysql 5, oracle, pgsql
|
# Valid: mssql, mysql, mysql 4, mysql 5, oracle, pgsql
|
||||||
dbms =
|
dbms =
|
||||||
|
|
||||||
|
# String to match within the page content when the query is valid, only
|
||||||
|
# needed if the page content dynamically changes at each refresh,
|
||||||
|
# consequently changing the MD5 hash of the page which is the method used
|
||||||
|
# by default to determine if a query was valid or not. Refer to the user's
|
||||||
|
# manual for further details.
|
||||||
|
string =
|
||||||
|
|
||||||
|
# Regular expression to match within the page content when the query is
|
||||||
|
# valid, only needed if the needed if the page content dynamically changes
|
||||||
|
# at each refresh, consequently changing the MD5 hash of the page which is
|
||||||
|
# the method used by default to determine if a query was valid or not.
|
||||||
|
# Refer to the user's manual for further details.
|
||||||
|
# Valid: regular expression with Python syntax
|
||||||
|
# (http://www.python.org/doc/2.5.2/lib/re-syntax.html)
|
||||||
|
regexp =
|
||||||
|
|
||||||
|
# String to be excluded by the page content before calculating the page
|
||||||
|
# MD5 hash
|
||||||
|
eString =
|
||||||
|
|
||||||
|
# Regular expression matches to be excluded by the page content before
|
||||||
|
# calculating the page MD5 hash
|
||||||
|
# Valid: regular expression with Python syntax
|
||||||
|
# (http://www.python.org/doc/2.5.2/lib/re-syntax.html)
|
||||||
|
eRegexp =
|
||||||
|
|
||||||
|
|
||||||
[Techniques]
|
[Techniques]
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user