Skip to content

Commit b4a55a8

Browse files
committed
Refactoring DBMS string escaping functions
1 parent 3b57fe2 commit b4a55a8

File tree

12 files changed

+52
-206
lines changed

12 files changed

+52
-206
lines changed

lib/controller/checks.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import copy
99
import httplib
10-
import random
1110
import re
1211
import socket
1312
import time

lib/techniques/error/use.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
from lib.core.common import initTechnique
2424
from lib.core.common import isListLike
2525
from lib.core.common import isNumPosStrValue
26-
from lib.core.common import isTechniqueAvailable
2726
from lib.core.common import listToStrValue
2827
from lib.core.common import readInput
2928
from lib.core.common import unArrayizeValue

plugins/dbms/access/syntax.py

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
See the file 'doc/COPYING' for copying permission
66
"""
77

8-
from lib.core.exception import SqlmapSyntaxException
98
from plugins.generic.syntax import Syntax as GenericSyntax
109

1110
class Syntax(GenericSyntax):
@@ -14,34 +13,7 @@ def __init__(self):
1413

1514
@staticmethod
1615
def escape(expression, quote=True):
17-
if quote:
18-
while True:
19-
index = expression.find("'")
20-
if index == -1:
21-
break
22-
23-
firstIndex = index + 1
24-
index = expression[firstIndex:].find("'")
25-
26-
if index == -1:
27-
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
28-
29-
lastIndex = firstIndex + index
30-
old = "'%s'" % expression[firstIndex:lastIndex]
31-
unescaped = ""
32-
33-
for i in xrange(firstIndex, lastIndex):
34-
unescaped += "CHR(%d)" % (ord(expression[i]))
35-
if i < lastIndex - 1:
36-
unescaped += "&"
37-
38-
expression = expression.replace(old, unescaped)
39-
else:
40-
unescaped = "".join("CHR(%d)&" % ord(c) for c in expression)
41-
if unescaped[-1] == "&":
42-
unescaped = unescaped[:-1]
43-
44-
expression = unescaped
45-
46-
return expression
16+
def escaper(value):
17+
return "&".join("CHR(%d)" % ord(_) for _ in value)
4718

19+
return Syntax._escape(expression, quote, escaper)

plugins/dbms/db2/syntax.py

Lines changed: 3 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
See the file 'doc/COPYING' for copying permission
66
"""
77

8-
from lib.core.data import logger
9-
from lib.core.exception import SqlmapSyntaxException
108
from plugins.generic.syntax import Syntax as GenericSyntax
119

1210
class Syntax(GenericSyntax):
@@ -15,32 +13,7 @@ def __init__(self):
1513

1614
@staticmethod
1715
def escape(expression, quote=True):
18-
if expression == u"'''":
19-
return "CHR(%d)" % (ord("'"))
16+
def escaper(value):
17+
return "||".join("CHR(%d)" % ord(_) for _ in value)
2018

21-
if quote:
22-
while True:
23-
index = expression.find("'")
24-
if index == -1:
25-
break
26-
27-
firstIndex = index + 1
28-
index = expression[firstIndex:].find("'")
29-
30-
if index == -1:
31-
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
32-
33-
lastIndex = firstIndex + index
34-
old = "'%s'" % expression[firstIndex:lastIndex]
35-
unescaped = ""
36-
37-
for i in xrange(firstIndex, lastIndex):
38-
unescaped += "CHR(%d)" % (ord(expression[i]))
39-
if i < lastIndex - 1:
40-
unescaped += "||"
41-
42-
expression = expression.replace(old, unescaped)
43-
else:
44-
expression = "||".join("CHR(%d)" % ord(c) for c in expression)
45-
46-
return expression
19+
return Syntax._escape(expression, quote, escaper)

plugins/dbms/firebird/syntax.py

Lines changed: 6 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
"""
77

88
from lib.core.common import isDBMSVersionAtLeast
9-
from lib.core.exception import SqlmapSyntaxException
109
from plugins.generic.syntax import Syntax as GenericSyntax
1110

1211
class Syntax(GenericSyntax):
@@ -15,38 +14,10 @@ def __init__(self):
1514

1615
@staticmethod
1716
def escape(expression, quote=True):
18-
if isDBMSVersionAtLeast('2.1'):
19-
if expression == u"'''":
20-
return "ASCII_CHAR(%d)" % (ord("'"))
21-
22-
if quote:
23-
while True:
24-
index = expression.find("'")
25-
if index == -1:
26-
break
27-
28-
firstIndex = index + 1
29-
index = expression[firstIndex:].find("'")
30-
31-
if index == -1:
32-
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
33-
34-
lastIndex = firstIndex + index
35-
old = "'%s'" % expression[firstIndex:lastIndex]
36-
unescaped = ""
37-
38-
for i in xrange(firstIndex, lastIndex):
39-
unescaped += "ASCII_CHAR(%d)" % (ord(expression[i]))
40-
if i < lastIndex - 1:
41-
unescaped += "||"
42-
43-
expression = expression.replace(old, unescaped)
44-
else:
45-
unescaped = "".join("ASCII_CHAR(%d)||" % ord(c) for c in expression)
46-
if unescaped[-1] == "||":
47-
unescaped = unescaped[:-1]
48-
49-
expression = unescaped
50-
51-
return expression
17+
def escaper(value):
18+
retVal = value
19+
if isDBMSVersionAtLeast('2.1'):
20+
retVal = "||".join("ASCII_CHAR(%d)" % ord(_) for _ in value)
21+
return retVal
5222

23+
return Syntax._escape(expression, quote, escaper)

plugins/dbms/mssqlserver/syntax.py

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
See the file 'doc/COPYING' for copying permission
66
"""
77

8-
from lib.core.exception import SqlmapSyntaxException
98
from plugins.generic.syntax import Syntax as GenericSyntax
109

1110
class Syntax(GenericSyntax):
@@ -14,25 +13,7 @@ def __init__(self):
1413

1514
@staticmethod
1615
def escape(expression, quote=True):
17-
if quote:
18-
while True:
19-
index = expression.find("'")
20-
if index == -1:
21-
break
16+
def escaper(value):
17+
return "+".join("%s(%d)" % ("CHAR" if ord(value[i]) < 256 else "NCHAR", ord(value[i])) for i in xrange(len(value)))
2218

23-
firstIndex = index + 1
24-
index = expression[firstIndex:].find("'")
25-
26-
if index == -1:
27-
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
28-
29-
lastIndex = firstIndex + index
30-
old = "'%s'" % expression[firstIndex:lastIndex]
31-
32-
unescaped = "+".join("%s(%d)" % ("CHAR" if ord(expression[i]) < 256 else "NCHAR", ord(expression[i])) for i in xrange(firstIndex, lastIndex))
33-
34-
expression = expression.replace(old, unescaped)
35-
else:
36-
expression = "+".join("CHAR(%d)" % ord(c) for c in expression)
37-
38-
return expression
19+
return Syntax._escape(expression, quote, escaper)

plugins/dbms/mysql/syntax.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
"""
77

88
import binascii
9-
import re
109

1110
from lib.core.convert import utf8encode
12-
from lib.core.exception import SqlmapSyntaxException
1311
from plugins.generic.syntax import Syntax as GenericSyntax
1412

1513
class Syntax(GenericSyntax):
@@ -18,14 +16,12 @@ def __init__(self):
1816

1917
@staticmethod
2018
def escape(expression, quote=True):
21-
if quote:
22-
unescaped = expression
23-
for item in re.findall(r"'[^']+'", expression, re.S):
24-
try:
25-
unescaped = unescaped.replace(item, "0x%s" % binascii.hexlify(item.strip("'")))
26-
except UnicodeEncodeError:
27-
unescaped = unescaped.replace(item, "CONVERT(0x%s USING utf8)" % "".join("%.2x" % ord(_) for _ in utf8encode(item.strip("'"))))
28-
else:
29-
unescaped = "0x%s" % binascii.hexlify(expression)
19+
def escaper(value):
20+
retVal = None
21+
try:
22+
retVal = "0x%s" % binascii.hexlify(value.strip("'"))
23+
except UnicodeEncodeError:
24+
retVal = "CONVERT(0x%s USING utf8)" % "".join("%.2x" % ord(_) for _ in utf8encode(value.strip("'")))
25+
return retVal
3026

31-
return unescaped
27+
return Syntax._escape(expression, quote, escaper)

plugins/dbms/oracle/syntax.py

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
See the file 'doc/COPYING' for copying permission
66
"""
77

8-
from lib.core.exception import SqlmapSyntaxException
98
from plugins.generic.syntax import Syntax as GenericSyntax
109

1110
class Syntax(GenericSyntax):
@@ -14,24 +13,7 @@ def __init__(self):
1413

1514
@staticmethod
1615
def escape(expression, quote=True):
17-
if quote:
18-
while True:
19-
index = expression.find("'")
20-
if index == -1:
21-
break
16+
def escaper(value):
17+
return "||".join("%s(%d)" % ("CHR" if ord(value[i]) < 256 else "NCHR", ord(value[i])) for i in xrange(len(value)))
2218

23-
firstIndex = index + 1
24-
index = expression[firstIndex:].find("'")
25-
26-
if index == -1:
27-
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
28-
29-
lastIndex = firstIndex + index
30-
old = "'%s'" % expression[firstIndex:lastIndex]
31-
unescaped = "||".join("%s(%d)" % ("CHR" if ord(expression[i]) < 256 else "NCHR", ord(expression[i])) for i in xrange(firstIndex, lastIndex))
32-
33-
expression = expression.replace(old, unescaped)
34-
else:
35-
expression = "||".join("CHR(%d)" % ord(c) for c in expression)
36-
37-
return expression
19+
return Syntax._escape(expression, quote, escaper)

plugins/dbms/postgresql/syntax.py

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
See the file 'doc/COPYING' for copying permission
66
"""
77

8-
from lib.core.exception import SqlmapSyntaxException
98
from plugins.generic.syntax import Syntax as GenericSyntax
109

1110
class Syntax(GenericSyntax):
@@ -19,24 +18,7 @@ def escape(expression, quote=True):
1918
e.g. SELECT 1 WHERE 'a'!='a'||'b' will trigger error ("argument of WHERE must be type boolean, not type text")
2019
"""
2120

22-
if quote:
23-
while True:
24-
index = expression.find("'")
25-
if index == -1:
26-
break
21+
def escaper(value):
22+
return "(%s)" % "||".join("CHR(%d)" % ord(_) for _ in value) # Postgres CHR() function already accepts Unicode code point of character(s)
2723

28-
firstIndex = index + 1
29-
index = expression[firstIndex:].find("'")
30-
31-
if index == -1:
32-
raise SqlmapSyntaxException("Unenclosed ' in '%s'" % expression)
33-
34-
lastIndex = firstIndex + index
35-
old = "'%s'" % expression[firstIndex:lastIndex]
36-
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)
37-
38-
expression = expression.replace(old, unescaped)
39-
else:
40-
expression = "(%s)" % "||".join("CHR(%d)" % ord(c) for c in expression)
41-
42-
return expression
24+
return Syntax._escape(expression, quote, escaper)

plugins/dbms/sqlite/syntax.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66
"""
77

88
import binascii
9-
import re
109

1110
from lib.core.common import isDBMSVersionAtLeast
12-
from lib.core.exception import SqlmapSyntaxException
1311
from plugins.generic.syntax import Syntax as GenericSyntax
1412

1513
class Syntax(GenericSyntax):
@@ -18,13 +16,10 @@ def __init__(self):
1816

1917
@staticmethod
2018
def escape(expression, quote=True):
21-
unescaped = expression
19+
def escaper(value):
20+
retVal = value
21+
if isDBMSVersionAtLeast('3'):
22+
retVal = "X'%s'" % binascii.hexlify(value)
23+
return retVal
2224

23-
if isDBMSVersionAtLeast('3'):
24-
if quote:
25-
for item in re.findall(r"'[^']+'", expression, re.S):
26-
unescaped = unescaped.replace(item, "X'%s'" % binascii.hexlify(item.strip("'")))
27-
else:
28-
unescaped = "X'%s'" % binascii.hexlify(expression)
29-
30-
return unescaped
25+
return Syntax._escape(expression, quote, escaper)

0 commit comments

Comments
 (0)