dvwa文件上传通关及代码分析

文章目录

low等级

查看源码:

复制代码
<?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>";
    }
}

?> 

对上传的文件没有任何过滤,上传一个具有一句话木马的php文件:

上传成功,并且返回成功的地址:

medium等级

做代码审计:

复制代码
<?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>';
    }
}

?>

发现它是接收了一个http头部,并用post方法传参,并在

复制代码
if(($uploaded_type == "image/jpeg" || $uploaded_type == "image/png") && ($uploaded_size < 100000))

限制了接收文件的类型,即只接收jpeg、png格式的图片,并限制了上传文件的大小不能超过100k。

我们继续上传有一句话木马的php文件,然后用bp抓包,修改文件的类型字段为image/png:

点击放包后可以看到上传文件成功:

high等级

查看源码:

复制代码
<?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);

strrpos(string,find,start) 函数返回字符串 find 在另一字符串 string 中最后一次出现的位置,如果没有找到字符串则返回 false,可选参数 start 规定在何处开始搜索。

getimagesize( $uploaded_tmp)通过读取文件头,返回图片的长、宽等信息,如果没有相关的图片文件头则报错

这段代码在medium的基础上增加了读取文件头,判断文件幻数来更严格地判断文件的类型,提高了过滤的强度。

接下来我们准备一张图片和包含一句话木马的php文件:

用下面的命令将它们合并成一个新的图片:

复制代码
copy dvwa_email.jpg/b + 1.php/a  2.jpg

然后直接上传,网页提示上传成功:

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

?>

发现这段代码包含了high等级的过滤策略,会检查图片文件的头部,用幻数来更严格地判断文件的类型,不仅如此,它还在

复制代码
if( $uploaded_type == 'image/jpeg' ) {
            $img = imagecreatefromjpeg( $uploaded_tmp );
            imagejpeg( $img, $temp_file, 100);
        }
        else {
            $img = imagecreatefrompng( $uploaded_tmp );
            imagepng( $img, $temp_file, 9);
        }

中用imagecreatefromjpeg( $uploaded_tmp )函数对上传的图片进行二次渲染,相当于直接生成一个外观相同的新图片文件,这样一来,如果图片中存在恶意代码,就会被过滤,这中方式更严密地防范了漏洞,导致攻击者无法上传木马文件。

相关推荐
Zhu7584 小时前
在k8s集群部署MySQL单实例,支持多个主流发行版
android·mysql·kubernetes
AFinalStone7 小时前
Android 7系统异常问题排查(四)Framework层(上)—System Server Watchdog
android·系统异常
宝杰X79 小时前
Android Room3 多平台数据库
android·数据库
huibin14785236912 小时前
热缓解学习记录
android·学习
小田的博客15 小时前
SAP MM 供应商银行主数据更新报错!message R1228!
android·java·服务器
一笑的小酒馆16 小时前
Android智能猫砂盆视频加载慢卡顿问题分析
android
只会cv的小前端17 小时前
七巧低代码服务端脚本使用方法
android·低代码·rxjava
17 小时前
Android 自定义 View 实战:从零打造工业级全向摇杆控件(OmniJoystickView)
android·kotlin·自定义view·摇杆控件
雨白17 小时前
深入理解 Kotlin 协程 (十一):以逸待劳,探秘 select 多路复用与并发安全策略
android·kotlin
hunterandroid20 小时前
[Android 从零到一] Android 深度链接与 App Links:从 URI Scheme 到可验证的应用跳转
android