WEB常见漏洞之文件上传(靶场篇)3

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: WEB常见漏洞之文件上传(靶场篇)

Pass-11

场景分析

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        $deny_ext = array("php","php5","php4","php3","php2","html","htm","phtml","pht","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess","ini");
        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = UPLOAD_PATH.'/'.$file_name;        
        if (move_uploaded_file($temp_file, $img_path)) {
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else {
        $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }
}

这是一个后端校验的 PHP 代码,从上可知其中定义了文件后缀名黑名单,黑名单里几乎包含了所有可解析的后缀名、.htaccess以及.ini,当上传文件的后缀名与黑名单匹配时会自动去除后缀名,没有了后缀名文件自然也无法解析,但由于只过滤单次后缀名,因此我们可以双写后缀名绕过限制

双写后缀名

上传名为mac.pphphp的 php 文件

成功访问上传文件


Pass-12

场景分析

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else{
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}

这是一个后端校验的 PHP 代码,从上可知其中定义了文件后缀名白名单,白名单中包含了jpg、png、gif,脚本会检测上传数据包的 MIME 类型是否在白名单当中,但由于文件上传路径可控,因此我们可以使用00截断的方式绕过限制。


那什么是00截断呢?

在 ASCII 码中0一般作为特殊字符保留,一般代表字符串结束。0x00、%00、/00其实都代表同一意思,当%00出现时其实就目标就会认为内容读取已经结束,从而忽略到%00后的字符串。但在 PHP 中的00截断需要注意几个前提:



1、PHP版本小于5.3.42、
PHP中的magic_quotes_gpc关闭

00截断

上传 php 文件并将文件路径修改为../upload/mac.php%00

成功访问上传文件

Pass-13

场景分析


$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传失败";
        }
    } else {
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}

这是一个后端校验的 PHP 代码,从上可知其中定义了文件后缀名白名单,白名单中包含了jpg、png、gif,脚本会检测上传数据包的 MIME 类型是否在白名单当中,但由于文件上传路径可控,因此我们可以使用00截断的方式绕过限制。


那什么是00截断呢?

在 ASCII 码中0一般作为特殊字符保留,一般代表字符串结束。0x00、%00、/00其实都代表同一意思,当%00出现时其实就目标就会认为内容读取已经结束,从而忽略到%00后的字符串。但在 PHP 中的00截断需要注意几个前提:

    1、PHP版本小于5.3.42、
    PHP中的magic_quotes_gpc关闭

    00截断+URL编码

    上传php 文件并将文件路径修改为../upload/mac.php%00,本题与上题类似,只不过修改位置进行了替换,我们需要对%00进行URL编码

    成功访问上传文件

    Pass-14

    场景分析

    本题对文件内容的前两个字节进行检测,同时提示其中存在文件包含漏洞

    640.png

    function getReailFileType($filename){
        $file = fopen($filename, "rb");
        $bin = fread($file, 2); //只读2字节
        fclose($file);
        $strInfo = @unpack("C2chars", $bin);    
        $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);    
        $fileType = '';    
        switch($typeCode){      
            case 255216:            
                $fileType = 'jpg';
                break;
            case 13780:            
                $fileType = 'png';
                break;        
            case 7173:            
                $fileType = 'gif';
                break;
            default:            
                $fileType = 'unknown';
            }    
            return $fileType;
    }
    $is_upload = false;
    $msg = null;
    if(isset($_POST['submit'])){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $file_type = getReailFileType($temp_file);
        if($file_type == 'unknown'){
            $msg = "文件未知,上传失败!";
        }else{
            $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;
            if(move_uploaded_file($temp_file,$img_path)){
                $is_upload = true;
            } else {
                $msg = "上传出错!";
            }
        }
    }

    这是一个后端校验的 PHP 代码,从上可知其中定义了文件白名单,白名单中包含了jpg、png、gif,脚本会检查文件开头的两个字节来判断文件是否为白名单。如果判断文件不为白名单则上传失败,因此我们可以伪造图片头并在图片中插入代码,使用图片马上传的方式可绕过限制吗,然后配合文件包含完成脚本解析


    结合文件包含漏洞

    文件包含漏洞通过参数file来指定图片马可进行解析

    640.png


    文件包含+图片马

    首先我们需要制作图片马,在不同系统中制作方式也不同

    # Windows
    copy 1.png /a + 2.php /b 3.png
    # Linux
    cat 1.png 2.php > 3.png

    图片马生成后开始上传文件

    成功访问上传文件

    配合文件包含成功解析


    include.php?file=upload/4720220519155838.png


    640.png

    Pass-15

    场景分析

    查看提示信息本题使用getimagesize()进行检测,同时提示其中存在文件包含漏洞


    那什么是 getimagesize() 函数呢?

    getimagesize() 函数用于获取图像大小及相关信息,图片对象包括 GIF、JPG、PNG 等,如果获取成功会返回一个数组,失败则会返回 FALSE 并产生一条 E_WARNING 级的错误信息。

    function isImage($filename){
        $types = '.jpeg|.png|.gif';
        if(file_exists($filename)){
            $info = getimagesize($filename);
            $ext = image_type_to_extension($info[2]);
            if(stripos($types,$ext)>=0){
                return $ext;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
    $is_upload = false;
    $msg = null;
    if(isset($_POST['submit'])){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $res = isImage($temp_file);
        if(!$res){
            $msg = "文件未知,上传失败!";
        }else{
            $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").$res;
            if(move_uploaded_file($temp_file,$img_path)){
                $is_upload = true;
            } else {
                $msg = "上传出错!";
            }
        }
    }

    这是一个后端校验的 PHP 代码,从上可知其中定义了文件后缀名白名单,白名单中只包含了图片后缀,与此同时它通过getimagesize()函数检查文件是否为图片。我们可以使用上传图片马的方式绕过限制。但它与上一题略有不同,在上一题中如果我们只修改文件前两个字节还能够上传成功,那么这题就不行了,需要实实在在构造一个图片马才行。


    结合文件包含漏洞

    由于题中本身存在文件包含漏洞,通过参数file来指定图片马可完成解析

    文件包含+图片马(首部检查)

    首先我们需要制作图片马,在不同系统中制作方式也不同

    # Windows
    copy 1.png /a + 2.php /b 3.png
    # Linux
    cat 1.png 2.php > 3.png

    图片马生成后开始上传文件

    成功访问上传文件

    配合文件包含成功解析


    include.php?file=upload/4720220519161618.png

    Pass-16

    场景分析

    本题使用exif_imagetype()进行检测,同时提示其中存在文件包含漏洞


    那什么是 exif_imagetype() 函数呢?

    exif_imagetype() 函数会读取一个图像的第一个字节并检查其签名。主要用来检查某个文件是否为图像。但它需要在php.ini中添加php_exif扩展并重启应用,否则无法调用该函数

    function isImage($filename){
        //需要开启php_exif模块
        $image_type = exif_imagetype($filename);
        switch ($image_type) {
            case IMAGETYPE_GIF:
                return "gif";
                break;
            case IMAGETYPE_JPEG:
                return "jpg";
                break;
            case IMAGETYPE_PNG:
                return "png";
                break;    
            default:
                return false;
                break;
        }
    }
    $is_upload = false;
    $msg = null;
    if(isset($_POST['submit'])){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $res = isImage($temp_file);
        if(!$res){
            $msg = "文件未知,上传失败!";
        }else{
            $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$res;
            if(move_uploaded_file($temp_file,$img_path)){
                $is_upload = true;
            } else {
                $msg = "上传出错!";
            }
        }
    }

    这是一个后端校验的 PHP 代码,从上可知其中定义了文件后缀名白名单,白名单中只包含了图片后缀,与此同时它通过exif_imagetype()函数检查文件是否为图片。我们可以使用上传图片马的方式绕过限制。


    结合文件包含漏洞

    由于题中本身存在文件包含漏洞,通过参数file来指定图片马可完成解析

    文件包含+图片马(函数检查)

    首先我们需要制作图片马,在不同系统中制作方式也不同

    # Windows
    copy 1.png /a + 2.php /b 3.png
    # Linux
    cat 1.png 2.php > 3.png

    图片马生成后开始上传文件

    成功访问上传文件

    配合文件包含成功解析


    include.php?file=upload/9220220519163603.png

    目录
    相关文章
    |
    2月前
    |
    缓存 移动开发 安全
    Web安全-HTTP响应拆分(CRLF注入)漏洞
    Web安全-HTTP响应拆分(CRLF注入)漏洞
    138 1
    |
    3月前
    |
    安全 关系型数据库 MySQL
    Web安全-条件竞争漏洞
    Web安全-条件竞争漏洞
    50 0
    |
    2月前
    |
    SQL
    Web for Pentester SQL sql注入靶场
    Web for Pentester SQL sql注入靶场
    |
    3月前
    |
    缓存 移动开发 安全
    Web安全-HTTP响应拆分(CRLF注入)漏洞
    Web安全-HTTP响应拆分(CRLF注入)漏洞
    179 8
    |
    3月前
    |
    安全 关系型数据库 Shell
    Web安全-浅析CSV注入漏洞的原理及利用
    Web安全-浅析CSV注入漏洞的原理及利用
    159 3
    |
    3月前
    |
    安全 应用服务中间件 开发工具
    Web安全-SVN信息泄露漏洞分析
    Web安全-SVN信息泄露漏洞分析
    218 2
    |
    3月前
    |
    JSON 安全 JavaScript
    Web安全-JQuery框架XSS漏洞浅析
    Web安全-JQuery框架XSS漏洞浅析
    500 2
    |
    3月前
    |
    安全 搜索推荐 应用服务中间件
    Web安全-目录遍历漏洞
    Web安全-目录遍历漏洞
    90 2
    |
    2月前
    |
    XML JSON API
    ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
    【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
    138 3
    |
    1月前
    |
    设计模式 前端开发 数据库
    Python Web开发:Django框架下的全栈开发实战
    【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
    151 45