important update regarding (Bug #209) - probably more will be needed

This commit is contained in:
Miroslav Stampar 2010-10-29 16:11:50 +00:00
parent a921fe0d5d
commit 5a38ac7ea9
21 changed files with 130 additions and 130 deletions

View File

@ -24,7 +24,6 @@ from lib.core.common import readInput
from lib.core.common import showStaticWords
from lib.core.common import wasLastRequestError
from lib.core.common import DynamicContentItem
from lib.core.convert import urlencode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger

View File

@ -11,6 +11,7 @@ import re
from xml.etree import ElementTree as ET
from lib.core.common import getCompiledRegex
from lib.core.common import getInjectionCase
from lib.core.common import randomInt
from lib.core.common import randomStr
@ -20,6 +21,7 @@ from lib.core.data import kb
from lib.core.data import queries
from lib.core.datatype import advancedDict
from lib.core.exception import sqlmapNoneDataException
from lib.core.settings import PAYLOAD_DELIMITER
class Agent:
"""
@ -54,18 +56,17 @@ class Agent:
falseValue = ""
negValue = ""
retValue = ""
newValue = urlencode(newValue) if place != "URI" else newValue
if negative or kb.unionNegative:
negValue = "-"
elif falseCond or kb.unionFalseCond:
randInt = randomInt()
falseValue = urlencode(" AND %d=%d" % (randInt, randInt + 1))
falseValue = " AND %d=%d" % (randInt, randInt + 1)
# After identifing the injectable parameter
if kb.injPlace == "User-Agent":
retValue = kb.injParameter.replace(kb.injParameter,
"%s%s" % (negValue, kb.injParameter + falseValue + newValue))
self.addPayloadDelimiters("%s%s" % (negValue, kb.injParameter + falseValue + newValue)))
elif kb.injParameter:
paramString = conf.parameters[kb.injPlace]
paramDict = conf.paramDict[kb.injPlace]
@ -76,21 +77,21 @@ class Agent:
iterator = root.getiterator(kb.injParameter)
for child in iterator:
child.text = "%s%s" % (negValue, value + falseValue + newValue)
child.text = self.addPayloadDelimiters(negValue + value + falseValue + newValue)
retValue = ET.tostring(root)
elif kb.injPlace == "URI":
retValue = paramString.replace("*",
"%s%s" % (negValue, falseValue + newValue))
self.addPayloadDelimiters("%s%s" % (negValue, falseValue + newValue)))
else:
retValue = paramString.replace("%s=%s" % (kb.injParameter, value),
"%s=%s%s" % (kb.injParameter, negValue, value + falseValue + newValue))
"%s=%s" % (kb.injParameter, self.addPayloadDelimiters(negValue + value + falseValue + newValue)))
# Before identifing the injectable parameter
elif parameter == "User-Agent":
retValue = value.replace(value, newValue)
retValue = value.replace(value, self.addPayloadDelimiters(newValue))
elif place == "URI":
retValue = value.replace("*", "%s" % newValue.replace(value, str()))
retValue = value.replace("*", self.addPayloadDelimiters("%s" % newValue.replace(value, str())))
else:
paramString = conf.parameters[place]
@ -99,12 +100,12 @@ class Agent:
iterator = root.getiterator(parameter)
for child in iterator:
child.text = newValue
child.text = self.addPayloadDelimiters(newValue)
retValue = ET.tostring(root)
else:
retValue = paramString.replace("%s=%s" % (parameter, value),
"%s=%s" % (parameter, newValue))
"%s=%s" % (parameter, self.addPayloadDelimiters(newValue)))
return retValue
@ -604,5 +605,60 @@ class Agent:
return queries[kb.dbms].case.query % expression
def addPayloadDelimiters(self, inpStr):
"""
Adds payload delimiters around the input string
"""
retVal = inpStr
if inpStr:
retVal = "%s%s%s" % (PAYLOAD_DELIMITER, inpStr, PAYLOAD_DELIMITER)
return retVal
def removePayloadDelimiters(self, inpStr, urlencode_=True):
"""
Removes payload delimiters from inside the input string
"""
retVal = inpStr
if inpStr:
if urlencode_:
regObj = getCompiledRegex("(?P<result>%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER))
for match in regObj.finditer(inpStr):
retVal = retVal.replace(match.group("result"), urlencode(match.group("result")[1:-1]))
else:
retVal = retVal.replace(PAYLOAD_DELIMITER, '')
return retVal
def extractPayload(self, inpStr):
"""
Extracts payload from inside of the input string
"""
retVal = None
if inpStr:
regObj = getCompiledRegex("(?P<result>%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER))
match = regObj.search(inpStr)
if match:
retVal = match.group("result")[1:-1]
return retVal
def replacePayload(self, inpStr, payload):
"""
Replaces payload inside the input string with a given payload
"""
retVal = inpStr
if inpStr:
regObj = getCompiledRegex("(?P<result>%s.*?%s)" % (PAYLOAD_DELIMITER, PAYLOAD_DELIMITER))
retVal = regObj.sub("%s%s%s" % (PAYLOAD_DELIMITER, payload, PAYLOAD_DELIMITER), inpStr)
return retVal
# SQL agent
agent = Agent()

View File

@ -1532,7 +1532,7 @@ def runningAsAdmin():
isAdmin = True
else:
errMsg = "sqlmap is not able to check if you are running it "
errMsg += "as an administrator accout on this platform. "
errMsg += "as an administrator account on this platform. "
errMsg += "sqlmap will assume that you are an administrator "
errMsg += "which is mandatory for the requested takeover attack "
errMsg += "to work properly"

View File

@ -556,14 +556,14 @@ def __setTamperingFunctions():
raise sqlmapSyntaxException, "can not import tamper script '%s' (%s)" % (filename[:-3], msg)
for name, function in inspect.getmembers(module, inspect.isfunction):
if name == "tamper" and function.func_code.co_argcount == 2:
if name == "tamper" and function.func_code.co_argcount == 1:
kb.tamperFunctions.append(function)
found = True
break
if not found:
raise sqlmapGenericException, "missing function 'tamper(place, value)' in tamper script '%s'" % tfile
raise sqlmapGenericException, "missing function 'tamper(value)' in tamper script '%s'" % tfile
def __setThreads():
if not isinstance(conf.threads, int) or conf.threads <= 0:

View File

@ -46,6 +46,8 @@ ERROR_EMPTY_CHAR = ":x:"
ERROR_START_CHAR = ":s:"
ERROR_END_CHAR = ":e:"
PAYLOAD_DELIMITER = "\x00"
# System variables
IS_WIN = subprocess.mswindows
# The name of the operating system dependent module imported. The following

View File

@ -92,7 +92,7 @@ def bannerParser(banner):
"""
xmlfile = None
if kb.dbms == "Microsoft SQL Server":
xmlfile = paths.MSSQL_XML
elif kb.dbms == "MySQL":
@ -104,7 +104,7 @@ def bannerParser(banner):
if not xmlfile:
return
checkFile(xmlfile)
if kb.dbms == "Microsoft SQL Server":

View File

@ -35,9 +35,6 @@ def forgeHeaders(cookie, ua):
for header, value in conf.httpHeaders:
if cookie and header == "Cookie":
if conf.cookieUrlencode:
cookie = urlEncodeCookieValues(cookie)
headers[header] = cookie
elif ua and header == "User-Agent":
headers[header] = ua

View File

@ -16,6 +16,7 @@ import urlparse
import traceback
from lib.contrib import multipartpost
from lib.core.agent import agent
from lib.core.common import readInput
from lib.core.common import getUnicode
from lib.core.convert import urlencode
@ -107,7 +108,6 @@ class Connect:
get = conf.parameters["GET"]
if get:
get = urlencode(get)
url = "%s?%s" % (url, get)
requestMsg += "?%s" % get
@ -149,7 +149,7 @@ class Connect:
cookieStr += "%s; " % cookie[8:index]
conn = urllib2.urlopen(req)
if not req.has_header("Accept-Encoding"):
requestHeaders += "Accept-Encoding: identity\n"
@ -307,8 +307,22 @@ class Connect:
place = kb.injPlace
if kb.tamperFunctions:
for function in kb.tamperFunctions:
value = function(place, value)
payload = agent.extractPayload(value)
if payload:
for function in kb.tamperFunctions:
payload = function(payload)
value = agent.replacePayload(value, payload)
if place == "GET":
value = agent.removePayloadDelimiters(value, True)
elif place == "POST":
value = agent.removePayloadDelimiters(value, False)
elif place == "Cookie":
value = agent.removePayloadDelimiters(value, conf.cookieUrlencode)
elif place == "User-Agent":
value = agent.removePayloadDelimiters(value, True)
elif place == "URI":
value = agent.removePayloadDelimiters(value, False)
if conf.checkPayload:
checkPayload(value)

View File

@ -22,7 +22,6 @@ from lib.core.common import pushValue
from lib.core.common import randomInt
from lib.core.common import readInput
from lib.core.common import safeStringFormat
from lib.core.convert import urlencode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger

View File

@ -22,7 +22,6 @@ from lib.core.common import pushValue
from lib.core.common import readInput
from lib.core.common import replaceNewlineTabs
from lib.core.common import safeStringFormat
from lib.core.convert import urlencode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@ -122,7 +121,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, posValue))
queriesCount[0] += 1
result = Request.queryPage(urlencode(forgedPayload))
result = Request.queryPage(forgedPayload)
if result:
return hintValue[idx-1]
@ -153,7 +152,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
if len(charTbl) == 1:
forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, charTbl[0]))
queriesCount[0] += 1
result = Request.queryPage(urlencode(forgedPayload))
result = Request.queryPage(forgedPayload)
if result:
return chr(charTbl[0]) if charTbl[0] < 128 else unichr(charTbl[0])
@ -174,7 +173,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
forgedPayload = safeStringFormat(payload, (expressionUnescaped, idx, posValue))
queriesCount[0] += 1
result = Request.queryPage(urlencode(forgedPayload))
result = Request.queryPage(forgedPayload)
if kb.dbms in ("SQLite", "Microsoft Access", "SAP MaxDB"):
posValue = popValue()
@ -226,7 +225,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
for retVal in (originalTbl[originalTbl.index(minValue)], originalTbl[originalTbl.index(minValue) + 1]):
forgedPayload = safeStringFormat(payload.replace('%3E', '%3D'), (expressionUnescaped, idx, retVal))
queriesCount[0] += 1
result = Request.queryPage(urlencode(forgedPayload))
result = Request.queryPage(forgedPayload)
if result:
return chr(retVal) if retVal < 128 else unichr(retVal)
@ -444,7 +443,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (expressionUnescaped, testValue)))
query = agent.postfixQuery(query)
queriesCount[0] += 1
result = Request.queryPage(urlencode(agent.payload(newValue=query)))
result = Request.queryPage(agent.payload(newValue=query))
# Did we have luck?
if result:
@ -468,7 +467,7 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
query = agent.prefixQuery(safeStringFormat("AND (%s) = %s", (subquery, testValue)))
query = agent.postfixQuery(query)
queriesCount[0] += 1
result = Request.queryPage(urlencode(agent.payload(newValue=query)))
result = Request.queryPage(agent.payload(newValue=query))
# Did we have luck?
if result:

View File

@ -15,7 +15,6 @@ from lib.core.common import getUnicode
from lib.core.common import randomInt
from lib.core.common import replaceNewlineTabs
from lib.core.common import safeStringFormat
from lib.core.convert import urlencode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
@ -68,7 +67,7 @@ def errorUse(expression):
logger.debug(debugMsg)
payload = agent.payload(newValue=forgedQuery)
result = Request.queryPage(urlencode(payload), content=True)
result = Request.queryPage(payload, content=True)
match = re.search('%s(?P<result>.*?)%s' % (ERROR_START_CHAR, ERROR_END_CHAR), result[0], re.DOTALL | re.IGNORECASE)
if match:

View File

@ -7,10 +7,7 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.convert import urldecode
from lib.core.convert import urlencode
def tamper(place, value):
def tamper(value):
"""
Replaces '>' with 'NOT BETWEEN 0 AND #'
Example: 'A > B' becomes 'A NOT BETWEEN 0 AND B'
@ -19,14 +16,12 @@ def tamper(place, value):
retVal = value
if value:
if place != "URI":
value = urldecode(value)
retVal = ""
quote, doublequote, firstspace = False, False, False
for i in xrange(len(value)):
if not firstspace:
if value[i].isspace():
firstspace = True
retVal += " "
@ -47,8 +42,5 @@ def tamper(place, value):
retVal += value[i]
if place != "URI":
retVal = urlencode(retVal)
return retVal

View File

@ -11,7 +11,7 @@ import string
from lib.core.exception import sqlmapUnsupportedFeatureException
def tamper(place, value):
def tamper(value):
"""
Replaces value with urlencode of non-encoded chars in value
Example: 'SELECT%20FIELD%20FROM%20TABLE' becomes '%53%45%4c%45%43%54%20%46%49%45%4c%44%20%46%52%4f%4d%20%54%41%42%4c%45'
@ -20,18 +20,15 @@ def tamper(place, value):
retVal = value
if value:
if place != "URI":
retVal = ""
i = 0
retVal = ""
i = 0
while i < len(value):
if value[i] == '%' and (i < len(value) - 2) and value[i+1] in string.hexdigits and value[i+2] in string.hexdigits:
retVal += value[i:i+3]
i += 3
else:
retVal += '%%%X' % ord(value[i])
i += 1
else:
raise sqlmapUnsupportedFeatureException, "can't use tamper script '%s' with 'URI' type injections" % __name__
while i < len(value):
if value[i] == '%' and (i < len(value) - 2) and value[i+1] in string.hexdigits and value[i+2] in string.hexdigits:
retVal += value[i:i+3]
i += 3
else:
retVal += '%%%X' % ord(value[i])
i += 1
return retVal

View File

@ -11,7 +11,7 @@ import string
from lib.core.exception import sqlmapUnsupportedFeatureException
def tamper(place, value):
def tamper(value):
"""
Replaces value with unicode-urlencode of non-encoded chars in value
Example: 'SELECT%20FIELD%20FROM%20TABLE' becomes '%u0053%u0045%u004c%u0045%u0043%u0054%u0020%u0046%u0049%u0045%u004c%u0044%u0020%u0046%u0052%u004f%u004d%u0020%u0054%u0041%u0042%u004c%u0045'
@ -20,18 +20,15 @@ def tamper(place, value):
retVal = value
if value:
if place != "URI":
retVal = ""
i = 0
retVal = ""
i = 0
while i < len(value):
if value[i] == '%' and (i < len(value) - 2) and value[i+1] in string.hexdigits and value[i+2] in string.hexdigits:
retVal += "%%u00%s" % value[i+1:i+3]
i += 3
else:
retVal += '%%u00%X' % ord(value[i])
i += 1
else:
raise sqlmapUnsupportedFeatureException, "can't use tamper script '%s' with 'URI' type injections" % __name__
while i < len(value):
if value[i] == '%' and (i < len(value) - 2) and value[i+1] in string.hexdigits and value[i+2] in string.hexdigits:
retVal += "%%u00%s" % value[i+1:i+3]
i += 3
else:
retVal += '%%u00%X' % ord(value[i])
i += 1
return retVal

View File

@ -10,16 +10,13 @@ See the file 'doc/COPYING' for copying permission
from lib.core.convert import urlencode
from lib.core.exception import sqlmapUnsupportedFeatureException
def tamper(place, value):
def tamper(value):
"""
Replaces value with urlencode(value)
Example: 'SELECT%20FIELD%20FROM%20TABLE' becomes 'SELECT%25%20FIELD%25%20FROM%25%20TABLE'
"""
if value:
if place != "URI":
value = urlencode(value, convall=True)
else:
raise sqlmapUnsupportedFeatureException, "can't use tamper script '%s' with 'URI' type injections" % __name__
value = urlencode(value, convall=True)
return value

View File

@ -7,18 +7,13 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.convert import urldecode
from lib.core.convert import urlencode
def tamper(place, value):
def tamper(value):
"""
Replaces 'IFNULL(A, B)' with 'IF(ISNULL(A), B, A)'
Example: 'IFNULL(1, 2)' becomes 'IF(ISNULL(1), 2, 1)'
"""
if value and value.find("IFNULL") > -1:
if place != "URI":
value = urldecode(value)
while value.find("IFNULL(") > -1:
index = value.find("IFNULL(")
@ -28,11 +23,14 @@ def tamper(place, value):
for i in xrange(index + len("IFNULL("), len(value)):
if deepness == 1 and value[i] == ',':
comma = i
elif deepness == 1 and value[i] == ')':
end = i
break
elif value[i] == '(':
deepness += 1
elif value[i] == ')':
deepness -= 1
@ -44,7 +42,4 @@ def tamper(place, value):
else:
break
if place != "URI":
value = urlencode(value)
return value

View File

@ -10,8 +10,6 @@ See the file 'doc/COPYING' for copying permission
import re
from lib.core.common import randomRange
from lib.core.convert import urldecode
from lib.core.convert import urlencode
from lib.core.data import kb
def tamper(place, value):
@ -23,9 +21,6 @@ def tamper(place, value):
retVal = value
if value:
if place != "URI":
retVal = urldecode(retVal)
for match in re.finditer(r"[A-Za-z_]+", retVal):
word = match.group()
@ -37,7 +32,4 @@ def tamper(place, value):
retVal = retVal.replace(word, newWord)
if place != "URI":
retVal = urlencode(retVal)
return retVal

View File

@ -10,11 +10,9 @@ See the file 'doc/COPYING' for copying permission
import re
from lib.core.common import randomRange
from lib.core.convert import urldecode
from lib.core.convert import urlencode
from lib.core.data import kb
def tamper(place, value):
def tamper(value):
"""
Add random comments to value
Example: 'INSERT' becomes 'IN/**/S/**/ERT'
@ -23,9 +21,6 @@ def tamper(place, value):
retVal = value
if value:
if place != "URI":
retVal = urldecode(retVal)
for match in re.finditer(r"[A-Za-z_]+", retVal):
word = match.group()
@ -41,7 +36,4 @@ def tamper(place, value):
newWord += word[-1]
retVal = retVal.replace(word, newWord)
if place != "URI":
retVal = urlencode(retVal)
return retVal

View File

@ -7,10 +7,7 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.convert import urldecode
from lib.core.convert import urlencode
def tamper(place, value):
def tamper(value):
"""
Replaces ' ' with '/**/'
Example: 'SELECT id FROM users' becomes 'SELECT/**/id/**/FROM users'
@ -19,9 +16,6 @@ def tamper(place, value):
retVal = value
if value:
if place != "URI":
value = urldecode(value)
retVal = ""
quote, doublequote, firstspace = False, False, False
@ -44,8 +38,5 @@ def tamper(place, value):
retVal += value[i]
if place != "URI":
retVal = urlencode(retVal)
return retVal

View File

@ -7,10 +7,7 @@ Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.convert import urldecode
from lib.core.convert import urlencode
def tamper(place, value):
def tamper(value):
"""
Replaces ' ' with '/**/'
Example: 'SELECT id FROM users' becomes 'SELECT+id+FROM+users'
@ -19,9 +16,6 @@ def tamper(place, value):
retVal = value
if value:
if place != "URI":
value = urldecode(value)
retVal = ""
quote, doublequote, firstspace = False, False, False
@ -44,8 +38,5 @@ def tamper(place, value):
retVal += value[i]
if place != "URI":
retVal = urlencode(retVal)
return retVal

View File

@ -9,10 +9,7 @@ See the file 'doc/COPYING' for copying permission
import random
from lib.core.convert import urldecode
from lib.core.convert import urlencode
def tamper(place, value):
def tamper(value):
"""
Replaces ' ' with a random blank char from a set ('\r', '\n', '\t')
Example: 'SELECT id FROM users' becomes 'SELECT\rid\tFROM\nusers'
@ -22,9 +19,6 @@ def tamper(place, value):
retVal = value
if value:
if place != "URI":
value = urldecode(value)
retVal = ""
quote, doublequote, firstspace = False, False, False
@ -47,8 +41,5 @@ def tamper(place, value):
retVal += value[i]
if place != "URI":
retVal = urlencode(retVal)
return retVal