Python編寫漏洞驗(yàn)證腳本批量測(cè)試繁瑣漏洞
前言
我們實(shí)戰(zhàn)經(jīng)常會(huì)遇到以下幾個(gè)問題:
? 1、遇到一個(gè)利用步驟十分繁瑣的漏洞,中間錯(cuò)一步就無(wú)法利用
? 2、挖到一個(gè)通用漏洞,想要批量刷洞小賺一波,但手動(dòng)去測(cè)試每個(gè)網(wǎng)站工作量太大
這個(gè)時(shí)候編寫一個(gè)poc腳本將會(huì)將會(huì)減輕我們很多工作。本文將以編寫一個(gè)高效通用的poc腳本為目的,學(xué)習(xí)一些必要的python知識(shí),這周也是拒絕做工具小子努力學(xué)習(xí)的一周
requests模塊使用技巧
Requests是Python中一個(gè)常用的HTTP請(qǐng)求庫(kù),使用Requests庫(kù)來(lái)發(fā)起網(wǎng)絡(luò)請(qǐng)求非常簡(jiǎn)單,具體的使用方法這里就不多介紹了,這里只提幾個(gè)Requests模塊的使用技巧,請(qǐng)收好
取消重定向
Requests 會(huì)自動(dòng)處理所有重定向,但有時(shí)我們并不需要重定向,可以通過allow_redirects
參數(shù)禁用重定向處理:
r = requests.get('http://github.com', allow_redirects=False)
SSL 證書驗(yàn)證
Requests在請(qǐng)求https網(wǎng)站默認(rèn)會(huì)驗(yàn)證SSL證書,可有些網(wǎng)站并沒有證書,可增加verify=False
參數(shù)忽略證書驗(yàn)證,但此時(shí)可能會(huì)遇到煩人的InsecureRequestWarning
警告消息。最終能沒有警告消息也能訪問無(wú)證書的https網(wǎng)站的方法如下:
import requests from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) requests.get('https://github.com', verify=False)
代理
使用代理的目的就不說了,使用方法如下:
# http代理,需要指定訪問的http協(xié)議和https協(xié)議兩種 proxies = { "http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:1080", } # socks5代理 proxies = { 'http': 'socks5://user:pass@host:port', 'https': 'socks5://user:pass@host:port' } requests.get("http://example.org", proxies=proxies)
有個(gè)使用技巧就是代理到burp中,檢查一下python發(fā)包。如我本地抓到requests請(qǐng)求包如下,可以發(fā)現(xiàn)特征十分明顯,所以我們?cè)趯?shí)戰(zhàn)使用時(shí)盡量修改User-Agent
保持cookie
使用session會(huì)話對(duì)象,向同一主機(jī)發(fā)送多個(gè)請(qǐng)求,底層的 TCP 連接將會(huì)被重用,不僅能提性能還能保持cookie
s = requests.Session() s.get('http://httpbin.org/cookies/set/sessioncookie/123456789') r = s.get("http://httpbin.org/cookies")
在編寫poc腳本時(shí)我們只需要利用Requests模塊發(fā)送帶有payload的數(shù)據(jù)即可,配合上這里的小技巧可能會(huì)有更好的體驗(yàn)
驗(yàn)證結(jié)果
發(fā)送帶有payload的請(qǐng)求后,我們需要通過分析響應(yīng)包判斷是否存在漏洞。往往存在漏洞的響應(yīng)包都有一些特殊值,我們只需要在響應(yīng)包中找到這樣的特殊值即可證明存在漏洞,所以這里我們通常有兩種寫法
成員運(yùn)算符 - in
if 'xxx' in r.text: print('存在漏洞') else: print('不存在漏洞')
正則匹配 - re.search()
if re.search('xxx',r.text): print('存在漏洞') else: print('不存在漏洞')
這兩種寫法差不多,不過re.search()有個(gè)好處是可以使用正則表達(dá)式,在漏洞特征是動(dòng)態(tài)變化的情況時(shí)也能有效的捕捉
單線程poc腳本
此時(shí)我們已經(jīng)能寫一個(gè)單線程poc腳本了,我對(duì)單線程的poc腳本的要求十分簡(jiǎn)單,就是簡(jiǎn)單,在面對(duì)不同的漏洞時(shí)簡(jiǎn)單修改幾行代碼就可以了。這里提供一個(gè)我自己寫的單線程poc腳本,大概意思就是這樣
import requests import re from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) def Poc(url): proxy = { 'http':'http://127.0.0.1:8080', 'https':'http://127.0.0.1:8080' } headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36', 'Connection':'close' } data = {'name':'xxxx','value':'xxxx'} try: response = requests.post(url=url,headers=headers,data=data,verify=False,proxies=proxy,timeout=10) if 'baidu' in response.text: print('存在漏洞') else: print('none') except Exception as e: print(f'請(qǐng)求失敗:{e}') if __name__ == '__main__': url = 'https://www.baidu.com' Poc(url)
使用多線程
當(dāng)我們想批量驗(yàn)證數(shù)個(gè)網(wǎng)站是否存在漏洞時(shí),就需要多線程來(lái)提升效率了。關(guān)于Python多線程的詳細(xì)知識(shí)這里就不是這里的重點(diǎn)了。這里我們將利用Threading和queue做一個(gè)多線程poc腳本,我計(jì)劃的流程如下
把所有目標(biāo)url放到queue隊(duì)列中;
啟動(dòng)多線程從queue隊(duì)列中獲取目標(biāo)并執(zhí)行;
保存執(zhí)行結(jié)果。
具體代碼最后會(huì)給出
顏色標(biāo)記
我在使用多線程時(shí)就遇到一個(gè)問題,因?yàn)槎嗑€程處理的數(shù)據(jù)比較多,終端瞬間會(huì)輸出大量信息,很容易就會(huì)忽略一些關(guān)鍵的信息
然后我就想用顏色來(lái)區(qū)分不同的信息,在linux終端中使用\033[顯示方式;前景色;背景色m
的格式就能輸出各個(gè)顏色的字體。這里推薦python第三方庫(kù):colorama
colorama是一個(gè)可以跨多終端顯示不同顏色字符與背景的第三方庫(kù),在linux終端上,使用ANSI轉(zhuǎn)義字符來(lái)實(shí)現(xiàn)彩色字體的輸出。在windows的終端上,通過包裝stdout實(shí)現(xiàn)。在windows和linux上有不同的實(shí)現(xiàn)方案,從而達(dá)到跨平臺(tái)的效果
安裝第三方庫(kù)的命令各位應(yīng)該都會(huì)吧
pip install colorama
具體使用參考官方文檔:https://pypi.org/project/colorama/
我的使用習(xí)慣就是報(bào)錯(cuò)信息的字體使用紅色,發(fā)現(xiàn)漏洞的字體使用綠色,此時(shí)部分代碼如下:
from colorama import init,Fore init(autoreset=True) print(Fore.GREEN + '[+]存在漏洞') print(Fore.RED + '[!]連接錯(cuò)誤')
使用顏色后的終端輸出如下,現(xiàn)在使用體驗(yàn)上明顯會(huì)更好一點(diǎn),大家也可以根據(jù)自己的喜好去設(shè)置
添加進(jìn)度條
我們使用多線程的目的就是為了更快的處理更多的url,但目標(biāo)過多,我們還是免不了更長(zhǎng)時(shí)間的等待。我們經(jīng)常會(huì)把腳本掛在那里跑,然后呆呆的等著。然后我就想做一個(gè)進(jìn)度條,根據(jù)進(jìn)度條能大概的去預(yù)估時(shí)間,然后安排自己的工作,提升工作效率,這不就是使用腳本的意義嗎
我首先就找到了很多人推薦的第三方庫(kù):tqdm,在多線程中使用時(shí)可以使用手動(dòng)更新進(jìn)度
import time from tqdm import tqdm with tqdm(total=200) as pbar: pbar.set_description('Processing:') for i in range(20): time.sleep(0.1) pbar.update(10)
但我這里就遇到一個(gè)問題,很多人使用tqdm時(shí)只輸出一個(gè)Progress bar任務(wù)條,但我們的需求是希望同時(shí)輸出每次漏洞探測(cè)結(jié)果和任務(wù)條,這會(huì)導(dǎo)致這兩者在終端中顯示的混亂,如下圖所示
有沒有一種辦法能讓任務(wù)條一直固定輸出在終端的末尾呢,這樣兩個(gè)信息都能很清晰的顯示
我找了好久解決方法,但官方似乎說沒有找到在多個(gè)平臺(tái)上平等使用tqdm的方法,就沒有這個(gè)功能。不過我最終找到官方提供了一個(gè)tqdm.write()方法,似乎能解決這個(gè)問題,只需要把腳本中所有print()方法換成tqdm.write()方法
到這里我們就成功的擁有了一個(gè)進(jìn)度條
多線程poc腳本
我最終寫好的多線程poc腳本如下,中間還有很多可以優(yōu)化的地方,希望能得到大家的指點(diǎn)
import requests from requests.packages.urllib3.exceptions import InsecureRequestWarning import threading import queue from colorama import init,Fore from tqdm import tqdm init(autoreset=True) requests.packages.urllib3.disable_warnings(InsecureRequestWarning) global_file_target_url = 'url.txt' global_file_result = 'right.txt' global_threads_num = 12 global_q = queue.Queue() global_list_result = [] # 目標(biāo)uri global_where = '' # payload 成功時(shí)頁(yè)面標(biāo)志信息 global_payload = 'test' global_request_proxy = { 'http':'socks5://127.0.0.1:8080', 'https':'socks5://127.0.0.1:8080' } global_request_headers = { 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36', 'cookie':'xxxxxxxxxxxxxx', 'Connection':'close' #關(guān)閉多余的連接請(qǐng)求 } global_request_data = {'name':'xxxx','value':'xxxx'} #POST傳遞的數(shù)據(jù) global_error = 0 def req(url): global global_error i = 0 while i<3: if i>0: #print(f'[!]第{i}次重試請(qǐng)求{url}') tqdm.write(f'[!]第{i}次重試請(qǐng)求{url}') try: response = requests.get(url=url,headers=global_request_headers,verify=False,timeout=10) response.encoding = response.apparent_encoding text = response.text if global_payload in text: return True else: return False except Exception as e: if i==0: global_error +=1 i = i+1 #print(Fore.RED+f'[!]{url}請(qǐng)求失敗') tqdm.write(Fore.RED+f'[!]{url}請(qǐng)求失敗') def poc(pbar): while not global_q.empty(): target_url = global_q.get() url = target_url+global_where if req(url): #print(Fore.GREEN+'[+]存在漏洞:'+target_url) tqdm.write(Fore.GREEN+'[+]存在漏洞:'+target_url) global_list_result.append(target_url) else: #print('[-]未發(fā)現(xiàn)漏洞') tqdm.write('[-]未發(fā)現(xiàn)漏洞') pbar.update(1) def main(): # 1、添加目標(biāo)url隊(duì)列 with open(global_file_target_url,'r') as f: urls = f.readlines() for url in urls: url = url.strip() global_q.put(url) num_url = global_q.qsize() pbar = tqdm(total=num_url) pbar.set_description('Processing:') tqdm.write('url總數(shù):'+str(num_url)) # 2、啟動(dòng)多線程poc驗(yàn)證 threads = [] for _ in range(global_threads_num): t = threading.Thread(target=poc,args=(pbar,)) threads.append(t) t.start() for t in threads: t.join() # 3、保存結(jié)果到文件 global_file_result if global_list_result: file = open(global_file_result,'w') for res in global_list_result: file.write(res+"\n") file.close() tqdm.write(f'失敗請(qǐng)求數(shù){global_error}') if __name__ == '__main__': main()
參考:
Python編寫漏洞驗(yàn)證腳本批量測(cè)試繁瑣漏洞
以上就是Python編寫漏洞驗(yàn)證腳本批量測(cè)試繁瑣漏洞的詳細(xì)內(nèi)容,更多關(guān)于Python漏洞驗(yàn)證腳本的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
詳解Python如何輕松實(shí)現(xiàn)定時(shí)執(zhí)行任務(wù)
這篇文章主要為大家詳細(xì)介紹了Python如何在Windows下不用任務(wù)管理器就實(shí)現(xiàn)輕松定時(shí)執(zhí)行任務(wù),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-10-10Python----數(shù)據(jù)預(yù)處理代碼實(shí)例
這篇文章主要介紹了Python數(shù)據(jù)預(yù)處理,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03在VS2017中用C#調(diào)用python腳本的實(shí)現(xiàn)
這篇文章主要介紹了在VS2017中用C#調(diào)用python腳本的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07python事件驅(qū)動(dòng)event實(shí)現(xiàn)詳解
這篇文章主要為大家詳細(xì)介紹了python事件驅(qū)動(dòng)event實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11Python高級(jí)排序sort()函數(shù)使用技巧實(shí)例探索
本文詳細(xì)介紹sort()函數(shù)的使用,包括基本排序、自定義排序、逆序排序等多種情況,并提供大量示例代碼,以幫助你充分理解和掌握這一函數(shù)的用法,探索更多sort()排序函數(shù)的作用2024-01-01Python實(shí)例練習(xí)水仙花數(shù)問題講解
這篇文章介紹了Python找水仙花數(shù)從分析到實(shí)現(xiàn)的過程,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05python 使用GDAL實(shí)現(xiàn)柵格tif轉(zhuǎn)矢量shp的方式小結(jié)
今天通過本文給大家分享python 使用GDAL實(shí)現(xiàn)柵格tif轉(zhuǎn)矢量shp的方式小結(jié),計(jì)劃是使用柵格轉(zhuǎn)矢量的方式,將柵格數(shù)據(jù)轉(zhuǎn)為矢量shp文件,然后進(jìn)行矢量切片,使用Mapbox進(jìn)行前端動(dòng)態(tài)渲染,具體內(nèi)容詳情跟隨小編一起看看吧2021-08-08