Loading

upload-labs 练习笔记

简述

因为主要是初学者学习相关知识点,而不是为了练手,所以基本先看提示,提示不行了,再看源码。

预备知识

提交的MIME 类型只是客户告知服务器应该怎样处理,服务器完全可以无视。而响应的 MIME 是告知 浏览器应该如何显示。提交的 MIME 是浏览器通过上传文件的后缀名推导出来的。

特殊点:

  1. .user.ini 与 .htaccess 当上传文件成功后没有对文件重命名时,可以考虑上传这两个配置文件进行试探。

  2. 关于不同平台的特性,

    windows 平台时 apache 可以将以下 url 中的文件识别为网站的 inj.php 文件,并且将其当作 php 执行。
    inj.php..
    inj.php空.
    inj.php空空
    inj.php.空.
    
    但在 Linux 平台上,url 的文件必须和网站的文件完全匹配。并且,当文件后缀含有空格,将不会被 apache 当作脚本识别。例如
    inj.php空 不支持,会直接显示源码。
    inj.php. 可以正常当作 php 脚本执行。
    
  3. 代码正面刚。

labs

  1. lab-1: 提示是 js 检查,故尝试将后缀修改为 .png ,而在数据包中将文件名后缀修改为 .php 成功。

  2. lab -2:提示MIME 检查,故可以直接上传 .png 的后门文件,此时 MIME 为浏览器推导出来的 image/png ,然后再在数据包中修改文件后缀为 php 即可

  3. lab-3: 提醒不允许上传指定后缀的文件,尝试利用后缀大小写都失败了。。。

    考点是默认 apache 配置文件中有 AddType application/x-httpd-php .php .phtml

    $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext; 
    

    因为通过验证后会修改文件名,所以无法上传 .htaccess 或者 .user.ini 。

    因为是提取过滤后的后缀作为文件后缀,所以无法使用文件名末尾加 . . 的形式在 windows 平台进行绕过。

    无法使用 %00 截断,因为用户提交的数据是以 $_FILE 的形式接受,已经产生截断。

  4. 考察的是上传配置文件 .htaccess

    'inj.php. .'
    
    //行末写出处理后的结果
    $file_name = trim($_FILES['upload_file']['name']);  //'inj.php. .'
    $file_name = deldot($file_name);					//'inj.php. '
    $file_ext = strrchr($file_name, '.');				//'. '
    $file_ext = strtolower($file_ext); 					//'. '
    $file_ext = str_ireplace('::$DATA', '', $file_ext); //'. '
    $file_ext = trim($file_ext); 						//'.'
    
    $img_path = UPLOAD_PATH.'/'.$file_name;    //'inj.php. '
    
    

    所以就可以上传 .htaccess 文件

    首先考虑绕过,采取 inj.php. . 在 windows 平台下可以直接上传。而linux 平台由于后缀中存在空格,所以不行。

    .htaccess 因为没有在黑名单内,故也可以上传。

    .user.ini 因为黑名单有 .ini 所以无法直接上传,但可以采用 .user.ini. . 的形式在windows 平台下上传。

    在 windows 下,任何格式通过 在后缀添加 . . 使得都可以上传。

  5. 考察的是windows平台特性。

    和第四关代码处理逻辑基本相同,可以看到代码中禁止了 .htaccess 上传。但没有 .ini 后缀限制。

    所以这块的目的是使得后缀通过验证 而 文件可以被当作 php 文件执行。

    这就利用windows 特性,考虑这样的文件

    'inj.php. .'
    
    //行末写出处理后的结果
    $file_name = trim($_FILES['upload_file']['name']);  //'inj.php. .'
    $file_name = deldot($file_name);					//'inj.php. '
    $file_ext = strrchr($file_name, '.');				//'. '
    $file_ext = strtolower($file_ext); 					//'. '
    $file_ext = str_ireplace('::$DATA', '', $file_ext); //'. '
    $file_ext = trim($file_ext); 						//'.'
    
    $img_path = UPLOAD_PATH.'/'.$file_name;    //'inj.php. '
    
    'inj.php.. ..'
    

    最终得到的后缀为一个点,由于它不在黑名单内,故通过验证。而在 windows 平台 最终的文件名保存时会自动去除尾部的空格和点。

    而在我的 Linux 平台下,当文件后缀含有空格时无法正常解析。

  6. 细细分析

    $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext; 
    

    上传成功后会更名,所以 .htaccess 和 .user.ini 没有太大的上传意义。(如果配合解析漏洞)

    代码正面刚的话,由于缺少转换大小写,只要对后缀进行大小写绕过黑名单即可。

    前面几关在 windows 平台下末尾加 . . 的方法依然可行

  7. 和第六关几乎一样,因为会更改文件名,所以两个配置文件没有太大上传意义。所以在windows 平台下,末尾加空格或点的时候依然可行。

  8. 没有对文件重命名,所以可以通过在文件末尾加点的方式成功上传。

  9. 首先,上传成功后会文件重命名,所以 两个配置文件没有太大上传意义。再因为是以过滤后的后缀作为文件后缀,所以 Windows 平台下文件名后加 . . 无效。

    但代码中没有对 ::$DATA 进行过滤,故文件名后加上即可。

    但 Linux 平台下暂时无解。

  10. 因为没有文件重命名 windows 平台下,可以 后缀加 . . 从而直接绕过代码逻辑,上传所有类型的文件。

  11. 代码中是采用正则表达式来过滤后缀,但是这个方法只是一次过滤,而并不是递归过滤。所以可以采用双写的方式上传两个配置文件,或者直接上传 php 文件。

  12. 考察的是00截断,可以注意到数据包中请求路径有 save_path

    代码是通过 POST 中的文件名来判断是否在白名单内,而保存的时候使用 GET 中 save_path 加上日期文件名来保存

    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    
    $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
    

    所以就可以利用 00 截断,直接将 POST 文件后缀更改为 .png 并且将 GET 中的 save_path 中加上文件名与 %00 从而达到截断效果

  13. 和12 关一样,区别在于是 POST 型提交,需要手动转码。

    https://www.freebuf.com/articles/web/179401.html

  14. 文件包含漏洞加文件上传。查看提示,说是检查文件内容前两个字节。那么直接以文本文件的形式打开一个图片,然后在之后加上php 代码。

    这里奇怪的是,我在文件内容前面加上响应的字节却没有作用。后来发现,直接在数据包修改会被当作 unicode 码,%ff 经转码后再提交给 代码时会被识别为 %u00ff 也就是十进制 195191。所以像文件内容这类编码的东西,最好不要在数据包中修改,直接在文件中修改。2020.12.1 版本的 burp 没有了 hex 视图功能,所以不能经过 url 编解码进行修改

  15. 和14 关解法一样,不过代码检验逻辑不同,是用到了getimagesize() 函数

  16. 和前两关类似,不过使用的是exif_imagetype()。因为我们是给一个正常图片末尾加上 php 代码,所以这三关的验证都可以正常通过。

  17. 感觉是绕过 imagecreatefromjpeg,又感觉是条件竞争,但题目又说是二次渲染。

    新感觉,二次渲染

    新新感觉,上传之后重命名是二次渲染,也就是说同时只存在一个文件。所以应该是文件包含 加上条件竞争

    所以,二次渲染+文件包含 或者 条件竞争+文件包含 都可以。不过前者明显更能持久创建后门。

    这块就先试试条件竞争,条件。

    条件竞争成功,但是如果 图片 太大,好像include 不成功。include 应该有大小限制

  18. 经典的条件竞争

  19. 代码稍微有点多,要理清思路。

    根据源码,大概猜想它某一处完成的工作。大概是检查后缀、大小、文件是否存在,移动文件,对文件重命名。

    奇怪的是,在我的电脑上,它一直提醒文件无法上传到临时目录,所以要看看是这个lab 出问题还是其它lab 也这样。

    条件竞争+解析漏洞

  20. 感觉更简单了?因为黑名单没有大小写检验,故可以直接大小写后缀的形式绕过。如果是搭建在 windows 下,直接截断也可通过。即构造文件名 inj.php%00.png

  21. 通过数组的方式进行绕过

posted @ 2021-03-28 09:57  沉云  阅读(199)  评论(0编辑  收藏  举报