Python:SQLMap源碼精讀—基於時間的盲注(time-based blind)

建議閱讀

Time-Based Blind SQL Injection Attacks

基於時間的盲注(time-based blind)

  測試應用是否存在SQL注入漏洞時,經常發現某一潛在的漏洞難以確認。這可能源於多種原因,但主要是因為Web應用未顯示任何錯誤,因而無法檢索任何數據。

  對於這種情況,要想識別漏洞,向數據庫注入時間延遲並檢查服務器響應是否也已經延遲會很有幫助。時間延遲是一種很強大的技術,Web服務器雖然可以隱藏錯誤或數據,但必須等待數據庫返回結果,因此可用它來確認是否存在SQL注入。該技術尤其適合盲注。

源碼解釋

代碼位置:在checkSqlInjection函數中(\\lib\\controller\\checks.py 文件,大約第444行左右)

使用了基於時間的盲注來對目標網址進行盲注測試,代碼如下:

<code># In case of time-based blind or stacked queries
# SQL injections
elif method == PAYLOAD.METHOD.TIME:
# Perform the test's request
trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)

if trueResult:
# Confirm test's results
trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)

if trueResult:
infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
logger.info(infoMsg)

injectable = True/<code>

其中,重點注意Request.queryPage函數,將參數timeBasedCompare設置為True,所以在Request.queryPage函數內部,有這麼一段代碼:

<code>if timeBasedCompare:
return wasLastRequestDelayed()/<code>

而函數wasLastRequestDelayed()的功能主要是判斷最後一次的請求是否有明顯的延時,方法就是將最後一次請求的響應時間與之前所有請求的響應時間的平均值進行比較,如果最後一次請求的響應時間明顯大於之前幾次請求的響應時間的平均值,就說明有延遲。

wasLastRequestDelayed函數的代碼如下:

<code>def wasLastRequestDelayed():
"""
Returns True if the last web request resulted in a time-delay
"""

# 99.9999999997440% of all non time-based sql injection affected
# response times should be inside +-7*stdev([normal response times])
# Math reference: http://www.answers.com/topic/standard-deviation
deviation = stdev(kb.responseTimes)
threadData = getCurrentThreadData()

if deviation:
if len(kb.responseTimes) < MIN_TIME_RESPONSES:
warnMsg = "time-based standard deviation method used on a model "
warnMsg += "with less than %d response times" % MIN_TIME_RESPONSES
logger.warn(warnMsg)

lowerStdLimit = average(kb.responseTimes) + TIME_STDEV_COEFF * deviation
retVal = (threadData.lastQueryDuration >= lowerStdLimit)

if not kb.testMode and retVal and conf.timeSec == TIME_DEFAULT_DELAY:
adjustTimeDelay(threadData.lastQueryDuration, lowerStdLimit)

return retVal
else:

return (threadData.lastQueryDuration - conf.timeSec) >= 0/<code>
Python:SQLMap源碼精讀—基於時間的盲注(time-based blind)

<code>def wasLastRequestDelayed():
"""
Returns True if the last web request resulted in a time-delay
"""

# 99.9999999997440% of all non time-based sql injection affected
# response times should be inside +-7*stdev([normal response times])
# Math reference: http://www.answers.com/topic/standard-deviation
deviation = stdev(kb.responseTimes)
threadData = getCurrentThreadData()

if deviation:
if len(kb.responseTimes) < MIN_TIME_RESPONSES:
warnMsg = "time-based standard deviation method used on a model "
warnMsg += "with less than %d response times" % MIN_TIME_RESPONSES
logger.warn(warnMsg)

lowerStdLimit = average(kb.responseTimes) + TIME_STDEV_COEFF * deviation
retVal = (threadData.lastQueryDuration >= lowerStdLimit)

if not kb.testMode and retVal and conf.timeSec == TIME_DEFAULT_DELAY:
adjustTimeDelay(threadData.lastQueryDuration, lowerStdLimit)

return retVal
else:
return (threadData.lastQueryDuration - conf.timeSec) >= 0/<code>

每次執行http請求的時候,會將執行所響應的時間append到kb.responseTimes列表中,但不包括time-based blind所發起的請求。

為什麼?

從以下代碼就可以知道了,當timeBasedCompare為True(即進行time-based blind注入檢測)時,直接返回執行結果,如果是其他類型的請求,就保存響應時間。

<code>if timeBasedCompare:
return wasLastRequestDelayed()
elif noteResponseTime:
kb.responseTimes.append(threadData.lastQueryDuration)/<code>

另外,為了確保基於時間的盲注的準確性,sqlmap執行了兩次queryPage。

如果2次的結果都為True,那麼就說明目標網址可注入,所以將injectable 設置為True。


原文鏈接:http://www.cnblogs.com/hongfei/p/sqlmap-time-based-blind.html


分享到:


相關文章: