一道面试题引发的思考-文件上传白名单
文件上传白名单绕过
这种问题简直是对 CTFer 的重大利好,跟进,举例一些白名单绕过的方法(掺杂几个黑名单绕过)
演示环境
使用 upload-labs 靶场做演示
apache + php,php 版本为 5.2.17
1.00截断
00 0a截断
截断条件
- PHP 版本 < 5.3.4
-
magic_quotes_gpc
关闭
原理:php 的一些函数的底层是 C 语言,而 move_uploaded_file 就是其中之一,遇到 0x00 会截断,0x 表示16进制,URL中%00解码成16进制就是 0x00
可以使用下图的插件判断 PHP 版本
Get00截断
upload-labs pass 12
选择 shell 上传,因为存储文件名为 save_path 拼接上 filenname,因为 save_path 使用 get 方式传输可以使用 00 截断
上传成功后返回上传地址,其实并没有这个文件
因为 00 截断保存文件实为 shell.php
直接访问 shell.php 即可
Post00截断
upload-labs pass 13
因为 post 请求数据包不能自动 url 解码,所以 post 截断需要使用 burp 抓包修改
生成 shell aa.php
2.文件包含
文件包含图片马
如果一个网站存在 PHP 文件包含漏洞,要知道 PHP include 函数的特点就是会把一切包含文件当作 PHP 代码执行,此时就可以上传一张图片利用文件包含漏洞 getshell,图片马的二次渲染绕过也属于此范畴,关于二次渲染可以看之前发过的一篇文章, 链接
upload-labs pass 14
先上传一个图片马
利用文件包含漏洞包含即可
Phar 协议文件包含
之前总结过 phar 反序列化, 链接 ,其中介绍了 phar 协议的文件包含
phar协议要求:
- php大于5.3.0
- 需要将php.ini的参数phar.readonly设置为off
因为phar文件本质就是以中压缩文件,所以可以使用phar伪协议读取执行
很多网站都采用单一入口模式来作为网站文件加载模式
<?php
//单一入口模式
error_reporting(0); //关闭错误显示
$file=addslashes($_GET['r']); //接收文件名
$action=$file==''?'index':$file; //判断为空或者等于index
include($action.'.php'); //载入相应文件
此处就存在文件包含漏洞,可以利用伪协议读取文件源码,但是只能访问php文件
如果该网站同时存在上传图片的功能,这时就可以利用phar反序列化漏洞
首先写一个 test.php,写入要执行的命令
<?php phpinfo();?>
将 test.php 压缩为 test.zip 注意:压缩时选择仅存储,在文件上传处上传 test.zip 文件
将 test.zip 文件后缀改为 jpg,上传 jpg 文件,在 url 中访问
?r=phar://pic/test.jpg/test
不仅可以使用phar协议,zip协议也是可以的
zip文件包含
和phar用法不同效果一致
include($file.'.jpg');
# \x00的截断在php<5.3.4you'xi
将php文件后缀改为jpg(因为是include .jpg),然后用压缩软件压缩为 zip格式,再将 zip 文件后缀名改为 jpg(绕过限制方便图片上传)
/?r=zip://pic/test4.jpg%23test
pic是图片保存目录
这个例子只是利用了phar伪协议解析文件,并没有利用反序列化
文件包含利用方式比较多,不仅可以上传文件包含,也可以结合日志、session文件 getshell,作为扩展内容补充
(扩展)文件包含日志
如果目标主机可以被访问到,且日志中记录了请求信息,就可以通过包含日志文件进行getshell
日志文件路径: ?file=/var/log/nginx/access.log
(扩展)文件包含session
利用session对话进行文件包含利用 参考链接
#poc.php
<!DOCTYPE html>
<form action="ip地址" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />