文件上传是现代互联网常见的功能,允许用户上传图片、视频、及其他类型文件,向用户提供的功能越多,Web受攻击的风险就越大。
- 上传文件时,如果未对上传的文件进行严格的验证和过滤,就容易造成文件上传漏洞,上传脚本文件(包括asp、aspx、php、jsp等)
- 恶意上传行为可能导致网站甚至整个服务器被控制。恶意的脚本文件又被称为WebShell,WebShell具有强大的功能,如查看服务器目录、服务器中文件、执行系统命令等。
文件上传漏洞的成因(复杂),一方面,Web 应用开放了文件上传功能,并且对上传的文件没有进行足够的限制;另一方面,程序开发部署时候,没有考虑到系统特性和过滤不严格;再者就是,攻击者通过Web服务器解析漏洞绕过限制,导致可以上传任意文件。
- 文件上传漏洞最直接的威胁就是上传任意文件,包括恶意脚本、可执行程序等。
- 如果Web 服务器所保存上传文件的可写目录具有执行权限,那么就可以直接上传后门文件,导致网站沦陷。
- 如果攻击者通过其他漏洞进行提权操纵,拿到系统管理权限,那么直接导致服务器沦陷。
- 同服务器下的其他网站无一幸免,均会被攻击者控制。
- Web 服务器要开启文件上传功能,并且上传api(接口)对外“开放”(Web用户可以访问);
- Web 用户对目标目录具有可写权限,甚至具有执行权限,一般情况下,Web 目录都有执行权限。
- 要想完美利用文件上传漏洞,就是上传的文件可以执行,也就是Web 容器可以解析我们上传的脚本,无论脚本以什么样的形式存在。
- 小马通常指一句话木马,因为其代码量较小,就是一句简单的代码。
- 一句话木马短小精悍,功能强大,是为了绕过waf的检测,虽然出现了无数的变形,但本质是不变的:木马的函数执行了我们发送的命令。
- 通过GET、POST、COOKIE三种方式提交数据
- 用$_GET[' ']、$_POST[' ']、$_COOKIE[' ']接收传递的数据,并把接收的数据传递给一句话木马中执行命令的函数,进而执行命令。
PHP:
ASP:<%eval request("cmd")%>
ASPX:<%@ Page Language="Jscript"%>
<%eval(Request.Item["cmd"],"unsafe";)%>
经典的一句话木马大多都只有两个部分,一个是可以执行代码的函数部分,个是接收数据的部分。
例如
eval就是执行命令的函数,$_POST[ ‘cmd’]就是接收的数据。eval函数把接收的数据当作PHP代码来执行。这样我们就能够让插入了一句话木马的网站执行我们传递过去的任意PHP语句。
之所以叫大马,是因为与小马(一句话木马)区分开,并且代码比较大,但是功能比较丰富。同样,大马有很多种脚本格式,其功能基本相同。每个团队都有自己的定制大马。
- 客户端(Client):或称为用户端(前端),与服务器相对应。由于客户端对于文件上传漏洞的防御是通过JS代码实现的,所以客户端检测与绕过也称为JS检测与绕过。
- 调用JS的selectFlle()函数,先将文件名转换为小写,然后通过substr获取文件名最后一个点号后面的后缀(包括点号)进行判断。
由于后端PHP代码没有对文件做任何检测,所以只要绕过前端JS的校验就可以上传WebShell。
对于文件上传,只从Web 前端进行检测显然防护不足,那么服务器端就特别重要了。一般服务端检测包括以下几个方面:
- 后缀名检测与绕过
- MIME类型检测与绕过
- 文件内容检测与绕过
- 00截断检测与绕过
- 条件竞争检测与绕过
检测原理
通过函数pathinfo()获取文件后缀,将后缀转为小写后判断是不是php。
有些中间件允许解析其他文件后缀名,如asa、cer之类的或在httpd.conf配置文件中,配置如下代码,则能解析php、php3、phtml文件。所以上传一个后缀名为php3、phtml的文件即可。
一些特殊的文件名命名方式在Windows下是不被允许的,利用BurpSuite抓包修改后缀名,绕过验证后上传文件,windows会自动去掉后面添加的,但要注意Unix/Linux系统没有这个特性。比如:
- 末尾的点(.) 【1.php.】
- 空格( ) 【1.php 】
- ::$DATA 【1.php::$DATA】
白名单绕过需要配合文件包含漏洞或解析漏洞
比如:当文件名[info.php.png] 中包含关键字[.php],并且.htaccess 文件内容如下,info.php.png 中的代码会被执行。
setHandler application/x-httpd-php
上传一个htaccess文件 可以让服务器将符合PHP语法规则的文件当作php解析
结合Apache文件解析机制,从右向左开始解析文件后缀,若后缀名不可识别则继续判断直到遇到可解析的后缀为止。
MIME(Multipurpose Internet Mail Extensions)是描述消息内容类型的因特网标准。MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。常见的MIME 类型如下:
文件扩展名 | Mime-Type |
---|---|
.js | application/x-javascript |
.html | text/html |
.jpg | image/jpeg |
.png | image/png |
application/pdf |
判断$_FILES["file"]["type"]是不是图片格式(image/gif、image/jpeg、image/pjpeg),不是则不允许上传。在HTTP 协议中,使用Content-Type 字段表示文件的MIME 类型。 $_FILES["file"]["type"]的值是从请求数据包中Content-Type中获取。
通过抓取数据请求包,上传php文件时,Content--Type值是applcation/octer-stream,上传jpg格式的文件时Content-Type值是imaag/jpeg。可修改文件类型进行绕过。
利用getimagesize()函数获取图片的宽高等信息,如果上传的不是图片,那么则获取不到信息。
文件相关信息检测
检测图像文件相关信息
在脚本文件开头补充图片对应头部值,或在图片后写入脚本代码
制作图片马
参数/b指定以二进制格式复制、合并文件,用于图像类/声音类文件
参数/a指定以ASCⅡ格式复制、合并文件,用于txt等文档类文件
图片马上传的漏洞无法解析,需要配合文件解析或者文件包含漏洞
截断漏洞出现的核心就是chr(0),这个字符不为空(NuⅡ),也不是空字符(" "),更不是空格。当程序在输出含有 chr(0)变量时,chr(0)后面的数据会被停止,换句话说,就是误把它当成结束符,后面的数据直接忽略,这就导致了漏洞产生。由于00代表结束符,PHP会把00后面的所有字符删除。
截断条件:PHP版本小于5.3.4、magic_quotes_gpc 为OFF状态
GET方式
POST方式
些网站文件检测逻辑是先允许上传任意文件,然后检查文件内容是否包含可执行脚本,如果包含则删除。这里使用sleep()函数来模拟判断是否含有脚本所需要的时间。
利用成功上传到删除文件的时间差,上传一个.php文件,在未删除之前立即访问,则会自动生成一个新php文件,新文件不会被删除。
');
?>