### 2、存储型xss
### ①、Low
漏洞代码:
```
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Sanitize name input
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
```
分析与利用:
分析代码执行流程:首先把用户输入的数据,使用trim去除字符串首尾处的空白字符(或者其他字符)。之后stripslashes方法返回一个去除转义反斜线后的字符串(' 转换为 ' 等等),双反斜线()被转换为单个反斜线()。
之后mysqli_real_escape_string对字符串特殊符号n r ‘ “ 等进行转义
最终未对用户输入数据进行xss检测编码,直接写入到数据库中,于是造成存储型xss漏洞。
构造利用:
![](/upload/attach/201710/201710161534_1db8ghmvo9iqm33.jpg)
Message文本框可以直接写入<script>:
![](/upload/attach/201710/201710161535_tcz8tltuua3t4gz.jpg)
name字段对输入字符有长度限制,这个可以通过burpsuite抓包改包绕过:(burp使用在此不再赘述,请自行查阅教程)
![](/upload/attach/201710/201710161535_0zcrabyvta5id43.jpg)
修改txtname字段为payload脚本:
![](/upload/attach/201710/201710161536_hcn058e5tp2ebcu.jpg)
成功执行xss脚本:
![](/upload/attach/201710/201710161536_9ake91mqe44v3av.jpg)
### ②、medium
漏洞代码:
```
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = str_replace( '<script>', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
```
分析与利用:
以上代码我们重点关注两行:
```
$message = htmlspecialchars( $message );
$name = str_replace( '<script>', '', $name );
```
Message由于使用了htmlspecialchars方法对用户输入数据进行编码转换,因此不存在xss漏洞。
但是name由于仅仅用了str_replace方法把<script>替换为空,于是我们有以下三种方法来绕过:
非<script>标签:
```
<img src=0 onerror=alert(/xss1/)>
```
大小写转换:
```
<Script>alert(/xss2/)</sCript>
```
双重<script>标签:
```
<sc<script>ript>alert(/xss3/)</script>
```
由于name字段对长度有限制,使用以上改包抓包方式,依次修改参数值,结果如下:
![](/upload/attach/201710/201710161537_6zp0igmb3acwl4e.jpg)
![](/upload/attach/201710/201710161537_t418zbxpieh8nb4.jpg)
![](/upload/attach/201710/201710161537_aqy5amxpgta48qt.jpg)
### ③、high
漏洞代码:
```
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = strip_tags( addslashes( $message ) );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
// Update database
$query = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
//mysql_close();
}
?>
```
分析与利用:
这里我们重点关注两行代码:
```
$message = htmlspecialchars( $message );
```
Message依旧不可绕过
```
$name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );
```
preg_replace执行一个正则表达式的搜索和替换,此时可以使用别的标签<img> <a> <iframe>等,比如刚刚使用过的<img>,构造payload :<img src=0 onerror=alert(/xss/)>,
改包替换绕过,成功执行xss代码:
![](/upload/attach/201710/201710161538_f1l75kititc8xlu.jpg)
### ④、impossible
安全代码:
```
<?php
if( isset( $_POST[ 'btnSign' ] ) ) {
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
// Get input
$message = trim( $_POST[ 'mtxMessage' ] );
$name = trim( $_POST[ 'txtName' ] );
// Sanitize message input
$message = stripslashes( $message );
$message = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $message ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$message = htmlspecialchars( $message );
// Sanitize name input
$name = stripslashes( $name );
$name = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"], $name ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$name = htmlspecialchars( $name );
// Update database
$data = $db->prepare( 'INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name );' );
$data->bindParam( ':message', $message, PDO::PARAM_STR );
$data->bindParam( ':name', $name, PDO::PARAM_STR );
$data->execute();
}
// Generate Anti-CSRF token
generateSessionToken();
?>
```
分析:
在此name和message都使用了htmlspecialchars方法,于是此处不存在xss漏洞。