upload-labs 练习笔记
简述
因为主要是初学者学习相关知识点,而不是为了练手,所以基本先看提示,提示不行了,再看源码。
预备知识
提交的MIME 类型只是客户告知服务器应该怎样处理,服务器完全可以无视。而响应的 MIME 是告知 浏览器应该如何显示。提交的 MIME 是浏览器通过上传文件的后缀名推导出来的。
特殊点:
- 
.user.ini 与 .htaccess 当上传文件成功后没有对文件重命名时,可以考虑上传这两个配置文件进行试探。 
- 
关于不同平台的特性, windows 平台时 apache 可以将以下 url 中的文件识别为网站的 inj.php 文件,并且将其当作 php 执行。 inj.php.. inj.php空. inj.php空空 inj.php.空. 但在 Linux 平台上,url 的文件必须和网站的文件完全匹配。并且,当文件后缀含有空格,将不会被 apache 当作脚本识别。例如 inj.php空 不支持,会直接显示源码。 inj.php. 可以正常当作 php 脚本执行。
- 
代码正面刚。 
labs
- 
lab-1: 提示是 js 检查,故尝试将后缀修改为 .png ,而在数据包中将文件名后缀修改为 .php 成功。 
- 
lab -2:提示MIME 检查,故可以直接上传 .png 的后门文件,此时 MIME 为浏览器推导出来的 image/png ,然后再在数据包中修改文件后缀为 php 即可 
- 
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 的形式接受,已经产生截断。 
- 
考察的是上传配置文件 .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 下,任何格式通过 在后缀添加 . .使得都可以上传。
- 
考察的是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 平台下,当文件后缀含有空格时无法正常解析。 
- 
细细分析 $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext;上传成功后会更名,所以 .htaccess 和 .user.ini 没有太大的上传意义。(如果配合解析漏洞) 代码正面刚的话,由于缺少转换大小写,只要对后缀进行大小写绕过黑名单即可。 前面几关在 windows 平台下末尾加 . .的方法依然可行
- 
和第六关几乎一样,因为会更改文件名,所以两个配置文件没有太大上传意义。所以在windows 平台下,末尾加空格或点的时候依然可行。 
- 
没有对文件重命名,所以可以通过在文件末尾加点的方式成功上传。 
- 
首先,上传成功后会文件重命名,所以 两个配置文件没有太大上传意义。再因为是以过滤后的后缀作为文件后缀,所以 Windows 平台下文件名后加 . .无效。但代码中没有对 ::$DATA进行过滤,故文件名后加上即可。但 Linux 平台下暂时无解。 
- 
因为没有文件重命名 windows 平台下,可以 后缀加 . .从而直接绕过代码逻辑,上传所有类型的文件。
- 
代码中是采用正则表达式来过滤后缀,但是这个方法只是一次过滤,而并不是递归过滤。所以可以采用双写的方式上传两个配置文件,或者直接上传 php 文件。 
- 
考察的是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 从而达到截断效果 
- 
和12 关一样,区别在于是 POST 型提交,需要手动转码。 
- 
文件包含漏洞加文件上传。查看提示,说是检查文件内容前两个字节。那么直接以文本文件的形式打开一个图片,然后在之后加上php 代码。 这里奇怪的是,我在文件内容前面加上响应的字节却没有作用。后来发现,直接在数据包修改会被当作 unicode 码,%ff 经转码后再提交给 代码时会被识别为 %u00ff 也就是十进制 195191。所以像文件内容这类编码的东西,最好不要在数据包中修改,直接在文件中修改。2020.12.1 版本的 burp 没有了 hex 视图功能,所以不能经过 url 编解码进行修改 
- 
和14 关解法一样,不过代码检验逻辑不同,是用到了getimagesize() 函数 
- 
和前两关类似,不过使用的是exif_imagetype()。因为我们是给一个正常图片末尾加上 php 代码,所以这三关的验证都可以正常通过。 
- 
感觉是绕过 imagecreatefromjpeg,又感觉是条件竞争,但题目又说是二次渲染。 新感觉,二次渲染 新新感觉,上传之后重命名是二次渲染,也就是说同时只存在一个文件。所以应该是文件包含 加上条件竞争 所以,二次渲染+文件包含 或者 条件竞争+文件包含 都可以。不过前者明显更能持久创建后门。 这块就先试试条件竞争,条件。 条件竞争成功,但是如果 图片 太大,好像include 不成功。include 应该有大小限制 
- 
经典的条件竞争 
- 
代码稍微有点多,要理清思路。 根据源码,大概猜想它某一处完成的工作。大概是检查后缀、大小、文件是否存在,移动文件,对文件重命名。 奇怪的是,在我的电脑上,它一直提醒文件无法上传到临时目录,所以要看看是这个lab 出问题还是其它lab 也这样。 条件竞争+解析漏洞 
- 
感觉更简单了?因为黑名单没有大小写检验,故可以直接大小写后缀的形式绕过。如果是搭建在 windows 下,直接截断也可通过。即构造文件名 inj.php%00.png 
- 
通过数组的方式进行绕过 

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号