checkBooleanExpression("%d%s%d"%(randInt1,INFERENCE_EQUALS_CHAR,randInt2))# just in case if DBMS hasn't properly recovered from previous delayed request
# 如果满足布尔表达式,则retVal为False,跳出循环
ifcheckBooleanExpression("%d%s%d"%(randInt1,INFERENCE_EQUALS_CHAR,randInt3)):# this must not be evaluated to True
retVal=False
break
# 如果满足布尔表达式,则retVal为False,跳出循环
elifcheckBooleanExpression("%d%s%d"%(randInt3,INFERENCE_EQUALS_CHAR,randInt2)):# this must not be evaluated to True
retVal=False
break
# 如果不满足布尔表达式,则retVal为False,跳出循环
elifnotcheckBooleanExpression("%d%s%d"%(randInt2,INFERENCE_EQUALS_CHAR,randInt2)):# this must be evaluated to True
retVal=False
break
# 如果满足布尔表达式,则retVal为False,跳出循环
elifcheckBooleanExpression("%d%d"%(randInt3,randInt2)):# this must not be evaluated to True (invalid statement)
retVal=False
break
# 如果retVal为False,则记录警告信息
ifnotretVal:
warnMsg="false positive or unexploitable injection point detected"
infoMsg="heuristic (XSS) test shows that %sparameter '%s' might be vulnerable to cross-site scripting (XSS) attacks"%("%s"%paramTypeifparamType!=parameterelse"",parameter)
# 输出信息,表示参数可能存在XSS攻击
logger.info(infoMsg)
ifconf.beep:
# 如果配置文件中设置了beep,则执行beep函数
beep()
formatchinre.finditer(FI_ERROR_REGEX,pageor""):
# 在page中查找FI_ERROR_REGEX,如果找到,则执行以下代码
ifrandStr1.lower()inmatch.group(0).lower():
# 如果randStr1的小写字母在match.group(0)的小写字母中,则执行以下代码
infoMsg="heuristic (FI) test shows that %sparameter '%s' might be vulnerable to file inclusion (FI) attacks"%("%s"%paramTypeifparamType!=parameterelse"",parameter)
@ -92,6 +97,7 @@ class DBMS_DIRECTORY_NAME(object):
VIRTUOSO="virtuoso"
classFORK(object):
# 定义分支数据库管理系统常量
MARIADB="MariaDB"
MEMSQL="MemSQL"
PERCONA="Percona"
@ -109,15 +115,18 @@ class FORK(object):
OPENGAUSS="OpenGauss"
classCUSTOM_LOGGING(object):
# 定义自定义日志常量
PAYLOAD=9
TRAFFIC_OUT=8
TRAFFIC_IN=7
classOS(object):
# 定义操作系统常量
LINUX="Linux"
WINDOWS="Windows"
classPLACE(object):
# 定义位置常量
GET="GET"
POST="POST"
URI="URI"
@ -129,6 +138,7 @@ class PLACE(object):
CUSTOM_HEADER="(custom) HEADER"
classPOST_HINT(object):
# 定义POST提示常量
SOAP="SOAP"
JSON="JSON"
JSON_LIKE="JSON-like"
@ -137,6 +147,7 @@ class POST_HINT(object):
ARRAY_LIKE="Array-like"
classHTTPMETHOD(object):
# 定义HTTP方法常量
GET="GET"
POST="POST"
HEAD="HEAD"
@ -148,15 +159,18 @@ class HTTPMETHOD(object):
PATCH="PATCH"
classNULLCONNECTION(object):
# 定义空连接常量
HEAD="HEAD"
RANGE="Range"
SKIP_READ="skip-read"
classREFLECTIVE_COUNTER(object):
# 定义反射计数器常量
MISS="MISS"
HIT="HIT"
classCHARSET_TYPE(object):
# 定义字符集类型常量
BINARY=1
DIGITS=2
HEXADECIMAL=3
@ -164,11 +178,13 @@ class CHARSET_TYPE(object):
ALPHANUM=5
classHEURISTIC_TEST(object):
# 定义启发式测试常量
CASTED=1
NEGATIVE=2
POSITIVE=3
classHASH(object):
# 定义哈希常量
MYSQL=r'(?i)\A\*[0-9a-f]{40}\Z'
MYSQL_OLD=r'(?i)\A(?![0-9]+\Z)[0-9a-f]{16}\Z'
POSTGRES=r'(?i)\Amd5[0-9a-f]{32}\Z'
@ -216,22 +232,26 @@ class MOBILES(object):
XIAOMI=("Xiaomi Mi 8 Pro","Mozilla/5.0 (Linux; Android 9; MI 8 Pro Build/PKQ1.180729.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/87.0.4280.66 Mobile Safari/537.36")
("--dummy",("all tested parameters do not appear to be injectable","does not seem to be injectable","there is not at least one","~might be injectable")),
("-u \"<url>&id2=1\" -p id2 -v 5 --flush-session --level=5 --text-only --test-filter=\"AND boolean-based blind - WHERE or HAVING clause (MySQL comment)\"",("~1AND",)),
("-l <log> --flush-session --keep-alive --skip-waf -vvvvv --technique=U --union-from=users --banner --parse-errors",("banner: '3.","ORDER BY term out of range","~xp_cmdshell","Connection: keep-alive")),
# When user provides DBMS credentials (with --dbms-cred), the
# command standard output is redirected to a temporary file
# The file needs to be copied to the support table,
# 'sqlmapoutput'
# 处理DBMS凭据情况下的命令输出
ifconf.dbmsCred:
inject.goStacked("BULK INSERT %s FROM '%s' WITH (CODEPAGE='RAW', FIELDTERMINATOR='%s', ROWTERMINATOR='%s')"%(self.cmdTblName,self.tmpFile,randomStr(10),randomStr(10)))
self.delRemoteFile(self.tmpFile)
query="SELECT %s FROM %s ORDER BY id"%(self.tblField,self.cmdTblName)
count=inject.getValue("SELECT COUNT(id) FROM %s"%self.cmdTblName,resumeValue=False,union=False,error=False,expected=EXPECTED.INT,charsetType=CHARSET_TYPE.DIGITS)
# We have to check if the SQL query might return multiple entries
# and in such case forge the SQL limiting the query output one
# entry at a time
# NOTE: we assume that only queries that get data from a table can
# return multiple entries
# 检查SQL查询是否可能返回多条记录
if(dumpand(conf.limitStartorconf.limitStop))or(" FROM "inexpression.upper()and((Backend.getIdentifiedDbms()notinFROM_DUMMY_TABLE)or(Backend.getIdentifiedDbms()inFROM_DUMMY_TABLEandnotexpression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()])))and("(CASE"notinexpression.upper()or("(CASE"inexpression.upper()and"WHEN use"inexpression)))andnotre.search(SQL_SCALAR_REGEX,expression,re.I):
returnnotany(re.search(_,pageor"",re.I)andnotre.search(_,kb.pageTemplateor"",re.I)for_in("(warning|error):","order (by|clause)","unknown column","failed"))andnotkb.heavilyDynamicandcomparison(page,headers,code)orre.search(r"data types cannot be compared or sorted",pageor"",re.I)isnotNone
fromTable=" FROM (%s) AS %s"%(" UNION ".join("SELECT %d%s%s"%(_,FROM_DUMMY_TABLE.get(Backend.getIdentifiedDbms(),"")," AS %s"%randomStr()if_==0else"")for_inxrange(LIMITED_ROWS_TEST_NUMBER)),randomStr())
elifkb.ncharandre.search(r" AS N(CHAR|VARCHAR)",agent.nullAndCastField(expression)):
debugMsg="turning off NATIONAL CHARACTER casting"# NOTE: in some cases there are "known" incompatibilities between original columns and NCHAR (e.g. http://testphp.vulnweb.com/artists.php?artist=1)
# We have to check if the SQL query might return multiple entries
# if the technique is partial UNION query and in such case forge the
# SQL limiting the query output one entry at a time
# NOTE: we assume that only queries that get data from a table can
# return multiple entries
# 检查是否需要分页查询
ifvalueisNoneand(kb.injection.data[PAYLOAD.TECHNIQUE.UNION].where==PAYLOAD.WHERE.NEGATIVEorkb.forcePartialUnionorconf.forcePartialor(dumpand(conf.limitStartorconf.limitStop))or"LIMIT "inexpression.upper())and" FROM "inexpression.upper()and((Backend.getIdentifiedDbms()notinFROM_DUMMY_TABLE)or(Backend.getIdentifiedDbms()inFROM_DUMMY_TABLEandnotexpression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()])))andnotre.search(SQL_SCALAR_REGEX,expression,re.I):
content=("<!DOCTYPE html><html lang=\"en\"><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL %s was not found on this server.</p></body></html>"%self.path.split('?')[0]).encode(UNICODE_ENCODING)
sys.exit("[%s] [CRITICAL] incompatible Python version detected ('%s'). To successfully run sqlmap you'll have to use version 2.6, 2.7 or 3.x (visit 'https://www.python.org/downloads/')"%(time.strftime("%X"),PYVERSION))