1 defstart():2 """
3 This function calls a function that performs checks on both URL4 stability and all GET, POST, Cookie and User-Agent parameters to5 check if they are dynamic and SQL injection affected6 """
7 if notconf.start:8 returnFalse9
10 ifconf.direct:11 initTargetEnv()12 setupTargetEnv()13 action()14 returnTrue15
16 if conf.url and notconf.forms:17 kb.targetUrls.add(( conf.url, conf.method, conf.data, conf.cookie ))18
19 if conf.configFile and notkb.targetUrls:20 errMsg = "you did not edit the configuration file properly, set"
21 errMsg += "the target url, list of targets or google dork"
22 logger.error(errMsg)23 returnFalse24
25 if kb.targetUrls and len(kb.targetUrls) > 1:26 infoMsg = "sqlmap got a total of %d targets" %len(kb.targetUrls)27 logger.info(infoMsg)28
29 hostCount =030 cookieStr = ""
31 setCookieAsInjectable =True32
33 for targetUrl, targetMethod, targetData, targetCookie inkb.targetUrls:34 try:35 conf.url =targetUrl36 conf.method =targetMethod37 conf.data =targetData38 conf.cookie =targetCookie39 initTargetEnv()40 parseTargetUrl()41
42 testSqlInj =False43 if PLACE.GET inconf.parameters:44 for parameter in re.findall(r"([^=]+)=[^&]+&?", conf.parameters[PLACE.GET]):45 paramKey =(conf.hostname, conf.path, PLACE.GET, parameter)46 if paramKey not inkb.testedParams:47 testSqlInj =True48 break
49 else:50 paramKey =(conf.hostname, conf.path, None, None)51 if paramKey not inkb.testedParams:52 testSqlInj =True53
54 testSqlInj &= (conf.hostname, conf.path, None, None) not inkb.testedParams55
56 if nottestSqlInj:57 infoMsg = "skipping '%s'" %targetUrl58 logger.info(infoMsg)59 continue
60
61 ifconf.multipleTargets:62 hostCount += 1
63 ifconf.forms:64 message = "[#%d] form:\n%s %s" % (hostCount, conf.method orHTTPMETHOD.GET, targetUrl)65 else:66 message = "url %d:\n%s %s%s" % (hostCount, conf.method or HTTPMETHOD.GET, targetUrl, "(PageRank: %s)" % get_pagerank(targetUrl) if conf.googleDork and conf.pageRank else "")67
68 ifconf.cookie:69 message += "\nCookie: %s" %conf.cookie70
71 ifconf.data:72 message += "\nPOST data: %s" % urlencode(conf.data) if conf.data else ""
73
74 ifconf.forms:75 if conf.method == HTTPMETHOD.GET and targetUrl.find("?") == -1:76 continue
77
78 message += "\ndo you want to test this form? [Y/n/q]"
79 test = readInput(message, default="Y")80
81 if not test or test[0] in ("y", "Y"):82 if conf.method ==HTTPMETHOD.POST:83 message = "Edit POST data [default: %s]%s:" % (urlencode(conf.data) if conf.data else "None", "(Warning: blank fields detected)" if conf.data and extractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data) else "")84 conf.data = readInput(message, default=conf.data)85 ifextractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data):86 message = "do you want to fill blank fields with random values? [Y/n]"
87 test = readInput(message, default="Y")88 if not test or test[0] in ("y", "Y"):89 whileextractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data):90 item =extractRegexResult(EMPTY_FORM_FIELDS_REGEX, conf.data)91 if item[-1] == '&':92 conf.data = conf.data.replace(item, "%s%s&" % (item[:-1], randomStr()))93 else:94 conf.data = conf.data.replace(item, "%s%s" %(item, randomStr()))95 conf.data =urldecode(conf.data)96
97 elif conf.method ==HTTPMETHOD.GET:98 if conf.url.find("?") > -1:99 firstPart = conf.url[:conf.url.find("?")]100 secondPart = conf.url[conf.url.find("?")+1:]101 message = "Edit GET data [default: %s]:" %secondPart102 test = readInput(message, default=secondPart)103 conf.url = "%s?%s" %(firstPart, test)104
105 elif test[0] in ("n", "N"):106 continue
107 elif test[0] in ("q", "Q"):108 break
109
110 elifconf.realTest:111 logger.info(message)112 else:113 message += "\ndo you want to test this url? [Y/n/q]"
114 test = readInput(message, default="Y")115
116 if not test or test[0] in ("y", "Y"):117 pass
118 elif test[0] in ("n", "N"):119 continue
120 elif test[0] in ("q", "Q"):121 break
122
123 logMsg = "testing url %s" %targetUrl124 logger.info(logMsg)125
126 setupTargetEnv()127 if not checkConnection(suppressOutput = conf.forms) or not checkString() or notcheckRegexp():128 continue
129
130 ifconf.nullConnection:131 checkNullConnection()132
133 if not conf.dropSetCookie andconf.cj:134 for _, cookie inenumerate(conf.cj):135 cookie =getUnicode(cookie)136 index = cookie.index("for")137
138 cookieStr += "%s;" % cookie[8:index]139
140 ifcookieStr:141 cookieStr = cookieStr[:-1]142
143 if PLACE.COOKIE inconf.parameters:144 message = "you provided an HTTP Cookie header value."
145 message += "The target url provided its own Cookie within"
146 message += "the HTTP Set-Cookie header. Do you want to"
147 message += "continue using the HTTP Cookie values that"
148 message += "you provided? [Y/n]"
149 test = readInput(message, default="Y")150
151 if not test or test[0] in ("y", "Y"):152 setCookieAsInjectable =False153
154 ifsetCookieAsInjectable:155 conf.httpHeaders.append(("Cookie", cookieStr))156 conf.parameters[PLACE.COOKIE] =cookieStr157 __paramDict =paramToDict(PLACE.COOKIE, cookieStr)158
159 if __paramDict:160 conf.paramDict[PLACE.COOKIE] = __paramDict
161 #TODO: consider the following line in __setRequestParams()
162 #__testableParameters = True
163
164 if (len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place isNone)) \165 and (kb.injection.place is None or kb.injection.parameter isNone):166 if not conf.string and notconf.regexp:167 #NOTE: this is not needed anymore, leaving only to display
168 #a warning message to the user in case the page is not stable
169 checkStability()170
171 #Do a little prioritization reorder of a testable parameter list
172 parameters =conf.parameters.keys()173
174 #Order of testing list (last to first)
175 orderList =(PLACE.URI, PLACE.GET, PLACE.POST)176
177 for place inorderList:178 if place inparameters:179 parameters.remove(place)180 parameters.insert(0, place)181
182 proceed =True183
184 for place inparameters:185 #Test User-Agent and Referer headers only if
186 #--level >= 3
187 skip = (place == PLACE.UA and conf.level < 3)188 skip |= (place == PLACE.REFERER and conf.level < 3)189
190 #Test Cookie header only if --level >= 2
191 skip |= (place == PLACE.COOKIE and conf.level < 2)192
193 skip &= not (place == PLACE.UA andintersect(USER_AGENT_ALIASES, conf.testParameter))194 skip &= not (place == PLACE.REFERER andintersect(REFERER_ALIASES, conf.testParameter))195
196 ifskip:197 continue
198
199 if notconf.paramDict.has_key(place):200 continue
201
202 paramDict =conf.paramDict[place]203 for parameter, value inparamDict.items():204 if notproceed:205 break
206
207 testSqlInj =True208
209 paramKey =(conf.hostname, conf.path, place, parameter)210
211 if paramKey inkb.testedParams:212 testSqlInj =False213
214 infoMsg = "skipping previously processed %s parameter '%s'" %(place, parameter)215 logger.info(infoMsg)216
217 #Avoid dinamicity test if the user provided the
218 #parameter manually
219 elif parameter in conf.testParameter orconf.realTest:220 pass
221
222 elif notcheckDynParam(place, parameter, value):223 warnMsg = "%s parameter '%s' is not dynamic" %(place, parameter)224 logger.warn(warnMsg)225
226 else:227 logMsg = "%s parameter '%s' is dynamic" %(place, parameter)228 logger.info(logMsg)229
230 kb.testedParams.add(paramKey)231
232 iftestSqlInj:233 check =heuristicCheckSqlInjection(place, parameter)234 if not check and conf.realTest and\235 notsimpletonCheckSqlInjection(place, parameter, value):236 continue
237
238 logMsg = "testing sql injection on %s" %place239 logMsg += "parameter '%s'" %parameter240 logger.info(logMsg)241
242 injection =checkSqlInjection(place, parameter, value)243 proceed = notkb.endDetection244
245 if injection is not None and injection.place is notNone:246 kb.injections.append(injection)247
248 #In case when user wants to end detection phase (Ctrl+C)
249 if notproceed:250 break
251
252 msg = "%s parameter '%s'" %(injection.place, injection.parameter)253 msg += "is vulnerable. Do you want to keep testing the others? [y/N]"
254 test = readInput(msg, default="N")255
256 if test[0] in ("n", "N"):257 proceed =False258 paramKey =(conf.hostname, conf.path, None, None)259 kb.testedParams.add(paramKey)260 else:261 warnMsg = "%s parameter '%s' is not" %(place, parameter)262 warnMsg += "injectable"
263 logger.warn(warnMsg)264
265 if len(kb.injections) == 0 or (len(kb.injections) == 1 and kb.injections[0].place isNone):266 if notconf.realTest:267 errMsg = "all parameters are not injectable, try to"
268 errMsg += "increase --level/--risk values to perform"
269 errMsg += "more tests."
270
271 if isinstance(conf.tech, list) and len(conf.tech) >0:272 errMsg += "Rerun without providing the --technique switch."
273
274 if not conf.textOnly andkb.originalPage:275 percent = (100.0 * len(getFilteredPageContent(kb.originalPage)) /len(kb.originalPage))276 errMsg += "Give it a go with the --text-only switch"
277 errMsg += "if the target page has a low percentage of"
278 errMsg += "textual content (~%.2f%% of" %percent279 errMsg += "page content is text)"
280
281 raisesqlmapNotVulnerableException, errMsg282 else:283 errMsg = "it seems that all parameters are not injectable"
284 raisesqlmapNotVulnerableException, errMsg285 else:286 #Flush the flag
287 kb.testMode =False288
289 __saveToSessionFile()290 __showInjections()291 __selectInjection()292
293 if kb.injection.place is not None and kb.injection.parameter is notNone:294 if kb.testQueryCount == 0 andconf.realTest:295 condition =False296 elifconf.multipleTargets:297 message = "do you want to exploit this SQL injection? [Y/n]"
298 exploit = readInput(message, default="Y")299
300 condition = not exploit or exploit[0] in ("y", "Y")301 else:302 condition =True303 ifcondition:304 action()305
306 exceptKeyboardInterrupt:307 ifconf.multipleTargets:308 warnMsg = "user aborted in multiple target mode"
309 logger.warn(warnMsg)310
311 message = "do you want to skip to the next target in list? [Y/n/q]"
312 test = readInput(message, default="Y")313
314 if not test or test[0] in ("y", "Y"):315 pass
316 elif test[0] in ("n", "N"):317 returnFalse318 elif test[0] in ("q", "Q"):319 raisesqlmapUserQuitException320 else:321 raise
322
323 exceptsqlmapUserQuitException:324 raise
325
326 exceptsqlmapSilentQuitException:327 raise
328
329 exceptexceptionsTuple, e:330 e =getUnicode(e)331
332 ifconf.multipleTargets:333 e += ", skipping to the next %s" % ("form" if conf.forms else "url")334 logger.error(e)335 else:336 logger.critical(e)337 returnFalse338
339 finally:340 showHttpErrorCodes()341
342 if conf.loggedToOut and notconf.multipleTargets:343 logger.info("Fetched data logged to text files under '%s'" %conf.outputPath)344
345 return True