zoukankan      html  css  js  c++  java
  • 【DVWA】File Upload(文件上传漏洞)通关教程


    日期:2019-08-01 17:28:33
    更新:
    作者:Bay0net
    介绍:


    0x01、 漏洞介绍

    在渗透测试过程中,能够快速获取服务器权限的一个办法。

    如果开发者对上传的内容过滤的不严,那么就会存在任意文件上传漏洞,就算不能解析,也能挂个黑页,如果被 fghk 利用的话,会造成很不好的影响。

    如果上传的文件,还能够解析,或者配合文件包含漏洞,那么就能获取到服务器的权限了。

    0x02、Low Security Level

    查看源码

    <?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' ] );
    
        // 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>";
        }
    }
    
    ?> 
    

    分析源码

    接受文件,上传到 hackable/uploads/,并且还会把路径回显,最简单的文件上传,上传个一句话木马,直接菜刀就能连上。

    0x03、Medium Security Level

    查看源码

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

    分析源码

    重点在于下面的代码,限制了上传的 Content-Type

    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png"
    

    可以直接上传一个图片,然后在后面加上一句话,成功上传。

    0x04、High Security Level

    查看源码

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

    分析源码

    # 截取后缀名
    $uploaded_ext  = substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1);
    
    # 后缀名白名单
    strtolower( $uploaded_ext ) == "jpg" || strtolower( $uploaded_ext ) == "jpeg" || strtolower( $uploaded_ext ) == "png"
    ?>
    

    利用的几种思路

    具体情况,和 PHP 的版本、中间件的版本相关,在 dvwa 里面无法直接练习。

    1、上传图片马,后缀名是 .png,然后利用文件包含漏洞来配合使用。
    2、利用 %00 截断漏洞上传,需要 PHP 版本小于 5.3.4
    3、利用 .htaccess 解析漏洞
    4、等等,详见 文件上传漏洞总结。。

    0x05、Impossible Security Level

    查看源码

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

    分析源码

    # 函数返回相应选项的值
    in_get(varname)
    
    # 函数返回图片文件的图像标识,失败返回false
    imagecreatefromjpeg ( filename )
    
    # 从 image 图像以 filename为 文件名创建一个 JPEG 图像
    imagejpeg ( image , filename , quality)
    
    # 函数销毁图像资源
    imagedestroy( img )
    

    Impossible 级别的代码对上传文件进行了重命名(为 md5 值,导致 %00 截断无法绕过过滤规则),加入 Anti-CSRF token 防护 CSRF攻击,同时对文件的内容作了严格的检查,导致攻击者无法上传含有恶意脚本的文件。

  • 相关阅读:
    就是要让你彻底学会 @Bean 注解
    Redis持久化深入理解
    设计模式内容聚合
    多线程高并发内容聚合
    实战分析:事务的隔离级别和传播属性
    28个Java开发常用规范技巧总结
    面试官:你了解过Redis对象底层实现吗
    几个高逼格 Linux 命令!
    Spring核心(IoC) 入门解读
    Python Beautiful Soup模块的安装
  • 原文地址:https://www.cnblogs.com/v1vvwv/p/DVWA-File-Upload.html
Copyright © 2011-2022 走看看