如果你是一位渗透测试新手,那么我建议你学习本系列文章,通过本系列文章你可以认识常见漏洞以及学会基础php代码审计,在这之前你需要搭建环境DVWA靶场。
一、靶场搭建
首先需要php集成环境,在这里笔者推荐使用phpstudy,下载地址:http://www.phpstudy.net/phpstudy/phpStudy20161103.zip
安装成功后启动如下图所示,Apache和mysql均为绿色
将其解压放在phpstudy的www文件夹下,点击config文件,将config.inc.php文件里的db_user以及db_psd值均修改为root并保存,复制一份config.inc.php.dist文件并将其与原文件放在同一目录下,修改后缀名为.php,否则在启动时会报错,如下图文件1和3所示
二、反射型xss
首先我们从low开始看起,查看源代码
<?php
header ("X-XSS-Protection: 0");
// Is there any input?
if( array_key_exists( "name", $_GET ) && $_GET[ 'name' ] != NULL ) {
// Feedback for end user
echo '<pre>Hello ' . $_GET[ 'name' ] . '</pre>';
}
?>
代码直接引用了name参数,并且未做任何过滤,此时我们提交恶意代码便会被执行,例如<script>alert(23333)</script>
<?php
header ("X-XSS-Protection: 0");
// 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>";
}
?>
可以看到使用了 str_replace
函数,来看下这个函数的语法规则:str_replace(find,replace,string,count)
,其中find,replace,string是必须有的,count可选,表达的意思是将find的值替换为replace,count是对替换数进行计数,在这里我们需要注意的是str_replace函数不区分大小写并且仅进行一次替换。来看medium的源代码,采用黑名单思想,将<script>
标签替换为空,我们可以很轻易的进行绕过,比如<scr<script>ipt>alert(2333) <scr</script>ipt>
<script>
标签的恶意代码例如<svg/onload=alert('XSS')>
<?php
header ("X-XSS-Protection: 0");
// 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>";
} /
?>
可以看到在这里使用了preg_replace
这一函数,来看看语法规则mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换,本实例中使用空格替换script任何一个字母,这样使得大小写字母,类似于middle中的双写绕过均无效,但我们可以使用body标签等进行绕过,例如<BODY ONLOAD=alert('XSS')>
<?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();
?>
可以看到里边有这样一段代码$name = htmlspecialchars( $_GET[ 'name' ] );
对预定义字符进行了实体编码,从而防止了xss的发生,这也是我们在做防御的过程中常用到的一种方法。