xss-lab

测试payload:<script “ ‘ OOnn/>

第一关

发现参数name的值被回显到了屏幕上,尝试是否name处存在xss

成功

第二关

当我们输入test后,返回的网页源码看到后端将test赋给了input的属性

构造payload闭合input标签

1
" onfocus=alert('xss') autofocus //

成功弹窗

第三关

输入test并回显,尝试输入框有无xss

输入框输入

1
<script>alert('XSS')</script>

发现并没有弹窗

查看页面源代码发现,我们输入的内容在后端进行了htmlspecialchars()处理,尖括号被编码了

所以我们不能自己构造js语句,而是要借助本来就有尖括号来执行我们的js,现在有两处我们可以插入,<h2>不太好利用,而input标签我们可以用onclick属性

搜索框输入’ onclick=’alert(/xss/)来构造input标签的闭合

发现input标签成功闭合,此时我们只需要点击搜索框就可以出发xss

或者还有如下payload,//是为了注释掉后面的单引号

1
' οnfοcus=alert(/XSS/) autofocus //

源码:

htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。

预定义的字符是:

  • & (和号)成为 &
  • “ (双引号)成为 “
  • ‘ (单引号)成为 ‘
  • < (小于)成为 <
  • > (大于)成为 >

即把这些字符变的没有意义,其只是普通字符,浏览器不会去解析

第四关

输入test返回test典型的反射型xss

先输入

1
<script>alert('XSS')</script>

看一下效果

可见第一处肯定是对参数进行了htmlspecialchars()处理,第二处应该是通过了strplace(不管是str_replace还是preg_replace)处理

那么依然采用的三关的方法,闭合input

搜索框输入:” οnfοcus=alert(/XSS/) autofocus //

成功弹窗

源代码

第五关

标准的反射型xss

输入

1
"><script>alert('XSS')</script> //

网页源码可以看到,给我在script中间加了个横线,猜测后端可能是用strplace匹配到script字符然后替换为scr_ipt

既然匹配script标签,那就尝试使用img标签试试

1
"><img  src=1  οnerrοr=alert("hack")> //

发现也匹配了并且给我加了横线

既然这样,猜测其他标签也差不多应该也都匹配了,那就尝试payload变形中的编码绕过,输入:

1
"><A hREF="j&#97;v&#x61;script:alert(/XSS/)">click me !</a> //

成功

且页面出现clikeme超链接,点击后成功触发xss

源码

第六关

payload同第五关就能过关

源代码中看只是增加几种过滤

第七关

典型的反射型xss

尝试

1
2
3
4
"><script>alert('XSS')</script>//
"><a href="javascript:alert(/XSS/)">click me!</a>//
"><img src=1 οnerrοr=alert("hack")>//
" οnfοcus=alert(/XSS/) autofocus //

发现script,on,href,src被过滤掉了

这样使得绝大多数payload不能用

那就试试payload的变形

大小写

1
">"<Img sRc='#' Onerror="alert(/XSS/)" /> //

还是给我过滤掉了src

双写

1
"><scrscriptipt>alert('XSS')</scrscriptipt> //

成功

源码:

第八关

输入test后,test会被写入a标签的href属性

尝试输入javascript:alert(/XSS/)

发现给我加了横线,猜测后端用了str_replace

尝试编码绕过,p的十进制编码为&#112 ;

那么输入

1
javascri&#112;t:alert(/XSS/)

就可以绕过过滤且成功xss

第九关

输入test,前端页面源码显示非法地址

寻思可能是后端检查输入参数是否包含http://字符串

输入http://,查看源码发现返回正常

我们又想构造如下a标签,而我们的输入必须包含http://,怎么办:

1
<a href="javascript:alert(/XSS/)">click me!</a>

可以使用html的注释

即输入

1
javascript:alert(/XSS/)/*http://*/

输入后发现对script进行了替换

那我们进行编码,输入如下即可绕过str_replace():

1
javascri&#112;t:alert(/XSS/)/*http://*/

成功xss

源码:

strpos() 函数查找字符串在另一字符串中第一次出现的位置。

第十关

输入测试代码<script “ ‘ OOnn>

查看前端源码发现后端对输入参数经过了htmlspeicalchars()以及str_replace()处理,所以keywords参数没有xss注入点

仔细观察源码发现有三个隐藏表单

尝试给这三个参数赋值:

http://192.168.253.128/xss/level10.php?keyword=qqq&t_link=1&t_history=2&t_sort=3

返回结果:

可以看到3被输出回来了,尝试该处是否有xss

构造:

http://192.168.253.128/xss/level10.php?keyword=qqq&t_sort=" type=”button” onclick=”alert(/xss/)

页面出现一个按钮

点击即成功触发xss并通关

源码:

第十二关

查看网页源码,发现第20行有个隐藏表单,盲猜后端应该是将$server[“useragent”]输入到input表单然后发送给客户端

那么尝试抓包修改useragent

返回如下

发现成功修改,那么尝试构造

1
<input type="button" οnclick="alert(/XSS/)">

抓包修改

返回页面,发现成功构造

点击页面的按钮即可弹窗

源码:

第十三关

查看网页源码,如出一辙,后端把cookie输出到了前端

抓包修改cookie,看看后端给我们限制了哪些字符

发现过滤了尖括号

但这并不影响我们构造input闭合

成功闭合

按下页面按钮即可弹窗

第十六关

首先输入测试payload

返回的网页源码可以看到给我们将空格以及script以及/都变为了&nbsp ;即空格

script标签被过滤我们可以用其他标签,/被过滤那我就不用带有反斜杠的标签比如img标签

空格被过滤,那就用%0a代替空格

构造如下:

1
?keyword=<img%0asrc=1%0aonerror=alert('xss')>

成功弹窗

源码:

总结

一般的当我们的输入回显到我们的页面上时,都可能存在xss注入点,我们首先找到这些可能存在注入的地方比如搜索框或者请求参数,然后输入顶部的测试代码通过返回的网页源码看看后端是否对这些敏感字符进行了过滤,然后针对不同的过滤构造不同的payload进行注入

注意要对htmlspecialchars(),str_replace(),preg_replace(),strpos()很熟悉

https://blog.csdn.net/wo41ge/article/details/107459332