implementation of switch --hex for 4 major DBMSes

This commit is contained in:
Miroslav Stampar 2012-02-21 11:44:48 +00:00
parent 77723a7aee
commit bcf3255fe1
7 changed files with 108 additions and 53 deletions

View File

@ -17,6 +17,7 @@ from lib.core.common import isDBMSVersionAtLeast
from lib.core.common import isTechniqueAvailable
from lib.core.common import randomInt
from lib.core.common import randomStr
from lib.core.common import singleTimeWarnMessage
from lib.core.convert import urlencode
from lib.core.data import conf
from lib.core.data import kb
@ -286,11 +287,22 @@ class Agent:
if field.startswith("(CASE") or field.startswith("(IIF"):
nulledCastedField = field
else:
nulledCastedField = queries[Backend.getIdentifiedDbms()].cast.query % field
_ = queries[Backend.getIdentifiedDbms()]
nulledCastedField = _.cast.query % field
if Backend.isDbms(DBMS.ACCESS):
nulledCastedField = queries[Backend.getIdentifiedDbms()].isnull.query % (nulledCastedField, nulledCastedField)
nulledCastedField = _.isnull.query % (nulledCastedField, nulledCastedField)
else:
nulledCastedField = queries[Backend.getIdentifiedDbms()].isnull.query % nulledCastedField
nulledCastedField = _.isnull.query % nulledCastedField
if conf.hexConvert:
if 'hex' in _:
nulledCastedField = _.hex.query % nulledCastedField
else:
warnMsg = "switch '--hex' is currently not supported on DBMS '%s'. " % Backend.getIdentifiedDbms()
warnMsg += "Going to switch it off"
singleTimeWarnMessage(warnMsg)
conf.hexConvert = False
return nulledCastedField

View File

@ -1234,6 +1234,7 @@ def parseUnionPage(output, unique=True):
for entry in output:
entry = entry.group(1)
entry = decodeHexValue(entry) if conf.hexConvert else entry
if unique:
key = entry.lower()
@ -3098,35 +3099,63 @@ def getCounter(technique):
return kb.counters.get(technique, 0)
def applyFunctionRecursively(value, function):
"""
Applies function recursively through list-like structures
"""
if isinstance(value, (list, tuple, set, BigArray)):
retVal = [applyFunctionRecursively(_, function) for _ in value]
else:
retVal = function(value)
return retVal
def decodeHexValue(value):
"""
Returns value decoded from DBMS specific hexadecimal representation
"""
def _(value):
if isinstance(value, basestring) and len(value) % 2 == 0:
if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.ORACLE, DBMS.PGSQL):
value = value.decode("hex")
elif Backend.isDbms(DBMS.MSSQL):
value = value[2:].decode("hex")
if value[1] == '\x00':
value = value.decode("utf16")
return value
return applyFunctionRecursively(value, _)
def extractExpectedValue(value, expected):
"""
Extracts and returns expected value by a given type
"""
if not expected:
return value
if expected:
value = unArrayizeValue(value)
value = unArrayizeValue(value)
if isNoneValue(value):
value = None
elif expected == EXPECTED.BOOL:
if isinstance(value, int):
value = bool(value)
elif isinstance(value, basestring):
value = value.strip().lower()
if value in ("true", "false"):
value = value == "true"
elif value in ("1", "-1"):
value = True
elif value == "0":
value = False
else:
value = None
elif expected == EXPECTED.INT:
if isinstance(value, basestring):
if value.isdigit():
value = int(value)
else:
value = None
if isNoneValue(value):
value = None
elif expected == EXPECTED.BOOL:
if isinstance(value, int):
value = bool(value)
elif isinstance(value, basestring):
value = value.strip().lower()
if value in ("true", "false"):
value = value == "true"
elif value in ("1", "-1"):
value = True
elif value == "0":
value = False
else:
value = None
elif expected == EXPECTED.INT:
if isinstance(value, basestring):
if value.isdigit():
value = int(value)
else:
value = None
return value

View File

@ -170,6 +170,7 @@ optDict = {
"flushSession": "boolean",
"forms": "boolean",
"freshQueries": "boolean",
"hexConvert": "boolean",
"parseErrors": "boolean",
"replicate": "boolean",
"updateAll": "boolean",

View File

@ -522,6 +522,10 @@ def cmdLineParser():
action="store_true",
help="Ignores query results stored in session file")
general.add_option("--hex", dest="hexConvert",
action="store_true",
help="Uses DBMS hex conversion function(s) for data retrieval")
general.add_option("--parse-errors", dest="parseErrors",
action="store_true",
help="Parse and display DBMS error messages from responses")

View File

@ -14,6 +14,7 @@ import traceback
from lib.core.agent import agent
from lib.core.common import Backend
from lib.core.common import dataToStdout
from lib.core.common import decodeHexValue
from lib.core.common import decodeIntToUnicode
from lib.core.common import filterControlChars
from lib.core.common import getCharset
@ -520,6 +521,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
logger.info(infoMsg)
if finalValue is not None:
finalValue = decodeHexValue(finalValue) if conf.hexConvert else finalValue
conf.hashDB.write(expression, finalValue)
else:
conf.hashDB.write(expression, "%s%s" % (PARTIAL_VALUE_MARKER, partialValue))

View File

@ -16,6 +16,7 @@ from lib.core.bigarray import BigArray
from lib.core.common import Backend
from lib.core.common import calculateDeltaSeconds
from lib.core.common import dataToStdout
from lib.core.common import decodeHexValue
from lib.core.common import extractRegexResult
from lib.core.common import getUnicode
from lib.core.common import incrementCounter
@ -123,6 +124,8 @@ def __oneShotErrorUse(expression, field):
retVal = output
break
retVal = decodeHexValue(retVal) if conf.hexConvert else retVal
if isinstance(retVal, basestring):
retVal = htmlunescape(retVal).replace("<br>", "\n")

View File

@ -102,7 +102,7 @@ proxy =
# Syntax: username:password
pCred =
# Ignore system default HTTP proxy
# Ignore system default HTTP proxy.
# Valid: True or False
ignoreProxy = False
@ -121,21 +121,21 @@ timeout = 30
# Default: 3
retries = 3
# Regular expression for filtering targets from provided Burp
# Regular expression for filtering targets from provided Burp.
# or WebScarab proxy log.
# Example: (google|yahoo)
scope =
# Url address to visit frequently during testing
# Url address to visit frequently during testing.
# Example: http://192.168.1.121/index.html
safUrl =
# Test requests between two visits to a given safe url (default 0)
# Test requests between two visits to a given safe url (default 0).
# Valid: integer
# Default: 0
saFreq = 0
# Evaluate provided Python code before the request
# Evaluate provided Python code before the request.
# Example: import hashlib;id2=hashlib.md5(id).hexdigest()
evalCode =
@ -188,20 +188,20 @@ dbms =
# Valid: linux, windows
os =
# Injection payload prefix string
# Injection payload prefix string.
prefix =
# Injection payload suffix string
# Injection payload suffix string.
suffix =
# Use logic operation(s) instead of negating values
# Use logic operation(s) instead of negating values.
# Valid: True or False
logicNegative = False
# Skip testing for given parameter(s)
# Skip testing for given parameter(s).
skip =
# Use given script(s) for tampering injection data
# Use given script(s) for tampering injection data.
tamper =
@ -209,14 +209,14 @@ tamper =
# content from HTTP responses when using blind SQL injection technique.
[Detection]
# Level of tests to perform
# Level of tests to perform.
# The higher the value is, the higher the number of HTTP(s) requests are
# as well as the better chances to detect a tricky SQL injection.
# Valid: Integer between 1 and 5
# Default: 1
level = 1
# Risk of tests to perform
# Risk of tests to perform.
# Note: boolean-based blind SQL injection tests with AND are considered
# risk 1, with OR are considered risk 3.
# Valid: Integer between 0 and 3
@ -236,17 +236,17 @@ string =
# (http://www.python.org/doc/2.5.2/lib/re-syntax.html)
regexp =
# HTTP response code to match when the query is valid
# HTTP response code to match when the query is valid.
# Valid: Integer
# Example: 200 (assuming any False statement returns a different response
# code)
# code =
# Compare pages based only on the textual content
# Compare pages based only on the textual content.
# Valid: True or False
textOnly = False
# Compare pages based only on their titles
# Compare pages based only on their titles.
# Valid: True or False
titles = False
@ -497,28 +497,28 @@ tmpPath =
# system Windows registry.
[Windows]
# Read a Windows registry key value
# Read a Windows registry key value.
# Valid: True or False
regRead = False
# Write a Windows registry key value data
# Write a Windows registry key value data.
# Valid: True or False
regAdd = False
# Delete a Windows registry key value
# Delete a Windows registry key value.
# Valid: True or False
regDel = False
# Windows registry key
# Windows registry key.
regKey =
# Windows registry key value
# Windows registry key value.
regVal =
# Windows registry key value data
# Windows registry key value data.
regData =
# Windows registry key value type
# Windows registry key value type.
regType =
@ -538,11 +538,11 @@ batch = False
# Force character encoding used for data retrieval.
charset =
# Check to see if Tor is used properly
# Check to see if Tor is used properly.
# Valid: True or False
checkTor = False
# Crawl the website starting from the target url
# Crawl the website starting from the target url.
# Valid: integer
# Default: 0
crawlDepth = 0
@ -560,7 +560,7 @@ eta = False
# Valid: True or False
flushSession = False
# Parse and test forms on target url
# Parse and test forms on target url.
# Valid: True or False
forms = False
@ -568,6 +568,10 @@ forms = False
# Valid: True or False
freshQueries = False
# Uses DBMS hex conversion function(s) for data retrieval.
# Valid: True or False
hexConvert = False
# Parse and display DBMS error messages from responses.
# Valid: True or False
parseErrors = False
@ -580,7 +584,7 @@ replicate = False
# Valid: True or False
tor = False
# Set Tor proxy port other than default
# Set Tor proxy port other than default.
# Valid: integer
# torPort =