建議閱讀
Time-Based Blind SQL Injection Attacks
基於時間的盲注(time-based blind)
測試應用是否存在SQL注入漏洞時,經常發現某一潛在的漏洞難以確認。這可能源於多種原因,但主要是因為Web應用未顯示任何錯誤,因而無法檢索任何數據。
對於這種情況,要想識別漏洞,向數據庫注入時間延遲並檢查服務器響應是否也已經延遲會很有幫助。時間延遲是一種很強大的技術,Web服務器雖然可以隱藏錯誤或數據,但必須等待數據庫返回結果,因此可用它來確認是否存在SQL注入。該技術尤其適合盲注。
源碼解釋
代碼位置:在checkSqlInjection函數中(\lib\controller\checks.py 文件,大約第444行左右)
# 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
其中,重點注意Request.queryPage函數,將參數timeBasedCompare設置為True,所以在Request.queryPage函數內部,有這么一段代碼:
if timeBasedCompare: return wasLastRequestDelayed()
而函數wasLastRequestDelayed()的功能主要是判斷最后一次的請求是否有明顯的延時,方法就是將最后一次請求的響應時間與之前所有請求的響應時間的平均值進行比較,如果最后一次請求的響應時間明顯大於之前幾次請求的響應時間的平均值,就說明有延遲。
wasLastRequestDelayed函數的代碼如下:
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
每次執行http請求的時候,會將執行所響應的時間append到kb.responseTimes列表中,但不包括time-based blind所發起的請求。
為什么?
從以下代碼就可以知道了,當timeBasedCompare為True(即進行time-based blind注入檢測)時,直接返回執行結果,如果是其他類型的請求,就保存響應時間。
if timeBasedCompare: return wasLastRequestDelayed() elif noteResponseTime: kb.responseTimes.append(threadData.lastQueryDuration)
另外,為了確保基於時間的盲注的准確性,sqlmap執行了兩次queryPage。
