DVWA之XSS
DVWA之XSS
OK呀咱们也是打上靶场了
先来整个XSS(Reflected)
初级形态(low)的靶场
1 | <script>alert('xxx')</script> |
一串小代码直接弹窗,说明执行成功,毫无过滤,轻松拿下
中级形态(medium)的靶场
1.一串小代码
1 | <script>alert('xxx')</script> |
结果没运行,响应了一串Hello alert(‘xxx’),一看,爷的script呢?十成让这小可爱给我过滤了, 分析一下源码找一下证据,发现medium比low多了一行
1 | $name = str_replace( '<script>', '', $_GET[ 'name' ] ); |
喝,长大了!知道要过滤了。但是你过滤script关我Script什么事?拿下。
2.当然了也可以双写绕过
1 | <sc<script>ript>alert('xxx')</script> |
高级形态(high)的靶场
还是经典的先试一试
1 | <script>alert('xxx')</script> |
两个语句的响应都是Hello >说明这次的过滤更全面,话不多说,我们直接红温开摆。。。。。。不好意思,当成打王者了。现在我们进一步,看一下关键源码,看看他是如何过滤的
1 | $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] ); |
很明显这是把script标签过滤掉了
那我们继续尝试一些其他XSS攻击方式
1 | <img src="" onerror="alert('XSS')"> |
发现执行成功。拿下这关。
超进化形态(impossible)的靶场
一般impossible情况下,单独利用漏洞就比较困难了,这里我们学习一下过滤方式,读一下源码
我们大致读一下就会发现,主要用来过滤的字段大概就是
1 | $name = htmlspecialchars( $_GET[ 'name' ] ); |
我们来了解一下htmlspecialchars这个函数
htmlspecialchars() 函数把一些预定义的字符转换为 HTML 实体。
预定义的字符是:
(这里因为html实体在Typora里实在难打出来,所以这里用截图的方式)
<>被转化成html实体后,其语言标签就不会再被识别,那些输入的代码自然不会被执行
XSS(Reflected)结束
接下来上场的是XSS(Stored)
低级形态(low)
其实总体的payload大致也没太变,我们来学习一下存储型xss的过滤手段
读一下源码发现里面的过滤函数有:
trim()
函数移除字符串两侧的空白字符或其他预定义字符。
语法:trim(string,charlist) ;string(必需,规定要检查的字符串) ; charlist(可选,规定从字符串中删除哪些字符。如果省略该参数,则移除下列所有字符:
“\0” - NULL
“\t” - 制表符
“\n” - 换行
“\x0B” - 垂直制表符
“\r” - 回车
“ “ - 空格
)
stripslashes()
删除字符串中的反斜杠
语法:stripslashes(string);string(要操作的字符串)
但是仔细查看源码,没有对script脚本进行过滤
所以我们的payload还可以用
1 | <script>alert('kevin')<script> |
但是我们插入的时候会发现第一个框有长度限制,但是没关系直接f12
将maxlength的值改大就行,再插入payload就没问题啦。
中级形态(medium)
来到中级形态,还是老样子尝试一下之前的经典payload
1 | <script>alert(document.cookie)</script> |
很可惜message直接展示出来了,说明script标签被过滤掉了,没有执行
去看源码,我们发现他已经对massage板块使用了htmlspecialchars() 函数,massage框已经不可能注入了
但是name框只是比较简单的str_replace过滤,那么我们完全可以在name框位置进行插入
还是大写绕过
1 | <SCRIPT>alert(document.cookie)</SCRIPT> |
或者双写绕过
1 | <scr<script>ipt>alert(document.cookie)</script> |
但是我们发现name框有长度限制,那么我们可以直接f12改长度限制,或者bp抓包改txtName字段就行
高级形态(high)
查看源码
massage还是htmlspecialchars函数;而name框则使用了preg_replace函数调用正则表达式的方法,对script做逐字匹配,并使用/i来不区分大小写。
补充一下preg_replace() 函数:
preg_replace()
函数执行一个正则表达式的搜索和替换。
语法:(有些用法我也没太看明白,我写一下自己理解的用法)
preg_replace($pattern, $replacement, $string);$pattern: 就是你想如何搜索,可以是字符串或一个字符串数组。
$replacement: 是用于替换的字符串或字符串数组。
$subject: 要搜索替换的目标字符串或字符串数组。
那么payload便不能再用script标签了
payload就可以是
1 | <img src="" onerror="alert('XSS')"> |
插入方式刚刚在中级形态教过了
超进化形态(impossible)
这个形态就是把两个框都用了htmlspecialchars函数
彻底杜绝了xss攻击
最后咱们把dom型来整一整
初级形态(low)
初级形态没啥意思,跟之前的都一样,就是插入点不太一样
变成了English这个位置
中级形态(medium)
查看源码
先补充一下stripos() 函数
stripos()
函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。
语法:stripos(string,find,start);string:必需,规定被搜索的字符串。
find:必需,规定要查找的字符。
start:可选,规定开始搜索的位置。
这段代码就是先看提交的GET请求里是否存在名为"default"
的参数,并且该参数的值不为空。如果存在,则将其值存储在变量$default
中,并进一步检查其是否包含<script>
标签。如果包含,则重定向到?default=English
。
看下前端源码
找到value值是从这里来的
那么我们可以尝试闭合它来执行
知识补充
’option‘ ’/select‘都是双标签,也就是说会识别两个标签之间的语句,那么我们就人为把它闭合起来,在执行过程中,一旦存在一对标签,那么就会执行这里面的语句,无法构成成对标签的不会执行里面的语句,而’<img‘是单标签,也就是说他要执行的语句涵盖在它里面。>闭合前面<option
所以构造闭合,我们直接
1 | ></option></select><img src=x:alert(alt) onerror=eval(src) alt=xss> |
插入点不变。
高级形态(high)
由于是高级形态,就直接看源码了
很明显的看到,这是一个白名单。
我们又发现是以form表单提交的
那就可以利用
由于 form表单提交的数据 想经过JS 过滤 所以注释部分的javascript 代码 不会被传到服务器端(也就符合了白名单的要求)
payload:
1 | #<script>alert(/xss/)</script> |
超进化形态(impossible)
读一下代码,学一下人家是怎么防御的
最后备注一下
我之前看到有些人在对script标签过滤的绕过中,会在script标签里加入\
这其实是利用某些浏览器或解析器的容错机制。这些机制有时会忽略某些字符或错误,从而导致原本应该被过滤的标签仍然被识别并执行。
虽然没啥用,但是给我这样的小白添加了一些知识面。