DVWA 储存型XSS攻击与防护

DVWA 储存型XSS攻击与防护

这篇文章主要利用DVWA的安全测试环境说明储存型XSS攻击与几种无效的防护说明, 储存型的XSS是最危险的的攻击, 因为XSS被系统储存之后, 将可能执行各种非预期的JavaScript脚本攻击, 这篇文章透过PHP讲解几种无效的攻击方式

留言板的储存型XSS攻击

在DVWA低安全性下, 一般常见的XSS攻击为储存型, 从这个代码可以看出, 主要接受使用者两个参数输入 message 与name, 这段代码虽然有做下列的字符号过滤, 但是对于XSS并无防护 :

  • trim 去除空白
  • mysql_real_escape_string 去除特殊符号
  • stripslashes 去除反斜杠

攻击方式: <script>alert(“xss”)</script>

<?php 
if( isset( $_POST[ 'btnSign' ] ) ) { 
    // Get input 
    $message = trim( $_POST[ 'mtxMessage' ] ); 
    $name    = trim( $_POST[ 'txtName' ] ); 
    // Sanitize message input 
    $message = stripslashes( $message ); 
    $message = mysql_real_escape_string( $message ); 
    // Sanitize name input 
    $name = mysql_real_escape_string( $name ); 
    // Update database 
    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );"; 
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' ); 
    //mysql_close(); 
} 
?>

中安全层级

在中安全层级, 已经额外加入下列防护方式, 但是还是不完整可以被绕过攻击, 主要是因为 name参数,只是简单过滤了<script>

  • strip_tags() 去字符串中的HTML、XML以及PHP的标签
  • addslashes() 函数返回在预定义字符

绕过攻击: name 输入 <sc<script>ript>alert(“xss”)</script>

绕过攻击:name透过大小写的方式 <Script>alert(/xss/)</scRIpt>

<?php 
if( isset( $_POST[ 'btnSign' ] ) ) { 
    // Get input 
    $message = trim( $_POST[ 'mtxMessage' ] ); 
    $name    = trim( $_POST[ 'txtName' ] ); 
    // Sanitize message input 
    $message = strip_tags( addslashes( $message ) ); 
    $message = mysql_real_escape_string( $message ); 
    $message = htmlspecialchars( $message ); 
    // Sanitize name input 
    $name = str_replace( '<script>', '', $name ); 
    $name = mysql_real_escape_string( $name ); 
    // Update database 
    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );"; 
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' ); 
    //mysql_close(); 
} 
?>

高安全层级防护

高安全层级的防护主要利用正则表达将script的字串过滤掉:

$name = preg_replace( ‘/<(.)s(.)c(.)r(.)i(.)p(.)t/i’, ”, $name );

但是我们还是可以利用img 或是iframe等方式进行攻击绕过

攻击方式: <img src=1 onerror=alert(“xss”)>

<?php 
if( isset( $_POST[ 'btnSign' ] ) ) { 
    // Get input 
    $message = trim( $_POST[ 'mtxMessage' ] ); 
    $name    = trim( $_POST[ 'txtName' ] ); 
    // Sanitize message input 
    $message = strip_tags( addslashes( $message ) ); 
    $message = mysql_real_escape_string( $message ); 
    $message = htmlspecialchars( $message ); 
    // Sanitize name input 
    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name ); 
    $name = mysql_real_escape_string( $name ); 
    // Update database 
    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );"; 
    $result = mysql_query( $query ) or die( '<pre>' . mysql_error() . '</pre>' ); 
    //mysql_close(); 
} 
?>

XSS 完整的防护方式

完整的防护方式主要使用 htmlspecialchars 来解决.

<?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 = mysql_real_escape_string( $message ); 
    $message = htmlspecialchars( $message ); 
    // Sanitize name input 
    $name = stripslashes( $name ); 
    $name = mysql_real_escape_string( $name ); 
    $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(); 
?>

Leave a Reply

Your email address will not be published. Required fields are marked *