DVWA 安全测试XSS篇
DVWA (Damn Vulnerable Web Application)提供安全测试人员一个很好的安全测试学习环境, 这篇文章主要说明XSS测试的相关练习与安全防护.
反射型XSS练习 (低安全级别)
这段PHP代码让使用者输入name,并且根据输入印出该name
由于没有相关的XSS防护因此很容易就可以进行XSS反射型的攻击
攻击方式: <script>alert(“a”)</script>
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
XSS反射型 – 中安全级别
在中安全级别, 我们可以看到该代码对于name 采用将<script>的字符串过滤取代为空白的方式, 但是这样还是很容议会被绕过,
攻击方式: <sc<script>ript>alert(“xss”)</script>
攻击方式:<ScrIPT>alert(“xss”)</ScriPT>
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = str_replace( '<script>', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
XSS反射型 高安全性
在高安全性下, 这段代码利用正则表示法将script相关字符取代为空白, 这使得大小写绕过的方法都不再有效, 由于该正则表示法仅针对<script>, 因此我们可以用其他方式绕过
攻击方式: <img src=1 onerror=alert(“xss”)>
<?php
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Get input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] );
// Feedback for end user
echo "<pre>Hello ${name}</pre>";
}
?>
完整的防护方式
这段代码使用PHP的函数 htmlspecialchars函数把预定义的字符&、”、 ’、<、>转换为HTML实体 ,防止浏览器作为HTML元素执行
<?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();
?>
反射型XSS小节
反射型XSS 主要根据使用者输入, 直接在页面上回传相关讯息
如果不会背后端储存, 一般来说危害的程度较低, 但是难免会被黑客作其他其他不可预期的应用, 整理DVWA XSS 几种安全防护层级的方式与绕过的攻击方式
安全等级 | 防护方式 | 反正型XSS注入方式 |
低 | 无 | <script>alert(“xss”)</script> |
中 | $name = str_replace( '<script>', '', $_GET[ 'name' ] ); | <SCript>alert(“xss”)</scriPT> |
高 | $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $_GET[ 'name' ] ); | <img src=1 onerror=alert(“xss”)> |
完整 | $name = htmlspecialchars( $_GET[ 'name' ] ); |