文件上传漏洞概述
⽂件上传是Web 应⽤必备功能之⼀。 如果服务器配置不当或者没有进⾏⾜够的过滤,Web ⽤户就可以上传任意⽂件,包括恶意脚本⽂件, exe 程序等等,这就造成了⽂件上传漏洞。
漏洞的成因
服务器配置不当 。
Web 应⽤开放了⽂件上传功能,没有对上传的⽂件做⾜够的限制和过滤。
在程序开发部署时,没有考虑到系统的特性或组件的漏洞,从⽽导致限制被绕过。
漏洞危害
上传漏洞最直接的威胁就是上传任意⽂件,包括恶意脚本、程序等。 直接上传后⻔⽂件,导致⽹站沦陷。 通过恶意⽂件,利⽤其他漏洞拿到管理员权限(提权),导致服务器沦陷。 通过⽂件上传漏洞获得的⽹站后⻔,叫 WebShell 。
文件上传漏洞利用的条件
Web 服务器开启⽂件上传功能,Web ⽤户可以使⽤该功能。
Web ⽤户(www-data|apache)对⽬标⽬录具有可写权限,甚⾄具有执⾏权限。 ⼀般情况下,Web ⽬录都有执⾏权限。
“完美利⽤”意味着⽂件可以执⾏,也就是说代码可以被服务器解析。
服务器开启了PUT ⽅法。
GetShell的一些影响因素
以 upload-labs 来探讨相关问题。
其他可执⾏的⽂件后缀名
php
php|php5|php4|php3|php2|php1
heml
html|htm|phtml|pht
asp
asp|aspx|asa|asax|ascx|ashx|asmx|.cer
jsp
jsp|jspa|jspx|jsw|jsv|jspf|.jtml
.htaccess 攻击
.htaccess 是 Apache 服务器分布式配置⽂件。 如果某⼀个⽬录下存在该⽂件, .htaccess ⽂件中的配置会覆盖掉 Apache 全局配置⽂件 httpd.conf 的配置,作⽤域是当前⽬录及其⼦⽬录有效。 此处想象空间⾮常⼤。
将 .jpg ⽂件当做 PHP ⽂件解析
AddType application/x-httpd-php .jpg
系统特性
忽略大小写
1. 脚本程序对⼤⼩写敏感,PHP 和php 是完全不同的两个⽂件后缀名。
2. Windows 系统对⼤⼩写不敏感。
忽略文件名末尾的点
# windows
[info.php.] -> [info.php]
忽略文件名末尾的空格
# windows
[info.php ] -> [info.php]
数据流 ::$DATA
# windows
# 数据流会被系统忽略
[info.php::$DATA] -> [info.php]
绕过⼀次过滤
[info.php..]
[info.php. .]
[info.php. ]
[info.php.]
[info.pphphp]
[info.pphphp]
[info.php]
PHP 特性:00 截断
$img_path = $_GET['save_path']."/".rand(10,
99).date("YmdHis").".".$file_ext;
//../upload/5320200407224828.png
//../upload1/5320200407224828.png
//?save_path=../upload/11.php
//../upload/11.php%00/5320200407224828.png
move_uploaded_file($temp_file,$img_path);
//../upload/11.php
//%00 是NULL 字符的URL 编码
Null 字符在C 语⾔中代表字符串的“结束”.
演示案例:upload-lab关卡分析
Pass-2(MIME类型)
将文件后缀名改为image/png格式
Pass-3(特殊解析后缀)
上传PHP的其他格式,
Pass-4( .htaccess解析)
查看源码可以上传JPG文件
文件内容一句话木马
上传成功
将.jpg文件当作PHP文件解析
AddType application/x-httpd-php .jpg
验证
Pass-5(大小写绕过)
源码没有大小写转换
Pass-6(空格绕过)
查看源码,发现少了个收尾去空
上传抓包,将后缀PHp改为php然后添加一个空格,即 "php "
Pass-7(点绕过)
分析代码发现少了删除文件名末位的点的验证
Pass-8(::$DATA绕过)
利用Windows特性
在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名
例如:"phpinfo.php::$DATA"Windows会自动去掉末尾的::$DATA变成"phpinfo.php"
Pass-9(点空格点绕过)
代码将字符串里的php替换为空
一次过滤
a.php -> a.
a.pphphp -> a.php 将中间的php过滤掉,还有个php
循环过滤 递归过滤
a.pphphp -> a. 只要有php出现就会一直过滤掉
Pass-10(双后缀名绕过)
Pass-11(%00截断——GET)
#将php版本选择5.2.17
#将5.2.17版本的php.ini文件中Magic_Quotes_Gpc = On改为
Magic_Quotes_Gpc = Off
Pass-12(%00截断——POST)
查看源码,提交方式位POST方式
post中内容不会给你直接url编码,所以我们需要改一下hex,需要在二进制中进行修改,因为post不会像get对%00进行自动解码。00截断版本只限于5.3之前。