任意文件上传
概述
大多数网站都有文件上传的接口,但如果在后台开发时没有对上传的文件进行安全考虑或者采用了有缺陷的措施,导致攻击者可以通过一些手段绕过安全措施从而上传一些恶意文件,从而通过对恶意文件的访问来控制整个后台
分类及实战
客户端检测绕过(javascript检测)
-
根据提示,只能上传图片,检查前端源代码,可以看到checkfileext()函数,只需要在前端删除该函数即可上传一个非图片的文件
-
把以.php结尾的小马改为以.jpg|.png|.gif结尾,用burpsuite抓包,再把.jpg|.png|.gif改回.php即可上传成功
服务端验证绕过
-
检查后缀
-
黑名单
-
上传特殊可解析的后缀名文件
-
首先会获取到前端的提交请求,然后定义了一个数组(定义图片上传指定类型),然后通过upload_sick函数对上传的文件进行一定的检查。
分析upload_sick函数存在漏洞的原因是因为 $ _FILES() 这个全局的方法是通过浏览器http头去获取的content-type,content-type是前端用户可以控制的。容易被绕过。- 上传一张正常的符合标准的图片,对其content-type进行抓包操作。可见正常上传符合要求的图片中数据包中content-type为image/png对比符合条件,而php文件则不符合条件返回文件类型错误。
-
截断上传数据包,修改Content-Type为image/gif,然后放行数据包
-
通过使用 PHP 的全局数组 $_FILES,你可以从客户计算机向远程服务器上传文件。
第一个参数是表单的 input name,第二个下标可以是 “name”, “type”, “size”, “tmp_name” 或 “error”-
常见类型
- $_FILES[“file”][“name”] - 被上传文件的名称
- $_FILES[“file”][“type”] - 被上传文件的类型
- $_FILES[“file”][“size”] - 被上传文件的大小,以字节计
- $_FILES[“file”][“tmp_name”] - 存储在服务器的文件的临时副本的名称
- $_FILES[“file”][“error”] - 由文件上传导致的错误代码
- 详细可参考:http://www.w3school.com.cn/php/php_file_upload.asp
-
-
我们可上传php3,php5…等这样可以被服务器解析的后缀名
-
-
.htaccess类型绕过
-
没有限制.htaccess文件的上传,所以我们依然可以使用
-
.htaccess的内容,可用记事本编辑
- <FilesMatch “”>
SetHandler application/x-httpd-php
- 意思是可以执行任意脚本文件
- <FilesMatch “”>
-
上传后再上传木马文件123.jpg(原为123.php)
-
-
-
后缀大小写绕过
- 但是
$file_ext = strtolower($file_ext);
//转换为小写 这一句没有了,我们就可以使用文件名后缀大小写混合绕过 - 把1.php改为1.phP…来上传
- 但是
-
点绕过
-
上传文件名后加上点+空格+点,改为1.php. .
-
文件名后加点和空格,改成1.php. #点后面有空格
-
这个需要用burpsuite抓包修改,上传后保存在Windows系统上的文件名最后的一个.和空格会被去掉,实际上保存的文件名就是1.php
-
-
另外一种方法就是利用PHP 和 Windows环境的叠加特性,以下符号在正则匹配时的相等性:
- 利用PHP 和 Windows环境的叠加特性,以下符号在正则匹配时的相等性:
-
-
-
双引号" = 点号.
大于符号> = 问号?
小于符号< = 星号*
先上传一个名为4.php:.jpg
的文件,上传成功后会生成4.php的空文件,大小为0KB.
-
然后将文件名改为
4.<或4.<<<或4.>>>或4.>><
后再次上传,重写4.php文件内容,Webshell代码就会写入原来的4.php空文件中。
--
空格绕过
-
文件名最后增加空格和点,写成1.php .
-
这个需要用burpsuite抓包修改,上传后保存在Windows系统上的文件名最后的一个.会被去掉,实际上保存的文件名就是1.php
-
-
-
::$DATA数据流绕过
-
分析代码,少了
$file_ext = str_ireplace(‘::$DATA‘, ‘‘, $file_ext);//去除字符串::$DATA
这一句,我们可以采用Windows文件流特性绕过-
文件名改成1.php::$DATA , 上传成功后保存的文件名其实是1.php
-
-
-
解析漏洞绕过
-
双后缀名绕过
-
,由于
$file_name = str_ireplace($deny_ext,"", $file_name);
只对文件后缀名进行一次过滤-
双写文件名绕过,文件名改成
1.pphphp
-
-
-
-
白名单
-
(MIME类型绕过)
-
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。
-
每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。
-
常见的MIME类型(通用型)
- 超文本标记语言文本 .html text/html
- xml文档 .xml text/xml
- XHTML文档 .xhtml application/xhtml+xml
- 普通文本 .txt text/plain
- RTF文本 .rtf application/rtf
- PDF文档 .pdf application/pdf
- Microsoft Word文件 .word application/msword
- PNG图像 .png image/png
- GIF图形 .gif image/gif
- JPEG图形 .jpeg,.jpg image/jpeg
- au声音文件 .au audio/basic
- MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
- RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
- MPEG文件 .mpg,.mpeg video/mpeg
- AVI文件 .avi video/x-msvideo
- GZIP文件 .gz application/x-gzip
- TAR文件 .tar application/x-tar
- 任意的二进制数据 application/octet-stream
-
-
-
%00截断
-
以时间戳的方式对上传文件进行命名,使用上传路径名%00截断绕过,不过这需要对文件有足够的权限,比如说创建文件夹
-
上传的文件名写成1.jpg, save_path改成…/upload/1.php%00 (1.php%00.jpg经过url转码后会变为1.php\000.jpg),最后保存下来的文件就是1.php
-
修复情况: php版本要小于5.3.4,5.3.4及以上已经修复该问题;magic_quotes_gpc需要为OFF状态,on状态无法绕过
-
-
-
0X00截断
-
上传路径0x00绕过
-
利用Burpsuite的Hex功能将save_path改成…/upload/1.php【二进制00】形式
-
1.php后面任意增加字符比如空格,a,b,c 等(需要知道其16进制ascii值,以方便定位修改),再在burpsuite十六进制中修改为00,
-
-
-
0x0a截断
-
-
检查内容
-
文件头检查
-
绕过文件头检查,添加GIF图片的文件头GIF89a,绕过GIF图片检查。
- 或者使用命令copy 1.jpg /b + shell.php /a webshell.jpg,将php一句话追加到jpg图片末尾,代码不全的话,人工补充完整。形成一个包含Webshell代码的新jpg图片,然后直接上传即可。但是我们没有办法拿到shell,因为我们上传的图片马无法被解析成php形式,通常图片马配合%00或者0x00截断上传,或者配合解析漏洞
-
-
getimagesize() 函数用于获取图像尺寸
- 详情参考:https://blog.csdn.net/sanbingyutuoniao123/article/details/52166617
-
image_type_to_extension() 函数用于获取图片后缀
-
exif_imagetype() 此函数是php内置函数,用来获取图片类型
-
二次渲染
-
绕过imagecreatefromjpeg函数渲染
- 通过上传大量带马的图片,找到可以通过二次渲染验证的图片,然后利用木马控制
-
图像二次渲染介绍
- https://xz.aliyun.com/t/2657
- https://blog.csdn.net/hitwangpeng/article/details/48661433
- https://blog.csdn.net/hitwangpeng/article/details/46548849
-
-
-
其他条件
-
重命名竞争
-
利用上传重命名竞争+Apache解析漏洞,成功绕过
-
上传名字为18.php.7Z的文件,快速重复提交该数据包,会提示文件已经被上传,但没有被重命名。
- 快速提交上面的数据包,可以让文件名字不被重命名上传成功
-
然后利用Apache的解析漏洞,即可获得shell
- 从右向左解析,遇到不能解析的右侧后缀被舍弃,按照左侧后缀解析
-
-
时间竞争
-
通过burpsuite抓包,快速上传快速访问
- 使用两个发包器,一个包是上传我们tj.php的包,一个是访问我们上传tj.php后的地址
-
利用条件竞争删除文件时间差绕过。使用命令pip install hackhttp安装hackhttp模块,运行下面的Python代码即可。如果还是删除太快,可以适当调整线程并发数。
-
在脚本运行的时候,访问Webshell
-
代码示例
-
-
- <?php
$myfile = fopen("qing.php", "w");
$txt = "<?php phpinfo();?>";
fwrite($myfile, $txt);
fclose($myfile);
?>
- 上传的文件如果被利用时间竞争成功运行,
则可以在服务器上创建新的文件qing.php
内容为<?php phpinfo();?>
可以换成一句话木马,进而控制后台
二次上传
来自CTF考题
- 通过burpsuite抓包,修改上传内容,增加一条上传信息,骗过服务器,达到上传脚本的目的