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

Skip to content

Commit 6ebb621

Browse files
committed
adding support for (custom) POST injection (marking injection point with '*' in conf.data)
1 parent efd27d7 commit 6ebb621

6 files changed

Lines changed: 58 additions & 40 deletions

File tree

lib/controller/controller.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ def start():
368368
parameters = conf.parameters.keys()
369369

370370
# Order of testing list (last to first)
371-
orderList = (PLACE.URI, PLACE.GET, PLACE.POST)
371+
orderList = (PLACE.URI, PLACE.GET, PLACE.POST, PLACE.CUSTOM_POST)
372372

373373
for place in orderList:
374374
if place in parameters:

lib/core/agent.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from xml.etree import ElementTree as ET
1313

1414
from lib.core.common import Backend
15+
from lib.core.common import extractRegexResult
1516
from lib.core.common import isDBMSVersionAtLeast
1617
from lib.core.common import isTechniqueAvailable
1718
from lib.core.common import randomInt
@@ -62,9 +63,6 @@ def payload(self, place=None, parameter=None, value=None, newValue=None, where=N
6263
if where is None and isTechniqueAvailable(kb.technique):
6364
where = kb.injection.data[kb.technique].where
6465

65-
# Debug print
66-
#print "value: %s, newValue: %s, where: %s, kb.technique: %s" % (value, newValue, where, kb.technique)
67-
6866
if kb.injection.place is not None:
6967
place = kb.injection.place
7068

@@ -81,6 +79,9 @@ def payload(self, place=None, parameter=None, value=None, newValue=None, where=N
8179
for char in ('?', '=', ':'):
8280
if char in origValue:
8381
origValue = origValue[origValue.rfind(char) + 1:]
82+
elif place == PLACE.CUSTOM_POST:
83+
origValue = origValue.split(CUSTOM_INJECTION_MARK_CHAR)[0]
84+
origValue = extractRegexResult(r"(?s)(?P<result>(\W+\Z|\w+\Z))", origValue)
8485

8586
if value is None:
8687
if where == PAYLOAD.WHERE.ORIGINAL:
@@ -112,7 +113,7 @@ def payload(self, place=None, parameter=None, value=None, newValue=None, where=N
112113
child.text = self.addPayloadDelimiters(newValue)
113114

114115
retValue = ET.tostring(root)
115-
elif place == PLACE.URI:
116+
elif place in (PLACE.URI, PLACE.CUSTOM_POST):
116117
retValue = paramString.replace("%s%s" % (origValue, CUSTOM_INJECTION_MARK_CHAR), self.addPayloadDelimiters(newValue))
117118
elif place in (PLACE.UA, PLACE.REFERER, PLACE.HOST):
118119
retValue = paramString.replace(origValue, self.addPayloadDelimiters(newValue))

lib/core/enums.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class PLACE:
6666
UA = "User-Agent"
6767
REFERER = "Referer"
6868
HOST = "Host"
69+
CUSTOM_POST = "(custom) POST"
6970

7071
class HTTPMETHOD:
7172
GET = "GET"

lib/core/option.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,6 +1473,7 @@ def __setKnowledgeBaseAttributes(flushAll=True):
14731473
kb.pageTemplate = None
14741474
kb.pageTemplates = dict()
14751475
kb.previousMethod = None
1476+
kb.processUserMarks = None
14761477
kb.orderByColumns = None
14771478
kb.originalCode = None
14781479
kb.originalPage = None

lib/core/target.py

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,16 @@ def __setRequestParams():
5959
conf.parameters[None] = "direct connection"
6060
return
6161

62-
__testableParameters = False
62+
testableParameters = False
6363

6464
# Perform checks on GET parameters
6565
if conf.parameters.has_key(PLACE.GET) and conf.parameters[PLACE.GET]:
6666
parameters = conf.parameters[PLACE.GET]
67-
__paramDict = paramToDict(PLACE.GET, parameters)
67+
paramDict = paramToDict(PLACE.GET, parameters)
6868

69-
if __paramDict:
70-
conf.paramDict[PLACE.GET] = __paramDict
71-
__testableParameters = True
69+
if paramDict:
70+
conf.paramDict[PLACE.GET] = paramDict
71+
testableParameters = True
7272

7373
# Perform checks on POST parameters
7474
if conf.method == HTTPMETHOD.POST and not conf.data:
@@ -83,18 +83,17 @@ def __setRequestParams():
8383
else:
8484
conf.data = conf.data.replace("\n", " ")
8585

86-
# Check if POST data is in xml syntax
8786
if re.match(SOAP_REGEX, conf.data, re.I | re.M):
8887
place = PLACE.SOAP
8988
else:
9089
place = PLACE.POST
9190

9291
conf.parameters[place] = conf.data
93-
__paramDict = paramToDict(place, conf.data)
92+
paramDict = paramToDict(place, conf.data)
9493

95-
if __paramDict:
96-
conf.paramDict[place] = __paramDict
97-
__testableParameters = True
94+
if paramDict:
95+
conf.paramDict[place] = paramDict
96+
testableParameters = True
9897

9998
conf.method = HTTPMETHOD.POST
10099

@@ -109,40 +108,52 @@ def __setRequestParams():
109108
message += "in the target url itself? [Y/n/q] "
110109
test = readInput(message, default="Y")
111110

112-
if not test or test[0] in ("y", "Y"):
111+
if not test or test[0] not in ("n", "N"):
113112
conf.url = "%s%s" % (conf.url, CUSTOM_INJECTION_MARK_CHAR)
114-
elif test[0] in ("n", "N"):
115-
pass
113+
kb.processUserMarks = True
116114
elif test[0] in ("q", "Q"):
117115
raise sqlmapUserQuitException
118116

119-
if CUSTOM_INJECTION_MARK_CHAR in conf.url:
120-
conf.parameters[PLACE.URI] = conf.url
121-
conf.paramDict[PLACE.URI] = {}
122-
parts = conf.url.split(CUSTOM_INJECTION_MARK_CHAR)
117+
for place, value in ((PLACE.URI, conf.url), (PLACE.CUSTOM_POST, conf.data)):
118+
if CUSTOM_INJECTION_MARK_CHAR in (value or ""):
119+
if kb.processUserMarks is None:
120+
message = "custom injection mark ('%s') found in " % CUSTOM_INJECTION_MARK_CHAR
121+
message += "'%s'. Do you want to process it? [Y/n/q] " % {PLACE.URI: '-u', PLACE.CUSTOM_POST: '--data'}[place]
122+
test = readInput(message, default="Y")
123+
if test and test[0] in ("q", "Q"):
124+
raise sqlmapUserQuitException
125+
else:
126+
kb.processUserMarks = not test or test[0] not in ("n", "N")
123127

124-
for i in xrange(len(parts)-1):
125-
result = str()
128+
if not kb.processUserMarks:
129+
continue
126130

127-
for j in xrange(len(parts)):
128-
result += parts[j]
131+
conf.parameters[place] = value
132+
conf.paramDict[place] = {}
133+
parts = value.split(CUSTOM_INJECTION_MARK_CHAR)
129134

130-
if i == j:
131-
result += CUSTOM_INJECTION_MARK_CHAR
135+
for i in xrange(len(parts) - 1):
136+
conf.paramDict[place]["#%d%s" % (i + 1, CUSTOM_INJECTION_MARK_CHAR)] = "".join("%s%s" % (parts[j], CUSTOM_INJECTION_MARK_CHAR if i == j else "") for j in xrange(len(parts)))
132137

133-
conf.paramDict[PLACE.URI]["#%d%s" % (i+1, CUSTOM_INJECTION_MARK_CHAR)] = result
138+
if place == PLACE.URI and PLACE.GET in conf.paramDict:
139+
del conf.paramDict[PLACE.GET]
140+
elif place == PLACE.CUSTOM_POST and PLACE.POST in conf.paramDict:
141+
del conf.paramDict[PLACE.POST]
134142

135-
conf.url = conf.url.replace(CUSTOM_INJECTION_MARK_CHAR, str())
136-
__testableParameters = True
143+
testableParameters = True
144+
145+
if kb.processUserMarks:
146+
conf.url = conf.url.replace(CUSTOM_INJECTION_MARK_CHAR, "")
147+
conf.data = conf.data.replace(CUSTOM_INJECTION_MARK_CHAR, "") if conf.data else conf.data
137148

138149
# Perform checks on Cookie parameters
139150
if conf.cookie:
140151
conf.parameters[PLACE.COOKIE] = conf.cookie
141-
__paramDict = paramToDict(PLACE.COOKIE, conf.cookie)
152+
paramDict = paramToDict(PLACE.COOKIE, conf.cookie)
142153

143-
if __paramDict:
144-
conf.paramDict[PLACE.COOKIE] = __paramDict
145-
__testableParameters = True
154+
if paramDict:
155+
conf.paramDict[PLACE.COOKIE] = paramDict
156+
testableParameters = True
146157

147158
# Perform checks on header values
148159
if conf.httpHeaders:
@@ -157,7 +168,7 @@ def __setRequestParams():
157168

158169
if condition:
159170
conf.paramDict[PLACE.UA] = { PLACE.UA: headerValue }
160-
__testableParameters = True
171+
testableParameters = True
161172

162173
elif httpHeader == PLACE.REFERER:
163174
conf.parameters[PLACE.REFERER] = urldecode(headerValue)
@@ -166,7 +177,7 @@ def __setRequestParams():
166177

167178
if condition:
168179
conf.paramDict[PLACE.REFERER] = { PLACE.REFERER: headerValue }
169-
__testableParameters = True
180+
testableParameters = True
170181

171182
elif httpHeader == PLACE.HOST:
172183
conf.parameters[PLACE.HOST] = urldecode(headerValue)
@@ -175,14 +186,14 @@ def __setRequestParams():
175186

176187
if condition:
177188
conf.paramDict[PLACE.HOST] = { PLACE.HOST: headerValue }
178-
__testableParameters = True
189+
testableParameters = True
179190

180191
if not conf.parameters:
181192
errMsg = "you did not provide any GET, POST and Cookie "
182193
errMsg += "parameter, neither an User-Agent, Referer or Host header value"
183194
raise sqlmapGenericException, errMsg
184195

185-
elif not __testableParameters:
196+
elif not testableParameters:
186197
errMsg = "all testable parameters you provided are not present "
187198
errMsg += "within the GET, POST and Cookie parameters"
188199
raise sqlmapGenericException, errMsg

lib/request/connect.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
from lib.core.enums import REDIRECTION
5252
from lib.core.exception import sqlmapConnectionException
5353
from lib.core.exception import sqlmapSyntaxException
54+
from lib.core.settings import CUSTOM_INJECTION_MARK_CHAR
5455
from lib.core.settings import HTTP_ACCEPT_HEADER_VALUE
5556
from lib.core.settings import HTTP_SILENT_TIMEOUT
5657
from lib.core.settings import MAX_CONNECTION_CHUNK_SIZE
@@ -557,7 +558,7 @@ def queryPage(value=None, place=None, content=False, getRatioValue=False, silent
557558
value = urlEncodeCookieValues(value)
558559

559560
elif place:
560-
if place in (PLACE.GET, PLACE.POST, PLACE.URI):
561+
if place in (PLACE.GET, PLACE.POST, PLACE.URI, PLACE.CUSTOM_POST):
561562
# payloads in GET and/or POST need to be urlencoded
562563
# throughly without safe chars (especially & and =)
563564
# addendum: as we support url encoding in tampering
@@ -582,6 +583,9 @@ def queryPage(value=None, place=None, content=False, getRatioValue=False, silent
582583
if PLACE.POST in conf.parameters:
583584
post = conf.parameters[PLACE.POST] if place != PLACE.POST or not value else value
584585

586+
if PLACE.CUSTOM_POST in conf.parameters:
587+
post = conf.parameters[PLACE.CUSTOM_POST].replace(CUSTOM_INJECTION_MARK_CHAR, "") if place != PLACE.CUSTOM_POST or not value else value
588+
585589
if PLACE.SOAP in conf.parameters:
586590
post = conf.parameters[PLACE.SOAP] if place != PLACE.SOAP or not value else value
587591

0 commit comments

Comments
 (0)