diff --git a/extra/safe2bin/safe2bin.py b/extra/safe2bin/safe2bin.py
index 9efc81bda..478592225 100644
--- a/extra/safe2bin/safe2bin.py
+++ b/extra/safe2bin/safe2bin.py
@@ -64,7 +64,9 @@ def safecharencode(value):
for char in SAFE_ENCODE_SLASH_REPLACEMENTS:
retVal = retVal.replace(char, repr(char).strip('\''))
- retVal = reduce(lambda x, y: x + (y if (y in string.printable or isinstance(value, text_type) and ord(y) >= 160) else '\\x%02x' % ord(y)), retVal, type(value)())
+ for char in set(retVal):
+ if not (char in string.printable or isinstance(value, text_type) and ord(char) >= 160):
+ retVal = retVal.replace(char, '\\x%02x' % ord(char))
retVal = retVal.replace(SLASH_MARKER, "\\\\")
retVal = retVal.replace(HEX_ENCODED_PREFIX_MARKER, HEX_ENCODED_PREFIX)
diff --git a/lib/controller/checks.py b/lib/controller/checks.py
index cd912cec2..b66f35cab 100644
--- a/lib/controller/checks.py
+++ b/lib/controller/checks.py
@@ -1377,7 +1377,7 @@ def checkWaf():
conf.timeout = IDS_WAF_CHECK_TIMEOUT
try:
- retVal = Request.queryPage(place=place, value=value, getRatioValue=True, noteResponseTime=False, silent=True, disableTampering=True)[1] < IDS_WAF_CHECK_RATIO
+ retVal = (Request.queryPage(place=place, value=value, getRatioValue=True, noteResponseTime=False, silent=True, disableTampering=True)[1] or 0) < IDS_WAF_CHECK_RATIO
except SqlmapConnectionException:
retVal = True
finally:
diff --git a/lib/core/common.py b/lib/core/common.py
index ba69a3e26..7a111d803 100644
--- a/lib/core/common.py
+++ b/lib/core/common.py
@@ -11,6 +11,7 @@ import collections
import contextlib
import copy
import distutils
+import functools
import getpass
import hashlib
import inspect
@@ -1849,7 +1850,7 @@ def safeFilepathEncode(filepath):
retVal = filepath
- if filepath and isinstance(filepath, six.text_type):
+ if filepath and six.PY2 and isinstance(filepath, six.text_type):
retVal = filepath.encode(sys.getfilesystemencoding() or UNICODE_ENCODING)
return retVal
@@ -1929,8 +1930,8 @@ def getFilteredPageContent(page, onlyText=True, split=" "):
Returns filtered page content without script, style and/or comments
or all HTML tags
- >>> getFilteredPageContent(u'
foobartest')
- u'foobar test'
+ >>> getFilteredPageContent(u'foobartest') == "foobar test"
+ True
"""
retVal = page
@@ -1947,8 +1948,8 @@ def getPageWordSet(page):
"""
Returns word set used in page content
- >>> sorted(getPageWordSet(u'foobartest'))
- [u'foobar', u'test']
+ >>> sorted(getPageWordSet(u'foobartest')) == [u'foobar', u'test']
+ True
"""
retVal = set()
@@ -2459,13 +2460,13 @@ def decodeHex(value):
True
"""
- return bytes.fromhex(value) if hasattr(bytes, "fromhex") else value.decode("hex")
+ return bytes.fromhex(getUnicode(value)) if hasattr(bytes, "fromhex") else value.decode("hex")
def getBytes(value, encoding=UNICODE_ENCODING, errors="strict"):
"""
Returns byte representation of provided Unicode value
- >>> getBytes(getUnicode("foo\x01\x83\xffbar")) == b"foo\x01\x83\xffbar"
+ >>> getBytes(getUnicode(b"foo\\x01\\x83\\xffbar")) == b"foo\\x01\\x83\\xffbar"
True
"""
@@ -2488,9 +2489,9 @@ def getOrds(value):
"""
Returns ORD(...) representation of provided string value
- >>> getOrds(u'fo\xf6bar')
+ >>> getOrds(u'fo\\xf6bar')
[102, 111, 246, 98, 97, 114]
- >>> getOrds(b"fo\xc3\xb6bar")
+ >>> getOrds(b"fo\\xc3\\xb6bar")
[102, 111, 195, 182, 98, 97, 114]
"""
@@ -2642,8 +2643,8 @@ def extractErrorMessage(page):
"""
Returns reported error message from page if it founds one
- >>> extractErrorMessage(u'Test\\nWarning: oci_parse() [function.oci-parse]: ORA-01756: quoted string not properly terminated
Only a test page
')
- u'oci_parse() [function.oci-parse]: ORA-01756: quoted string not properly terminated'
+ >>> extractErrorMessage(u'Test\\nWarning: oci_parse() [function.oci-parse]: ORA-01756: quoted string not properly terminated
Only a test page
') == u'oci_parse() [function.oci-parse]: ORA-01756: quoted string not properly terminated'
+ True
"""
retVal = None
@@ -2716,10 +2717,10 @@ def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CH
"""
URL decodes given value
- >>> urldecode('AND%201%3E%282%2B3%29%23', convall=True)
- u'AND 1>(2+3)#'
- >>> urldecode('AND%201%3E%282%2B3%29%23', convall=False)
- u'AND 1>(2%2B3)#'
+ >>> urldecode('AND%201%3E%282%2B3%29%23', convall=True) == 'AND 1>(2+3)#'
+ True
+ >>> urldecode('AND%201%3E%282%2B3%29%23', convall=False) == 'AND 1>(2%2B3)#'
+ True
"""
result = value
@@ -2738,7 +2739,7 @@ def urldecode(value, encoding=None, unsafe="%%&=;+%s" % CUSTOM_INJECTION_MARK_CH
charset = set(string.printable) - set(unsafe)
def _(match):
- char = chr(ord(match.group(1).decode("hex")))
+ char = getUnicode(decodeHex(match.group(1)))
return char if char in charset else match.group(0)
if spaceplus:
@@ -3020,13 +3021,15 @@ def findDynamicContent(firstPage, secondPage):
prefix = prefix[-DYNAMICITY_BOUNDARY_LENGTH:]
suffix = suffix[:DYNAMICITY_BOUNDARY_LENGTH]
- infix = max(re.search(r"(?s)%s(.+)%s" % (re.escape(prefix), re.escape(suffix)), _) for _ in (firstPage, secondPage)).group(1)
-
- if infix[0].isalnum():
- prefix = trimAlphaNum(prefix)
-
- if infix[-1].isalnum():
- suffix = trimAlphaNum(suffix)
+ for _ in (firstPage, secondPage):
+ match = re.search(r"(?s)%s(.+)%s" % (re.escape(prefix), re.escape(suffix)), _)
+ if match:
+ infix = match.group(1)
+ if infix[0].isalnum():
+ prefix = trimAlphaNum(prefix)
+ if infix[-1].isalnum():
+ suffix = trimAlphaNum(suffix)
+ break
kb.dynamicMarkings.append((prefix if prefix else None, suffix if suffix else None))
@@ -3557,7 +3560,7 @@ def getLatestRevision():
req = _urllib.request.Request(url="https://raw.githubusercontent.com/sqlmapproject/sqlmap/master/lib/core/settings.py")
try:
- content = _urllib.request.urlopen(req).read()
+ content = getUnicode(_urllib.request.urlopen(req).read())
retVal = extractRegexResult(r"VERSION\s*=\s*[\"'](?P[\d.]+)", content)
except:
pass
@@ -4423,12 +4426,8 @@ def serializeObject(object_):
"""
Serializes given object
- >>> serializeObject([1, 2, 3, ('a', 'b')])
- 'gAJdcQEoSwFLAksDVQFhVQFihnECZS4='
- >>> serializeObject(None)
- 'gAJOLg=='
- >>> serializeObject('foobar')
- 'gAJVBmZvb2JhcnEBLg=='
+ >>> type(serializeObject([1, 2, 3, ('a', 'b')])) == six.binary_type
+ True
"""
return base64pickle(object_)
@@ -4668,7 +4667,10 @@ def prioritySortColumns(columns):
def _(column):
return column and "id" in column.lower()
- return sorted(sorted(columns, key=len), lambda x, y: -1 if _(x) and not _(y) else 1 if not _(x) and _(y) else 0)
+ if six.PY2:
+ return sorted(sorted(columns, key=len), lambda x, y: -1 if _(x) and not _(y) else 1 if not _(x) and _(y) else 0)
+ else:
+ return sorted(sorted(columns, key=len), key=functools.cmp_to_key(lambda x, y: -1 if _(x) and not _(y) else 1 if not _(x) and _(y) else 0))
def getRequestHeader(request, name):
"""
@@ -4975,12 +4977,12 @@ def safeVariableNaming(value):
"""
Returns escaped safe-representation of a given variable name that can be used in Python evaluated code
- >>> safeVariableNaming("class.id")
- 'EVAL_636c6173732e6964'
+ >>> safeVariableNaming("class.id") == "EVAL_636c6173732e6964"
+ True
"""
if value in keyword.kwlist or re.search(r"\A[^a-zA-Z]|[^\w]", value):
- value = "%s%s" % (EVALCODE_ENCODED_PREFIX, value.encode(UNICODE_ENCODING).encode("hex"))
+ value = "%s%s" % (EVALCODE_ENCODED_PREFIX, getUnicode(binascii.hexlify(getBytes(value))))
return value
@@ -4988,12 +4990,12 @@ def unsafeVariableNaming(value):
"""
Returns unescaped safe-representation of a given variable name
- >>> unsafeVariableNaming("EVAL_636c6173732e6964")
- u'class.id'
+ >>> unsafeVariableNaming("EVAL_636c6173732e6964") == "class.id"
+ True
"""
if value.startswith(EVALCODE_ENCODED_PREFIX):
- value = value[len(EVALCODE_ENCODED_PREFIX):].decode("hex").decode(UNICODE_ENCODING)
+ value = getUnicode(decodeHex(value[len(EVALCODE_ENCODED_PREFIX):]))
return value
diff --git a/lib/core/compat.py b/lib/core/compat.py
index 0cb669f81..850d86bbc 100644
--- a/lib/core/compat.py
+++ b/lib/core/compat.py
@@ -162,6 +162,10 @@ class WichmannHill(random.Random):
z = (z + a) % 256 or 1
self.__whseed(x, y, z)
+def patchHeaders(headers):
+ if not hasattr(headers, "headers"):
+ headers.headers = ["%s: %s\r\n" % (header, headers[header]) for header in headers]
+
# Reference: https://github.com/urllib3/urllib3/blob/master/src/urllib3/filepost.py
def choose_boundary():
return uuid.uuid4().hex
diff --git a/lib/core/convert.py b/lib/core/convert.py
index f847f3afa..08fee210c 100644
--- a/lib/core/convert.py
+++ b/lib/core/convert.py
@@ -11,6 +11,7 @@ except:
import pickle
import base64
+import binascii
import json
import re
import sys
@@ -24,8 +25,8 @@ def base64decode(value):
"""
Decodes string value from Base64 to plain format
- >>> base64decode('Zm9vYmFy')
- 'foobar'
+ >>> base64decode('Zm9vYmFy') == b'foobar'
+ True
"""
return base64.b64decode(unicodeencode(value))
@@ -34,8 +35,8 @@ def base64encode(value):
"""
Encodes string value from plain to Base64 format
- >>> base64encode('foobar')
- 'Zm9vYmFy'
+ >>> base64encode('foobar') == b'Zm9vYmFy'
+ True
"""
return base64.b64encode(unicodeencode(value))
@@ -44,8 +45,8 @@ def base64pickle(value):
"""
Serializes (with pickle) and encodes to Base64 format supplied (binary) value
- >>> base64pickle('foobar')
- 'gAJVBmZvb2JhcnEBLg=='
+ >>> base64unpickle(base64pickle([1, 2, 3])) == [1, 2, 3]
+ True
"""
retVal = None
@@ -68,8 +69,8 @@ def base64unpickle(value):
"""
Decodes value from Base64 to plain format and deserializes (with pickle) its content
- >>> base64unpickle('gAJVBmZvb2JhcnEBLg==')
- 'foobar'
+ >>> type(base64unpickle('gAJjX19idWlsdGluX18Kb2JqZWN0CnEBKYFxAi4=')) == object
+ True
"""
retVal = None
@@ -85,8 +86,8 @@ def hexdecode(value):
"""
Decodes string value from hex to plain format
- >>> hexdecode('666f6f626172')
- 'foobar'
+ >>> hexdecode('666f6f626172') == b'foobar'
+ True
"""
value = value.lower()
@@ -103,16 +104,12 @@ def hexencode(value, encoding=None):
"""
Encodes string value from plain to hex format
- >>> hexencode('foobar')
- '666f6f626172'
+ >>> hexencode('foobar') == b'666f6f626172'
+ True
"""
retVal = unicodeencode(value, encoding)
-
- if six.PY2:
- retVal = retVal.encode("hex")
- else:
- retVal = retVal.hex()
+ retVal = binascii.hexlify(retVal)
return retVal
@@ -120,8 +117,8 @@ def unicodeencode(value, encoding=None):
"""
Returns 8-bit string representation of the supplied unicode value
- >>> unicodeencode(u'foobar')
- 'foobar'
+ >>> unicodeencode(u'foobar') == b'foobar'
+ True
"""
retVal = value
@@ -138,8 +135,8 @@ def utf8encode(value):
"""
Returns 8-bit string representation of the supplied UTF-8 value
- >>> utf8encode(u'foobar')
- 'foobar'
+ >>> utf8encode(u'foobar') == b'foobar'
+ True
"""
return unicodeencode(value, "utf-8")
@@ -148,11 +145,16 @@ def utf8decode(value):
"""
Returns UTF-8 representation of the supplied 8-bit string representation
- >>> utf8decode('foobar')
+ >>> utf8decode(b'foobar')
u'foobar'
"""
- return value.decode("utf-8")
+ retVal = value
+
+ if isinstance(value, six.binary_type):
+ retVal = value.decode("utf-8")
+
+ return retVal
def htmlunescape(value):
"""
@@ -217,8 +219,8 @@ def dejsonize(data):
"""
Returns JSON deserialized data
- >>> dejsonize('{\\n "foo": "bar"\\n}')
- {u'foo': u'bar'}
+ >>> dejsonize('{\\n "foo": "bar"\\n}') == {u'foo': u'bar'}
+ True
"""
return json.loads(data)
diff --git a/lib/core/option.py b/lib/core/option.py
index 1c53c07d3..c694fb4ec 100644
--- a/lib/core/option.py
+++ b/lib/core/option.py
@@ -1765,7 +1765,8 @@ def _cleanupOptions():
conf.string = decodeStringEscape(conf.string)
if conf.getAll:
- map(lambda _: conf.__setitem__(_, True), WIZARD.ALL)
+ for _ in WIZARD.ALL:
+ conf.__setitem__(_, True)
if conf.noCast:
for _ in list(DUMP_REPLACEMENTS.keys()):
diff --git a/lib/core/settings.py b/lib/core/settings.py
index 10cbbdf5f..117dc21b9 100644
--- a/lib/core/settings.py
+++ b/lib/core/settings.py
@@ -17,7 +17,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
from lib.core.enums import OS
# sqlmap version (...)
-VERSION = "1.3.5.3"
+VERSION = "1.3.5.4"
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)
@@ -839,8 +839,8 @@ for key, value in os.environ.items():
def _reversible(ex):
if isinstance(ex, UnicodeDecodeError):
if INVALID_UNICODE_PRIVATE_AREA:
- return ("".join(unichr(int('000f00%2x' % ord(_), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
+ return (u"".join(unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end)
else:
- return ("".join(INVALID_UNICODE_CHAR_FORMAT % ord(_) for _ in ex.object[ex.start:ex.end]).decode(UNICODE_ENCODING), ex.end)
+ return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end)
codecs.register_error("reversible", _reversible)
diff --git a/lib/request/connect.py b/lib/request/connect.py
index d6a88ed01..b1f8a9ef3 100644
--- a/lib/request/connect.py
+++ b/lib/request/connect.py
@@ -58,6 +58,7 @@ from lib.core.common import wasLastResponseDelayed
from lib.core.common import unsafeVariableNaming
from lib.core.common import urldecode
from lib.core.common import urlencode
+from lib.core.compat import patchHeaders
from lib.core.compat import xrange
from lib.core.data import conf
from lib.core.data import kb
@@ -517,6 +518,7 @@ class Connect(object):
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()
+ patchHeaders(responseHeaders)
kb.serverHeader = responseHeaders.get(HTTP_HEADER.SERVER, kb.serverHeader)
else:
code = None
@@ -592,6 +594,7 @@ class Connect(object):
page = ex.read() if not skipRead else None
responseHeaders = ex.info()
responseHeaders[URI_HTTP_HEADER] = ex.geturl()
+ patchHeaders(responseHeaders)
page = decodePage(page, responseHeaders.get(HTTP_HEADER.CONTENT_ENCODING), responseHeaders.get(HTTP_HEADER.CONTENT_TYPE))
except socket.timeout:
warnMsg = "connection timed out while trying "
@@ -1349,8 +1352,7 @@ class Connect(object):
kb.permissionFlag = True
singleTimeWarnMessage("potential permission problems detected ('%s')" % message)
- if not hasattr(headers, "headers"):
- headers.headers = ["%s: %s\r\n" % (header, headers[header]) for header in headers]
+ patchHeaders(headers)
if content or response:
return page, headers, code
diff --git a/lib/techniques/blind/inference.py b/lib/techniques/blind/inference.py
index 8355b5af1..87fcf8e9b 100644
--- a/lib/techniques/blind/inference.py
+++ b/lib/techniques/blind/inference.py
@@ -158,7 +158,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
length = None
showEta = conf.eta and isinstance(length, int)
- numThreads = min(conf.threads, length) or 1
+ numThreads = min(conf.threads or 0, length or 0) or 1
if showEta:
progress = ProgressBar(maxValue=length)
@@ -198,8 +198,10 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
else:
posValue = ord(hintValue[idx - 1])
+ markingValue = "'%s'" % CHAR_INFERENCE_MARK
+ unescapedCharValue = unescaper.escape("'%s'" % decodeIntToUnicode(posValue))
forgedPayload = agent.extractPayload(payload)
- forgedPayload = safeStringFormat(forgedPayload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, posValue))
+ forgedPayload = safeStringFormat(forgedPayload.replace(INFERENCE_GREATER_CHAR, INFERENCE_EQUALS_CHAR), (expressionUnescaped, idx, posValue)).replace(markingValue, unescapedCharValue)
result = Request.queryPage(agent.replacePayload(payload, forgedPayload), timeBasedCompare=timeBasedCompare, raise404=False)
incrementCounter(kb.technique)
@@ -293,12 +295,13 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
lastChar = [_ for _ in threadData.shared.value if _ is not None][-1]
except IndexError:
lastChar = None
- if 'a' <= lastChar <= 'z':
- position = charTbl.index(ord('a') - 1) # 96
- elif 'A' <= lastChar <= 'Z':
- position = charTbl.index(ord('A') - 1) # 64
- elif '0' <= lastChar <= '9':
- position = charTbl.index(ord('0') - 1) # 47
+ else:
+ if 'a' <= lastChar <= 'z':
+ position = charTbl.index(ord('a') - 1) # 96
+ elif 'A' <= lastChar <= 'Z':
+ position = charTbl.index(ord('A') - 1) # 64
+ elif '0' <= lastChar <= '9':
+ position = charTbl.index(ord('0') - 1) # 47
except ValueError:
pass
finally:
@@ -633,7 +636,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
dataToStdout(filterControlChars(val))
# some DBMSes (e.g. Firebird, DB2, etc.) have issues with trailing spaces
- if len(partialValue) > INFERENCE_BLANK_BREAK and partialValue[-INFERENCE_BLANK_BREAK:].isspace():
+ if Backend.getIdentifiedDbms() in (DBMS.FIREBIRD, DBMS.DB2, DBMS.MAXDB) and len(partialValue) > INFERENCE_BLANK_BREAK and partialValue[-INFERENCE_BLANK_BREAK:].isspace():
finalValue = partialValue[:-INFERENCE_BLANK_BREAK]
break
elif charsetType and partialValue[-1:].isspace():
diff --git a/lib/utils/hash.py b/lib/utils/hash.py
index cf52fb562..d39a72506 100644
--- a/lib/utils/hash.py
+++ b/lib/utils/hash.py
@@ -724,19 +724,20 @@ def attackDumpedTable():
def hashRecognition(value):
retVal = None
- isOracle, isMySQL = Backend.isDbms(DBMS.ORACLE), Backend.isDbms(DBMS.MYSQL)
+ if six.PY2: # currently only supported on Python2
+ isOracle, isMySQL = Backend.isDbms(DBMS.ORACLE), Backend.isDbms(DBMS.MYSQL)
- if isinstance(value, six.string_types):
- for name, regex in getPublicTypeMembers(HASH):
- # Hashes for Oracle and old MySQL look the same hence these checks
- if isOracle and regex == HASH.MYSQL_OLD or isMySQL and regex == HASH.ORACLE_OLD:
- continue
- elif regex == HASH.CRYPT_GENERIC:
- if any((value.lower() == value, value.upper() == value)):
+ if isinstance(value, six.string_types):
+ for name, regex in getPublicTypeMembers(HASH):
+ # Hashes for Oracle and old MySQL look the same hence these checks
+ if isOracle and regex == HASH.MYSQL_OLD or isMySQL and regex == HASH.ORACLE_OLD:
continue
- elif re.match(regex, value):
- retVal = regex
- break
+ elif regex == HASH.CRYPT_GENERIC:
+ if any((value.lower() == value, value.upper() == value)):
+ continue
+ elif re.match(regex, value):
+ retVal = regex
+ break
return retVal
diff --git a/tamper/between.py b/tamper/between.py
index d9c971660..5c8392990 100644
--- a/tamper/between.py
+++ b/tamper/between.py
@@ -34,6 +34,8 @@ def tamper(payload, **kwargs):
'1 AND A NOT BETWEEN 0 AND B--'
>>> tamper('1 AND A = B--')
'1 AND A BETWEEN B AND B--'
+ >>> tamper('1 AND LAST_INSERT_ROWID()=LAST_INSERT_ROWID()')
+ '1 AND LAST_INSERT_ROWID() BETWEEN LAST_INSERT_ROWID() AND LAST_INSERT_ROWID()'
"""
retVal = payload
@@ -48,7 +50,7 @@ def tamper(payload, **kwargs):
retVal = re.sub(r"\s*>\s*(\d+|'[^']+'|\w+\(\d+\))", r" NOT BETWEEN 0 AND \g<1>", payload)
if retVal == payload:
- match = re.search(r"(?i)(\b(AND|OR)\b\s+)(?!.*\b(AND|OR)\b)([^=]+?)\s*=\s*(\w+)\s*", payload)
+ match = re.search(r"(?i)(\b(AND|OR)\b\s+)(?!.*\b(AND|OR)\b)([^=]+?)\s*=\s*([\w()]+)\s*", payload)
if match:
_ = "%s %s BETWEEN %s AND %s" % (match.group(2), match.group(4), match.group(5), match.group(5))
diff --git a/tamper/hex2char.py b/tamper/hex2char.py
index 37d9fd3c8..3f86aa86f 100644
--- a/tamper/hex2char.py
+++ b/tamper/hex2char.py
@@ -8,6 +8,7 @@ See the file 'LICENSE' for copying permission
import re
from lib.core.common import decodeHex
+from lib.core.common import getOrds
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
@@ -37,7 +38,7 @@ def tamper(payload, **kwargs):
if payload:
for match in re.finditer(r"\b0x([0-9a-f]+)\b", retVal):
if len(match.group(1)) > 2:
- result = "CONCAT(%s)" % ','.join("CHAR(%d)" % ord(_) for _ in decodeHex(match.group(1)))
+ result = "CONCAT(%s)" % ','.join("CHAR(%d)" % _ for _ in getOrds(decodeHex(match.group(1))))
else:
result = "CHAR(%d)" % ord(decodeHex(match.group(1)))
retVal = retVal.replace(match.group(0), result)
diff --git a/tamper/symboliclogical.py b/tamper/symboliclogical.py
index df542d4b5..bbf55737b 100644
--- a/tamper/symboliclogical.py
+++ b/tamper/symboliclogical.py
@@ -6,7 +6,6 @@ See the file 'LICENSE' for copying permission
"""
import re
-import urllib
from lib.core.enums import PRIORITY
@@ -26,6 +25,6 @@ def tamper(payload, **kwargs):
retVal = payload
if payload:
- retVal = re.sub(r"(?i)\bAND\b", urllib.quote("&&"), re.sub(r"(?i)\bOR\b", urllib.quote("||"), payload))
+ retVal = re.sub(r"(?i)\bAND\b", "%26%26", re.sub(r"(?i)\bOR\b", "%7C%7C", payload))
return retVal