文件上传
全文以upload-lab为例展开
关于上传的具体步骤
首先在本地前端可能会经过一次js代码的检验,上传到服务器之后会先存在一个后缀为.tmp
的临时文件,之后服务器会对上传的文件进行判断,最终使用move_uploaded_file
函数将文件移动至标准路径,要注意使用该函数时路径由后台代码控制,最终储存的文件名不一定等于原文件名
客户端的检验
使用本地js代码进行判断,是非常弱的检验手段。
不仅可以在本地看见源码,还可以手动把源码直接修改掉,也可通过抓包修改的形式避开判断。
客户端的捣乱
有的时候上传的那个按钮属性会被设置为disable,查下代码手动改一改才能开始上传
服务器端的检验
在服务器端进行检验,该过程发生在数据包发送以后
黑名单
禁止带有特定后缀名的文件上传,如.php,.asp等等
这里需要注意的是我们如果要直接访问我们上传的后门,其后缀必须得是php及其衍生格式才能被解析。
upload-labs中的后缀处理步骤为:
- 去除文件名两端的空格
- 去除后缀最后的.
- 以最后一个点为标志位截取文件后缀
- 转为小写
- 去除后缀最后的::$DATA
- 修剪两端空格
- 将修剪后的文件名与黑名单进行对比
常见的PHP衍生格式
以upload-labs的第三关为例,这里过滤了.asp .aspx .php .jsp文件,我们可以使用PHP的衍生格式文件进行上传绕过。
- .php2
- .php3
- .php4
- .php5
- .php7
- .phtml
大小写后缀绕过
有的题目检测的不是很上心,大小写混搭即可绕过
增加空格绕过
有的检测是通过in_array函数实现的,并且是检测我们的后缀是否处于禁用列表之中,这时如果没有去除文件名后缀的空格,就可以完成绕过,如.php
注:upload-labs的第六关的显示源码和真正的源码不符,显示的源码中仍有trim函数,坑死我了
Windows特性绕过
只有在服务器是Windows系统下才有用的操作
加.进行绕过
发生在没有对文件删除.的检测中,由于Windows的特性,会自动去除文件后缀名中最后的点,这样我们的加点后缀在检测中就是以.php.
的形式进行检测,但上传之后.会被去除又变回.php
加::$DATA绕过检测
php在window的时候如果文件名+”::$DATA”会把::$DATA之后的数据当成文件流处理,不会检测后缀名.且保持”::$DATA”之前的文件名,完成绕过
使用原文件名作为新文件名
以upload-labs第九题为例
一般来说服务器会将检测后的文件名作为上传文件的文件名进行保存,但是某些情况下会将原文件名进行保存,这时我们就可以利用这点构造进行绕过
例:webshell.php. .
,通过Windows服务器特性即可绕过检测并可被解析,但如果储存的是处理过的文件名,此处被截取到的文件后缀将为空。
被禁用后缀名替换为空
同样的套路常见于SQL注入,双写绕过即可
例:.phphpp
禁止<?
可以使用这样的标签来进行定义,等价于
该标准已在php7中禁用
白名单
只允许上传某些文件,如.jpg,.png等等,这时如何使我们上传的后门被解析是一个重点问题
.htaccess重定向
是Apache的配置文件,.htaccess文件规定了当前目录的应用规则,不同的目录下可以拥有不同的.htaccess文件规定不同的规则
这里用它将所有文件都解析为php文件就可以用上传后缀为.jpg的shell了
将所有文件解析为php的代码如下SetHandler application/x-httpd-php
可后接文件后缀名使特定文件被解析为php
上传该内容的.htaccess文件即可以上传.jpg后缀的文件作为后门了
启用.htaccess文件需要在Apache配置中修改允许重写
.htaccess构成的后门:http://www.dengb.com/aqgjrj/961456.html
几个常见语句
- 设置php变量
php_value <key> <val>
例如php_value auto_append_file xxx.php
该语句等价于在当前页面底端增加一句require(xxx.php) - 更改解析方式
SetHandler application/x-httpd-php .ext
,AddType语句和SetHandler一个效果,该语句规定将后缀为.ext的文件解析为php文件 php_flag engine off
,该语句命令当前目录下的所有文件都不可作为PHP脚本解析,当服务器存在该设置时可以考虑控制文件上传路径,使我们的shell放置在无.htaccess文件的地方php_flag display_errors on
字面意思,显示错误php_value zend.script_encoding “UTF-7″
修改编码方式,要是我就用base64了
.user.ini包含后门
.user.ini文件中也有和htaccess一样的auto_append_file,并且相较于.htaccess,.user.ini存在于各种服务器之中,使用文件包含时,被包含的任何文件都会被解析为php文件,所以我们可以通过上传.user.ini文件再上传一个图片马,进行访问就可以进入后门了(当然需要一个正常的可访问php文件才能)
贴一个文章:https://wooyun.js.org/drops/user.ini%E6%96%87%E4%BB%B6%E6%9E%84%E6%88%90%E7%9A%84PHP%E5%90%8E%E9%97%A8.html
00截断
适用情形:截断条件:php版本小于5.3.4,php的magic_quotes_gpc为OFF状态
因为对PHP版本要求过老,基本没用
在上传的时候,当文件系统读到【0x00】时,会认为文件已经结束。利用00截断就是利用程序员在写程序时对文件的上传路径过滤不严格,产生0x00上传截断漏洞。
出现在上传路径可控的情况下,以get方式传递时可直接使用%00进行绕过,会自动进行url解码,以post方式执行时,需要在十六进制中对数据进行修改为00
图片马绕过
PHP存在一些判断文件类型的函数,通常就是看看文件头尾是不是符合图片的类型,这个时候我们可以把木马拼接在图片中,即可制造出一个图片马进行上传。
图片马是以.jpg形式上传的,使用就需要有文件包含,或是.htaccess,或者其他的解析漏洞。
图片马制作copy 1.jpg /b + shell.php /a shell.jpg
,感觉直接在010editor里面拼也差不多
该方法可以绕过getReailFileType
,getimagesize
,exif_imagetype
等函数检验
exif_imagetype()绕过
可以在文件开头增加GIF89a
来绕过#define width 20
#define height 10
如上两行是xbm格式图片的开头,在上传.htaccess或是php脚本文件时将这两行添加进去可绕过exif_imagetype,并在解析时被作为注释,不影响脚本正常解析
二次渲染绕过
图片进行二次渲染之后可能会剔除我们之前拼接在图片中的脚本,并且对于.jpg,.png和.gif图片而言,处理二次渲染的方式并不一致
- .gif文件:.gif图片在进行二次渲染时存在二进制文件完全不变的部分,将代码插入该部分即可。
- .png文件:很复杂,要分析数据块,将代码写入PLTE数据块并重新计算crc值修改,也可使用大佬的脚本
- .jpg文件:使用大佬脚本进行填充,但部分jpg文件不存在可填充空间,所以需要多拿几张图片进行尝试
一篇写的很好的文章:https://xz.aliyun.com/t/2657 脚本也贴在里面了
条件竞争
发生在逻辑漏洞中,有的系统先将上传的文件进行保存再进行安全性检验,对于不通过的再予以删除,如果我们高频率对上传的文件进行访问,就有可能在其被删除之前访问到它,以此完成条件竞争
重复发包我们可以使用bp的intruder模块,随便自己加一个参数发起进攻即可,同时在浏览器反复尝试对上传的文件进行访问即可(需要知道上传的文件储存路径,并且文件名不要有变化)
阻止文件改名
系统存在将上传的文件进行改名的操作,进行随机改名之后我们不知道被修改的文件名是什么,自然无法进行进一步的访问。如果也同条件竞争一样一直对服务器进行文件上传,就有机会访问到尚未未改名的文件(实测时发现最后竟然保留了一个未被改名的文件,不知道为什么)
检测文件属性
检测内容为文件的content-type,即文件属性。注意此处的content-type位于数据包中post的数据部分,不属于包的头部参数。
可以将文件名直接修改为.jpg
然后抓包修改后缀为.php
,或将.php
文件的content-type修改为图片的image/jpeg
即可绕过检测
本地包含的文件上传
存在include等函数时,会将包含的文件当做PHP代码执行,所以如果有该函数,我们以此方式对上传的.jpg后缀文件进行访问也可正确解析。
被限定后缀的本地包含
后台向文件包含位置增加一个.php后缀
这时可以使用php的phar伪协议,phar伪协议可以读取压缩包里的内容,我们可以将shell.php压缩为shell.zip,修改后缀为shell.jpg上传之后以phar伪协议进行读取,?file=phar://upload/shell.jpg/shell
,这里最后一个shell会因为被添加一个.php被读取出来
phar反序列化
PHP新爆出的重大安全隐患,许多文件相关操作函数不经意间存在对phar文件的反序列化操作,使得我们精心设计的恶意数据将会得以导入
这种类型的漏洞需要源码进行代码审计,对__call,__construct等魔法方法着重关注,并且注意齐是否存在对文件操作函数的调用
zsx巨佬的博客https://blog.zsxsoft.com/post/38
能够触发phar反序列化的函数
fileatime / filectime / filemtime
stat / fileinode / fileowner / filegroup / fileperms
file / file_get_contents / readfile / fopen`
file_exists / is_dir / is_executable / is_file / is_link / is_readable / is_writeable / is_writable
parse_ini_file
unlink
copy
这么多的函数都可以在传入参数为phar://协议时对包含的数据进行反序列化,再通过一系列魔法方法形成pop链,完成入侵
在构造数据时也要注意自己的数据是什么时候被构造或析构,数据的显示应该通过什么方法进行等等。