for targetUrl, targetMethod, targetData, targetCookie, targetHeaders in kb.targets: targetCount += 1 …… try: if conf.checkInternet: ……
1.2.1 使用 —check-internet 命令
检测是否连接到互联网。若没有也会尝试重连,超出配置次数后会报错并退出程序。
1.2.2 执行注入的预处理
对 conf 的 data 部分执行 URL 编码并删除请求头中重复内容
if conf.data: conf.data = re.sub(r"\b(__\w+)=([^&]+)", lambda match: "%s=%s" % (match.group(1), urlencode(match.group(2), safe='%')), conf.data) conf.httpHeaders = [conf.httpHeaders[i] for i in xrange(len(conf.httpHeaders)) if conf.httpHeaders[i][0].upper() not in (__[0].upper() for __ in conf.httpHeaders[i + 1:])]
# 判断是否需要测试SQL注入testSqlInj = False# 检测每个参数是否未被测试过SQL注入if PLACE.GET in conf.parameters and not any((conf.data, conf.testParameter)): for parameter in re.findall(r"([^=]+)=([^%s]+%s?|\Z)" % (re.escape(conf.paramDel or "") or DEFAULT_GET_POST_DELIMITER, re.escape(conf.paramDel or "") or DEFAULT_GET_POST_DELIMITER), conf.parameters[PLACE.GET]): paramKey = (conf.hostname, conf.path, PLACE.GET, parameter[0]) # 如果参数未被测试过,则设置testSqlInj为True并跳出循环 if paramKey not in kb.testedParams: testSqlInj = True breakelse: paramKey = (conf.hostname, conf.path, None, None) if paramKey not in kb.testedParams: testSqlInj = True# 如果需要测试SQL注入且当前主机已被标记为存在漏洞,询问是否跳过此主机的后续测试if testSqlInj and conf.hostname in kb.vulnHosts: if kb.skipVulnHost is None: message = "SQL injection vulnerability has already been detected " message += "against '%s'. Do you want to skip " % conf.hostname message += "further tests involving it? [Y/n]" # 读取用户输入,决定是否跳过此主机的测试,保存到环境变量 kb kb.skipVulnHost = readInput(message, default='Y', boolean=True) # 根据用户选择决定是否继续测试此主机 testSqlInj = not kb.skipVulnHost # 如果不需要测试SQL注入,则记录信息并跳过当前目标URL的测试if not testSqlInj: infoMsg = "skipping '%s'" % targetUrl logger.info(infoMsg) continue
询问用户是否测试表单,可由用户输入请求包中的 data 信息,并重新解析目标 URL ,设置目标环境
根据原始页面的 <select> 标签,更新 kb 的随机池
# 如果conf.rParam为真且原始页面已知,进行以下操作if conf.rParam and kb.originalPage: # 确保randomPool中的每个值都是列表类型 kb.randomPool = dict([_ for _ in kb.randomPool.items() if isinstance(_[1], list)]) # 遍历原始页面中所有<select>元素,提取name和options for match in re.finditer(r"(?si)<select[^>]+\bname\s*=\s*[\"']([^\"']+)(.+?)</select>", kb.originalPage): name, _ = match.groups() # 提取每个<select>元素中的<option>值 options = tuple(re.findall(r"<option[^>]+\bvalue\s*=\s*[\"']([^\"']+)", _)) # 如果找到选项值,则更新randomPool if options: kb.randomPool[name] = options
if kb.injection.place is not None and kb.injection.parameter is not None: if conf.multipleTargets: message = "do you want to exploit this SQL injection? [Y/n] " condition = readInput(message, default='Y', boolean=True) else: condition = Trueif condition: # 执行SQL注入攻击 action()