add comments to inject.py

pull/3/head
wang 2 months ago
parent 33945c2dbd
commit f6b4a8f04f

@ -314,30 +314,42 @@ def _goBooleanProxy(expression):
Retrieve the output of a boolean based SQL query
"""
# 初始化技术
initTechnique(getTechnique())
# 如果配置了dns域名
if conf.dnsDomain:
# 获取查询语句
query = agent.prefixQuery(getTechniqueData().vector)
query = agent.suffixQuery(query)
# 获取payload
payload = agent.payload(newValue=query)
# 执行dns查询
output = _goDns(payload, expression)
# 如果查询结果不为空,则返回
if output is not None:
return output
# 获取查询语句
vector = getTechniqueData().vector
vector = vector.replace(INFERENCE_MARKER, expression)
query = agent.prefixQuery(vector)
query = agent.suffixQuery(query)
# 获取payload
payload = agent.payload(newValue=query)
# 判断是否是时间相关的技术
timeBasedCompare = getTechnique() in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED)
# 从hash数据库中获取查询结果
output = hashDBRetrieve(expression, checkConf=True)
# 如果查询结果为空,则执行查询
if output is None:
output = Request.queryPage(payload, timeBasedCompare=timeBasedCompare, raise404=False)
# 如果查询结果不为空则将结果写入hash数据库
if output is not None:
hashDBWrite(expression, output)
@ -349,8 +361,10 @@ def _goUnion(expression, unpack=True, dump=False):
injection vulnerability on the affected parameter.
"""
# 执行联合查询
output = unionUse(expression, unpack=unpack, dump=dump)
# 如果输出是字符串类型,则解析输出
if isinstance(output, six.string_types):
output = parseUnionPage(output)
@ -364,6 +378,7 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
affected parameter.
"""
# 如果配置了hex转换并且数据库类型已知则设置字符集类型为十六进制
if conf.hexConvert and expected != EXPECTED.BOOL and Backend.getIdentifiedDbms():
if not hasattr(queries[Backend.getIdentifiedDbms()], "hex"):
warnMsg = "switch '--hex' is currently not supported on DBMS %s" % Backend.getIdentifiedDbms()
@ -372,31 +387,39 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
else:
charsetType = CHARSET_TYPE.HEXADECIMAL
# 设置安全字符编码和恢复值
kb.safeCharEncode = safeCharEncode
kb.resumeValues = resumeValue
# 将表达式中的关键字转换为大写
for keyword in GET_VALUE_UPPERCASE_KEYWORDS:
expression = re.sub(r"(?i)(\A|\(|\)|\s)%s(\Z|\(|\)|\s)" % keyword, r"\g<1>%s\g<2>" % keyword, expression)
# 如果抑制输出不为空,则设置当前线程的抑制输出
if suppressOutput is not None:
pushValue(getCurrentThreadData().disableStdOut)
getCurrentThreadData().disableStdOut = suppressOutput
try:
# 保存当前数据库和表
pushValue(conf.db)
pushValue(conf.tbl)
# 如果期望的输出是布尔类型
if expected == EXPECTED.BOOL:
forgeCaseExpression = booleanExpression = expression
# 如果表达式以SELECT开头则将表达式转换为布尔表达式
if expression.startswith("SELECT "):
booleanExpression = "(%s)=%s" % (booleanExpression, "'1'" if "'1'" in booleanExpression else "1")
else:
forgeCaseExpression = agent.forgeCaseStatement(expression)
# 如果直接执行
if conf.direct:
value = direct(forgeCaseExpression if expected == EXPECTED.BOOL else expression)
# 如果使用了任何公开的技术
elif any(isTechniqueAvailable(_) for _ in getPublicTypeMembers(PAYLOAD.TECHNIQUE, onlyValues=True)):
query = cleanQuery(expression)
query = expandAsteriskForColumns(query)
@ -459,52 +482,72 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
warnMsg += "(%s) " % _
singleTimeWarnMessage(warnMsg)
# 如果启用了盲注,并且布尔技术可用,且未找到结果,则设置布尔技术
if blind and isTechniqueAvailable(PAYLOAD.TECHNIQUE.BOOLEAN) and not found:
setTechnique(PAYLOAD.TECHNIQUE.BOOLEAN)
# 如果期望的结果是布尔值则使用_goBooleanProxy函数获取结果
if expected == EXPECTED.BOOL:
value = _goBooleanProxy(booleanExpression)
# 否则使用_goInferenceProxy函数获取结果
else:
value = _goInferenceProxy(query, fromUser, batch, unpack, charsetType, firstChar, lastChar, dump)
# 计数加一
count += 1
# 如果结果不为空或者结果为空且期望结果为空或者计数大于等于最大技术数则设置found为True
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE
# 如果启用了时间注入,并且时间或堆栈技术可用,且未找到结果,则设置时间或堆栈技术
if time and (isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME) or isTechniqueAvailable(PAYLOAD.TECHNIQUE.STACKED)) and not found:
# 使用正则表达式匹配表达式中的FROM和ORDER BY
match = re.search(r"\bFROM\b ([^ ]+).+ORDER BY ([^ ]+)", expression)
# 将匹配结果设置为kb.responseTimeMode
kb.responseTimeMode = "%s|%s" % (match.group(1), match.group(2)) if match else None
# 如果时间技术可用,则设置时间技术
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.TIME):
setTechnique(PAYLOAD.TECHNIQUE.TIME)
# 否则,设置堆栈技术
else:
setTechnique(PAYLOAD.TECHNIQUE.STACKED)
# 如果期望的结果是布尔值则使用_goBooleanProxy函数获取结果
if expected == EXPECTED.BOOL:
value = _goBooleanProxy(booleanExpression)
# 否则使用_goInferenceProxy函数获取结果
else:
value = _goInferenceProxy(query, fromUser, batch, unpack, charsetType, firstChar, lastChar, dump)
else:
# 如果没有找到可用的注入类型,则抛出异常
errMsg = "none of the injection types identified can be "
errMsg += "leveraged to retrieve queries output"
raise SqlmapNotVulnerableException(errMsg)
# 最后恢复kb.resumeValues和kb.responseTimeMode的值
finally:
kb.resumeValues = True
kb.responseTimeMode = None
# 从kb中弹出tbl和db的值
conf.tbl = popValue()
conf.db = popValue()
# 如果suppressOutput不为None则禁用标准输出
if suppressOutput is not None:
getCurrentThreadData().disableStdOut = popValue()
# 设置kb.safeCharEncode为False
kb.safeCharEncode = False
# 如果没有启用测试模式、dummy、离线、noCast、hexConvert且结果为空且数据库已识别且kb.fingerprinted为True则抛出异常或警告
if not any((kb.testMode, conf.dummy, conf.offline, conf.noCast, conf.hexConvert)) and value is None and Backend.getDbms() and conf.dbmsHandler and kb.fingerprinted:
# 如果启用了abortOnEmpty则抛出异常
if conf.abortOnEmpty:
errMsg = "aborting due to empty data retrieval"
logger.critical(errMsg)
raise SystemExit
# 否则,抛出警告
else:
warnMsg = "in case of continuous data retrieval problems you are advised to try "
warnMsg += "a switch '--no-cast' "
@ -543,24 +586,35 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
return extractExpectedValue(value, expected)
def goStacked(expression, silent=False):
# 检查是否已经设置了堆叠注入技术
if PAYLOAD.TECHNIQUE.STACKED in kb.injection.data:
# 如果已经设置了堆叠注入技术,则直接设置
setTechnique(PAYLOAD.TECHNIQUE.STACKED)
else:
# 如果没有设置堆叠注入技术,则遍历所有公开的技术
for technique in getPublicTypeMembers(PAYLOAD.TECHNIQUE, True):
# 获取技术的数据
_ = getTechniqueData(technique)
# 如果数据存在,并且标题中包含"stacked",则设置该技术
if _ and "stacked" in _["title"].lower():
setTechnique(technique)
break
# 清理查询语句
expression = cleanQuery(expression)
# 如果配置了直接执行,则直接执行查询语句
if conf.direct:
return direct(expression)
# 构造查询语句
query = agent.prefixQuery(";%s" % expression)
query = agent.suffixQuery(query)
# 构造payload
payload = agent.payload(newValue=query)
# 执行查询语句
Request.queryPage(payload, content=False, silent=silent, noteResponseTime=False, timeBasedCompare="SELECT" in (payload or "").upper())
def checkBooleanExpression(expression, expectingNone=True):
# 检查布尔表达式
return getValue(expression, expected=EXPECTED.BOOL, charsetType=CHARSET_TYPE.BINARY, suppressOutput=True, expectingNone=expectingNone)

Loading…
Cancel
Save