1. 程式人生 > >sqlmap基於時間盲注判斷原理

sqlmap基於時間盲注判斷原理

檢測入口:

lib/controller/checks.pycheckSqlInjection函式中:

elifmethod == 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' appears to be '%s' injectable "% (paramType, parameter, title)
            logger.info(infoMsg)

            injectable = True

檢測是否是時間盲注注入點,呼叫queryPage函式,若返回True,再呼叫該函式驗證一次,驗證成功之後,則判斷該注入點存在時間盲注。

Lib/requests/connect.py中queryPage函式:

若檢測時間盲注,queryPage函式中timeBasedCompare設定為True

判斷是否存在時間盲注時,若kb.responseTimes中的長度小於MIN_TIME_RESPONSES(30),則連續請求30次頁面,獲取響應時間。

    while len(kb.responseTimes[kb.responseTimeMode]) < MIN_TIME_RESPONSES:
        value = kb.responseTimePayload.replace(RANDOM_INTEGER_MARKER, str(randomInt(6))).replace(RANDOM_STRING_MARKER, randomStr()) if 
kb.responseTimePayload else kb.responseTimePayload         Connect.queryPage(value=value, content=True, raise404=False)         dataToStdout('.')     dataToStdout(" (done)\n")

timeBasedCompare為True,呼叫wasLastResponseDelayed()判斷上次請求是否存在延遲。

if timeBasedCompare:
    return wasLastResponseDelayed()
  elif noteResponseTime:
    kb.responseTimes.setdefault(kb.responseTimeMode, [])
    kb.responseTimes[kb.responseTimeMode].append(threadData.lastQueryDuration)

Lib/core/common.py wasLastResponseDelayed()中:

首先根據responseTimes中的所有時間計算得到標準差deviation

計算最慢的響應時間:lowerStdLimit平均值+TIME_STDEV_COEFF*標準差。

TIME_STDEV_COEFF設定為7可以使得判斷的準確度在99.9999999997440%

之上。

判斷上次請求的響應時間是否大於max(MIN_VALID_DELAYED_RESPONSE,lowerStdLimit)),是則置retVal為True,返回。(即存在時間注入)

若當前網路情況良好,使用者可以輸入Y來optimize value,呼叫adjustTimeDelay()來縮短sleep時間。

def wasLastResponseDelayed():
    """
    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.get(kb.responseTimeMode, []))
    threadData = getCurrentThreadData()
  
    if deviation and not conf.direct:
        if len(kb.responseTimes[kb.responseTimeMode]) < 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[kb.responseTimeMode]) + TIME_STDEV_COEFF * deviation
        retVal = (threadData.lastQueryDuration >= max(MIN_VALID_DELAYED_RESPONSE, lowerStdLimit))
  
        if not kb.testMode and retVal:
            if kb.adjustTimeDelay is None:
                msg = "do you want sqlmap to try to optimize value(s) "
                msg += "for DBMS delay responses (option '--time-sec')? [Y/n] "
                choice = readInput(msg, default='Y')
                kb.adjustTimeDelay = ADJUST_TIME_DELAY.DISABLE if choice.upper() == 'N' else ADJUST_TIME_DELAY.YES
            if kb.adjustTimeDelay is ADJUST_TIME_DELAY.YES:
                adjustTimeDelay(threadData.lastQueryDuration, lowerStdLimit)
  
        return retVal
    else:
        return (threadData.lastQueryDuration - conf.timeSec) >= 0

總結:

Sqlmap根據基於時間的盲注技術來檢測注入點,不需要依賴具體的sleep(n)  n的大小,而是判斷上次請求的響應時間是否在預期之內,不在則認為產生了時延,存在注入點。

並且採用了數學的方法, 將判斷的準確度控制在相當高的一個百分比之上。

檢測的思想具有很好的學習價值。

其它參考資料:

http://blog.csdn.net/jinzhichaoshuiping/article/details/45568883
http://www.cnblogs.com/hongfei/p/sqlmap-time-based-blind.html