Refactoring DBMS string escaping functions

This commit is contained in:
Miroslav Stampar 2013-01-20 13:45:58 +01:00
parent 3b57fe2924
commit b4a55a809e
12 changed files with 52 additions and 206 deletions

View File

@ -7,7 +7,6 @@ See the file 'doc/COPYING' for copying permission
import copy
import httplib
import random
import re
import socket
import time

View File

@ -23,7 +23,6 @@ from lib.core.common import incrementCounter
from lib.core.common import initTechnique
from lib.core.common import isListLike
from lib.core.common import isNumPosStrValue
from lib.core.common import isTechniqueAvailable
from lib.core.common import listToStrValue
from lib.core.common import readInput
from lib.core.common import unArrayizeValue

View File

@ -5,7 +5,6 @@ Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.exception import SqlmapSyntaxException
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@ -14,34 +13,7 @@ class Syntax(GenericSyntax):
@staticmethod
def escape(expression, quote=True):
if quote:
while True:
index = expression.find("'")
if index == -1:
break
firstIndex = index + 1
index = expression[firstIndex:].find("'")
if index == -1:
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
lastIndex = firstIndex + index
old = "'%s'" % expression[firstIndex:lastIndex]
unescaped = ""
for i in xrange(firstIndex, lastIndex):
unescaped += "CHR(%d)" % (ord(expression[i]))
if i < lastIndex - 1:
unescaped += "&"
expression = expression.replace(old, unescaped)
else:
unescaped = "".join("CHR(%d)&" % ord(c) for c in expression)
if unescaped[-1] == "&":
unescaped = unescaped[:-1]
expression = unescaped
return expression
def escaper(value):
return "&".join("CHR(%d)" % ord(_) for _ in value)
return Syntax._escape(expression, quote, escaper)

View File

@ -5,8 +5,6 @@ Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.data import logger
from lib.core.exception import SqlmapSyntaxException
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@ -15,32 +13,7 @@ class Syntax(GenericSyntax):
@staticmethod
def escape(expression, quote=True):
if expression == u"'''":
return "CHR(%d)" % (ord("'"))
def escaper(value):
return "||".join("CHR(%d)" % ord(_) for _ in value)
if quote:
while True:
index = expression.find("'")
if index == -1:
break
firstIndex = index + 1
index = expression[firstIndex:].find("'")
if index == -1:
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
lastIndex = firstIndex + index
old = "'%s'" % expression[firstIndex:lastIndex]
unescaped = ""
for i in xrange(firstIndex, lastIndex):
unescaped += "CHR(%d)" % (ord(expression[i]))
if i < lastIndex - 1:
unescaped += "||"
expression = expression.replace(old, unescaped)
else:
expression = "||".join("CHR(%d)" % ord(c) for c in expression)
return expression
return Syntax._escape(expression, quote, escaper)

View File

@ -6,7 +6,6 @@ See the file 'doc/COPYING' for copying permission
"""
from lib.core.common import isDBMSVersionAtLeast
from lib.core.exception import SqlmapSyntaxException
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@ -15,38 +14,10 @@ class Syntax(GenericSyntax):
@staticmethod
def escape(expression, quote=True):
if isDBMSVersionAtLeast('2.1'):
if expression == u"'''":
return "ASCII_CHAR(%d)" % (ord("'"))
if quote:
while True:
index = expression.find("'")
if index == -1:
break
firstIndex = index + 1
index = expression[firstIndex:].find("'")
if index == -1:
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
lastIndex = firstIndex + index
old = "'%s'" % expression[firstIndex:lastIndex]
unescaped = ""
for i in xrange(firstIndex, lastIndex):
unescaped += "ASCII_CHAR(%d)" % (ord(expression[i]))
if i < lastIndex - 1:
unescaped += "||"
expression = expression.replace(old, unescaped)
else:
unescaped = "".join("ASCII_CHAR(%d)||" % ord(c) for c in expression)
if unescaped[-1] == "||":
unescaped = unescaped[:-1]
expression = unescaped
return expression
def escaper(value):
retVal = value
if isDBMSVersionAtLeast('2.1'):
retVal = "||".join("ASCII_CHAR(%d)" % ord(_) for _ in value)
return retVal
return Syntax._escape(expression, quote, escaper)

View File

@ -5,7 +5,6 @@ Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.exception import SqlmapSyntaxException
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@ -14,25 +13,7 @@ class Syntax(GenericSyntax):
@staticmethod
def escape(expression, quote=True):
if quote:
while True:
index = expression.find("'")
if index == -1:
break
def escaper(value):
return "+".join("%s(%d)" % ("CHAR" if ord(value[i]) < 256 else "NCHAR", ord(value[i])) for i in xrange(len(value)))
firstIndex = index + 1
index = expression[firstIndex:].find("'")
if index == -1:
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
lastIndex = firstIndex + index
old = "'%s'" % expression[firstIndex:lastIndex]
unescaped = "+".join("%s(%d)" % ("CHAR" if ord(expression[i]) < 256 else "NCHAR", ord(expression[i])) for i in xrange(firstIndex, lastIndex))
expression = expression.replace(old, unescaped)
else:
expression = "+".join("CHAR(%d)" % ord(c) for c in expression)
return expression
return Syntax._escape(expression, quote, escaper)

View File

@ -6,10 +6,8 @@ See the file 'doc/COPYING' for copying permission
"""
import binascii
import re
from lib.core.convert import utf8encode
from lib.core.exception import SqlmapSyntaxException
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@ -18,14 +16,12 @@ class Syntax(GenericSyntax):
@staticmethod
def escape(expression, quote=True):
if quote:
unescaped = expression
for item in re.findall(r"'[^']+'", expression, re.S):
try:
unescaped = unescaped.replace(item, "0x%s" % binascii.hexlify(item.strip("'")))
except UnicodeEncodeError:
unescaped = unescaped.replace(item, "CONVERT(0x%s USING utf8)" % "".join("%.2x" % ord(_) for _ in utf8encode(item.strip("'"))))
else:
unescaped = "0x%s" % binascii.hexlify(expression)
def escaper(value):
retVal = None
try:
retVal = "0x%s" % binascii.hexlify(value.strip("'"))
except UnicodeEncodeError:
retVal = "CONVERT(0x%s USING utf8)" % "".join("%.2x" % ord(_) for _ in utf8encode(value.strip("'")))
return retVal
return unescaped
return Syntax._escape(expression, quote, escaper)

View File

@ -5,7 +5,6 @@ Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.exception import SqlmapSyntaxException
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@ -14,24 +13,7 @@ class Syntax(GenericSyntax):
@staticmethod
def escape(expression, quote=True):
if quote:
while True:
index = expression.find("'")
if index == -1:
break
def escaper(value):
return "||".join("%s(%d)" % ("CHR" if ord(value[i]) < 256 else "NCHR", ord(value[i])) for i in xrange(len(value)))
firstIndex = index + 1
index = expression[firstIndex:].find("'")
if index == -1:
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
lastIndex = firstIndex + index
old = "'%s'" % expression[firstIndex:lastIndex]
unescaped = "||".join("%s(%d)" % ("CHR" if ord(expression[i]) < 256 else "NCHR", ord(expression[i])) for i in xrange(firstIndex, lastIndex))
expression = expression.replace(old, unescaped)
else:
expression = "||".join("CHR(%d)" % ord(c) for c in expression)
return expression
return Syntax._escape(expression, quote, escaper)

View File

@ -5,7 +5,6 @@ Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.exception import SqlmapSyntaxException
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@ -19,24 +18,7 @@ class Syntax(GenericSyntax):
e.g. SELECT 1 WHERE 'a'!='a'||'b' will trigger error ("argument of WHERE must be type boolean, not type text")
"""
if quote:
while True:
index = expression.find("'")
if index == -1:
break
def escaper(value):
return "(%s)" % "||".join("CHR(%d)" % ord(_) for _ in value) # Postgres CHR() function already accepts Unicode code point of character(s)
firstIndex = index + 1
index = expression[firstIndex:].find("'")
if index == -1:
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
lastIndex = firstIndex + index
old = "'%s'" % expression[firstIndex:lastIndex]
unescaped = "(%s)" % "||".join("CHR(%d)" % (ord(expression[i])) for i in xrange(firstIndex, lastIndex)) # Postgres CHR() function already accepts Unicode code point of character(s)
expression = expression.replace(old, unescaped)
else:
expression = "(%s)" % "||".join("CHR(%d)" % ord(c) for c in expression)
return expression
return Syntax._escape(expression, quote, escaper)

View File

@ -6,10 +6,8 @@ See the file 'doc/COPYING' for copying permission
"""
import binascii
import re
from lib.core.common import isDBMSVersionAtLeast
from lib.core.exception import SqlmapSyntaxException
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@ -18,13 +16,10 @@ class Syntax(GenericSyntax):
@staticmethod
def escape(expression, quote=True):
unescaped = expression
def escaper(value):
retVal = value
if isDBMSVersionAtLeast('3'):
retVal = "X'%s'" % binascii.hexlify(value)
return retVal
if isDBMSVersionAtLeast('3'):
if quote:
for item in re.findall(r"'[^']+'", expression, re.S):
unescaped = unescaped.replace(item, "X'%s'" % binascii.hexlify(item.strip("'")))
else:
unescaped = "X'%s'" % binascii.hexlify(expression)
return unescaped
return Syntax._escape(expression, quote, escaper)

View File

@ -5,7 +5,6 @@ Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
from lib.core.exception import SqlmapSyntaxException
from plugins.generic.syntax import Syntax as GenericSyntax
class Syntax(GenericSyntax):
@ -14,24 +13,7 @@ class Syntax(GenericSyntax):
@staticmethod
def escape(expression, quote=True):
if quote:
while True:
index = expression.find("'")
if index == -1:
break
def escaper(value):
return "+".join("%s(%d)" % ("CHAR" if ord(value[i]) < 256 else "TO_UNICHAR", ord(value[i])) for i in xrange(len(value)))
firstIndex = index + 1
index = expression[firstIndex:].find("'")
if index == -1:
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
lastIndex = firstIndex + index
old = "'%s'" % expression[firstIndex:lastIndex]
unescaped = "+".join("%s(%d)" % ("CHAR" if ord(expression[i]) < 256 else "TO_UNICHAR", ord(expression[i])) for i in xrange(firstIndex, lastIndex))
expression = expression.replace(old, unescaped)
else:
expression = "+".join("CHAR(%d)" % ord(c) for c in expression)
return expression
return Syntax._escape(expression, quote, escaper)

View File

@ -5,6 +5,8 @@ Copyright (c) 2006-2013 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
"""
import re
from lib.core.exception import SqlmapUndefinedMethod
class Syntax:
@ -15,6 +17,18 @@ class Syntax:
def __init__(self):
pass
@staticmethod
def _escape(expression, quote=True, escaper=None):
retVal = expression
if quote:
for item in re.findall(r"'[^']+'", expression, re.S):
retVal = retVal.replace(item, escaper(item[1:-1]))
else:
retVal = escaper(expression)
return retVal
@staticmethod
def escape(expression, quote=True):
errMsg = "'escape' method must be defined "