Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c3a95e8

Browse files
committed
Fixes #3797
1 parent c1ae1b4 commit c3a95e8

3 files changed

Lines changed: 32 additions & 96 deletions

File tree

lib/core/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from thirdparty.six import unichr as _unichr
1919

2020
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
21-
VERSION = "1.3.7.18"
21+
VERSION = "1.3.7.19"
2222
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2323
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2424
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

tamper/plus2concat.py

Lines changed: 12 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
from lib.core.common import singleTimeWarnMessage
1212
from lib.core.common import zeroDepthSearch
13-
from lib.core.compat import xrange
1413
from lib.core.enums import DBMS
1514
from lib.core.enums import PRIORITY
1615

@@ -35,51 +34,22 @@ def tamper(payload, **kwargs):
3534
>>> tamper('SELECT CHAR(113)+CHAR(114)+CHAR(115) FROM DUAL')
3635
'SELECT CONCAT(CHAR(113),CHAR(114),CHAR(115)) FROM DUAL'
3736
38-
>>> tamper('SELECT (CHAR(113)+CHAR(114)+CHAR(115)) FROM DUAL')
39-
'SELECT CONCAT(CHAR(113),CHAR(114),CHAR(115)) FROM DUAL'
37+
>>> tamper('1 UNION ALL SELECT NULL,NULL,CHAR(113)+CHAR(118)+CHAR(112)+CHAR(112)+CHAR(113)+ISNULL(CAST(@@VERSION AS NVARCHAR(4000)),CHAR(32))+CHAR(113)+CHAR(112)+CHAR(107)+CHAR(112)+CHAR(113)-- qtfe')
38+
'1 UNION ALL SELECT NULL,NULL,CONCAT(CHAR(113),CHAR(118),CHAR(112),CHAR(112),CHAR(113),ISNULL(CAST(@@VERSION AS NVARCHAR(4000)),CHAR(32)),CHAR(113),CHAR(112),CHAR(107),CHAR(112),CHAR(113))-- qtfe'
4039
"""
4140

4241
retVal = payload
4342

4443
if payload:
45-
prefix, suffix = '+' * len(re.search(r"\A(\+*)", payload).group(0)), '+' * len(re.search(r"(\+*)\Z", payload).group(0))
46-
retVal = retVal.strip('+')
47-
48-
while True:
49-
indexes = zeroDepthSearch(retVal, '+')
50-
51-
if indexes:
52-
first, last = 0, 0
53-
for i in xrange(1, len(indexes)):
54-
if ' ' in retVal[indexes[0]:indexes[i]]:
55-
break
56-
else:
57-
last = i
58-
59-
start = retVal[:indexes[first]].rfind(' ') + 1
60-
end = (retVal[indexes[last] + 1:].find(' ') + indexes[last] + 1) if ' ' in retVal[indexes[last] + 1:] else len(retVal) - 1
61-
62-
chars = [char for char in retVal]
63-
for index in indexes[first:last + 1]:
64-
chars[index] = ','
65-
66-
retVal = "%sCONCAT(%s)%s" % (retVal[:start], ''.join(chars)[start:end], retVal[end:])
67-
else:
68-
match = re.search(r"\((CHAR\(\d+.+\bCHAR\(\d+\))\)", retVal)
69-
if match:
70-
part = match.group(0)
71-
indexes = set(zeroDepthSearch(match.group(1), '+'))
72-
if not indexes:
73-
break
74-
chars = [char for char in part]
75-
for i in xrange(1, len(chars)):
76-
if i - 1 in indexes:
77-
chars[i] = ','
78-
replacement = "CONCAT%s" % "".join(chars)
79-
retVal = retVal.replace(part, replacement)
80-
else:
81-
break
82-
83-
retVal = "%s%s%s" % (prefix, retVal, suffix)
44+
match = re.search(r"('[^']+'|CHAR\(\d+\))\+.*(?<=\+)('[^']+'|CHAR\(\d+\))", retVal)
45+
if match:
46+
part = match.group(0)
47+
48+
chars = [char for char in part]
49+
for index in zeroDepthSearch(part, '+'):
50+
chars[index] = ','
51+
52+
replacement = "CONCAT(%s)" % "".join(chars)
53+
retVal = retVal.replace(part, replacement)
8454

8555
return retVal

tamper/plus2fnconcat.py

Lines changed: 19 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -36,63 +36,29 @@ def tamper(payload, **kwargs):
3636
>>> tamper('SELECT CHAR(113)+CHAR(114)+CHAR(115) FROM DUAL')
3737
'SELECT {fn CONCAT({fn CONCAT(CHAR(113),CHAR(114))},CHAR(115))} FROM DUAL'
3838
39-
>>> tamper('SELECT (CHAR(113)+CHAR(114)+CHAR(115)) FROM DUAL')
40-
'SELECT {fn CONCAT({fn CONCAT(CHAR(113),CHAR(114))},CHAR(115))} FROM DUAL'
39+
>>> tamper('1 UNION ALL SELECT NULL,NULL,CHAR(113)+CHAR(118)+CHAR(112)+CHAR(112)+CHAR(113)+ISNULL(CAST(@@VERSION AS NVARCHAR(4000)),CHAR(32))+CHAR(113)+CHAR(112)+CHAR(107)+CHAR(112)+CHAR(113)-- qtfe')
40+
'1 UNION ALL SELECT NULL,NULL,{fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT({fn CONCAT(CHAR(113),CHAR(118))},CHAR(112))},CHAR(112))},CHAR(113))},ISNULL(CAST(@@VERSION AS NVARCHAR(4000)),CHAR(32)))},CHAR(113))},CHAR(112))},CHAR(107))},CHAR(112))},CHAR(113))}-- qtfe'
4141
"""
4242

4343
retVal = payload
4444

4545
if payload:
46-
prefix, suffix = '+' * len(re.search(r"\A(\+*)", payload).group(0)), '+' * len(re.search(r"(\+*)\Z", payload).group(0))
47-
retVal = retVal.strip('+')
48-
49-
while True:
50-
indexes = zeroDepthSearch(retVal, '+')
51-
52-
if indexes:
53-
first, last = 0, 0
54-
for i in xrange(1, len(indexes)):
55-
if ' ' in retVal[indexes[0]:indexes[i]]:
56-
break
57-
else:
58-
last = i
59-
60-
start = retVal[:indexes[first]].rfind(' ') + 1
61-
end = (retVal[indexes[last] + 1:].find(' ') + indexes[last] + 1) if ' ' in retVal[indexes[last] + 1:] else len(retVal) - 1
62-
63-
count = 0
64-
chars = [char for char in retVal]
65-
for index in indexes[first:last + 1]:
66-
if count == 0:
67-
chars[index] = ','
68-
else:
69-
chars[index] = '\x01'
70-
count += 1
71-
72-
retVal = "%s%s%s)}%s" % (retVal[:start], "{fn CONCAT(" * count, ''.join(chars)[start:end].replace('\x01', ")},"), retVal[end:])
73-
else:
74-
match = re.search(r"\((CHAR\(\d+.+\bCHAR\(\d+\))\)", retVal)
75-
if match:
76-
part = match.group(0)
77-
indexes = set(zeroDepthSearch(match.group(1), '+'))
78-
if not indexes:
79-
break
80-
81-
count = 0
82-
chars = [char for char in part]
83-
for i in xrange(1, len(chars)):
84-
if i - 1 in indexes:
85-
if count == 0:
86-
chars[i] = ','
87-
else:
88-
chars[i] = '\x01'
89-
count += 1
90-
91-
replacement = "%s%s}" % (("{fn CONCAT(" * count)[:-1], "".join(chars).replace('\x01', ")},"))
92-
retVal = retVal.replace(part, replacement)
93-
else:
94-
break
95-
96-
retVal = "%s%s%s" % (prefix, retVal, suffix)
46+
match = re.search(r"('[^']+'|CHAR\(\d+\))\+.*(?<=\+)('[^']+'|CHAR\(\d+\))", retVal)
47+
if match:
48+
old = match.group(0)
49+
parts = []
50+
last = 0
51+
52+
for index in zeroDepthSearch(old, '+'):
53+
parts.append(old[last:index].strip('+'))
54+
last = index
55+
56+
parts.append(old[last:].strip('+'))
57+
replacement = parts[0]
58+
59+
for i in xrange(1, len(parts)):
60+
replacement = "{fn CONCAT(%s,%s)}" % (replacement, parts[i])
61+
62+
retVal = retVal.replace(old, replacement)
9763

9864
return retVal

0 commit comments

Comments
 (0)