CasperKid 师傅以前在一篇 paper 里写到他对渗透测试本质的看法,大概意思是抽象来看,漏洞利用的本质就是
代码注入 + 代码解析/代码执行
像 SQL Inject、Remote Code Execution 之类的是让直接让代码、SQL 语句等直接注入一个可以直接执行的环境里,就不用考虑代码执行的部分。
如果我们能上传一个可被直接解析的 Webshell 的话也可以不用考虑代码执行了,但大多数程序的上传点都是做了检测的,不能直接可直接执行上传 Webshell ,这个时候我们就需要考虑怎么绕过了。
0x00 概述
文件上传是很多网站都有的功能,但不少网站的文件上传部分有一些逻辑漏洞,这导致攻击者可以通过这些未严格过滤的文件上传检测直接把Webshell 上传到服务器上。
首先我们要了解一些常见的检测方法,才能去研究如何绕过,常见的检测方法有如下几种
- javascript 文件扩展名检测
- javascript 文件幻数检测
- 服务端 MIME 检测
- 服务端文件扩展名检测
- 服务端文件幻数检测
- 文件加载检测
按检测代码执行的位置,我们可以大概的把检测分为客户端检测和服务端检测两种,接下来我们会按照这两大类来分析检测方法和绕过姿势。
P.S. 所谓绕过是指“绕过不严谨的文件类型检测机制直接上传可以被直接解析的文件”,这也正是本文的主题。
0x01 客户端检测
javascript 文件扩展名检测
这类检测一般只是初步过滤掉普通用户不小心上传的错误类型文件,并不能对攻击者造成什么影响,毕竟客户端的控制权在用户手中。
我们可以通过 BurpSuite Proxy 直接抓包改包,把文件名改为服务器可以解析的文件名。
javascript 文件幻数检测
文件幻数,也就是Magic number,作为文件格式的标志存在于文件的开头。
检测幻数的方法很简单,就是读文件然后检测前面的幻数部分~
绕过也是同样的简单,在文件开头加上相应的文件幻数即可。
0x02 服务端检测
服务端 MIME 检测
服务端检测文件类型的时候最常用的就是 MIME 检测。比如 PHP 只要简单的一行就能判断是否是允许的文件类型
if($_FILE["file"]["type"] != "image/jpeg"){
echo "Type Error!"
}
PHP 获取文件类型的方法是通过 HTTP Response 里面的 Content-type 头。
所以我们只需要修改 Content-type 就能绕过 MIME 检测了。
服务端文件扩展名检测
扩展名的检测可以分为两类,黑名单和白名单。
如果开发者使用黑名单做监测的话,就意味着要承受黑名单未定义扩展名的风险,攻击思路一般有如下几种
- 扩展名大小写
- 漏网之鱼
- 扩展名嵌套
- 在文件名后加个空格、
::$DATA
或.
(仅在服务器为 Windows 时有用,且攻击者是 windows 的话需要改包)
白名单本身是没问题的,较黑名单来说安全许多。一般来说如果遇到白名单就无法直接上传非法扩展名了,不过可以考虑用 00 截断试试
服务端文件幻数检测
同 javascript 幻数检测
文件加载检测
一般我们上传的图片会被渲染,而要是像我们使用以上的那些方法的话,Webshell 是无法正常加载出来的,这个时候我们就得用到图马了,在不破坏图片的情况下把Webshell 插进图片的空白区域。
但如果是二次渲染的话就 GG 了~
0x03 HTTP PUT
除了绕过各种检测外,我们还可以考虑直接绕过网站,从其他地方想办法
当服务器支持 PUT 方法时,我们也可以通过 PUT 来上传我们的文件,但由于在 HTTP 中像 PUT 这种方法是比较危险的,所以几乎在所有的服务器里都是默认关闭的,不过 IIS 在开启 WebDAV 之后就会支持 WebDAV 的所有方法了,其中包括 PUT 和 MOVE。
WebDAV(Web-based Distributed Authoring and Versioning)是一种基于 HTTP 1.1协议的通信协议。它扩展了HTTP 1.1,在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法。
只要权限允许,攻击者可以直接通过 PUT 方法上传Webshell ,由于不可以直接上传可执行文件,所以必须通过 MOVE 方法或者文件解析漏洞使Webshell 可执行。
0x04 防御方式
客户端只能初步过滤普通用户的错误输入,不能作为防御攻击者的措施。
在服务端检测中我们得尽量使用白名单检测,在条件允许的话尽量使用文件加载检测。
除了检测过程之外还有其他一些需要注意的几点
- 文件上传后改名,只要不知道文件的 URL 攻击者也就没办法了
- 不要给存放文件的目录可执行的权限
- 对服务器进行安全配置,保证远离文件解析漏洞
- 开发时注意不要造成文件包含漏洞
0x05 总结
早期的开发者在开发的过程中的确会考虑用户的错误输入,但是却可能会忽视掉来自攻击者的威胁。
比如这篇文章讲的文件上传,虽说客户端过滤可以过滤掉 99% 的用户,但攻击者从来都不是那 99% 。任何从客户端发来的东西都是不可靠的,客户端检测顶多只是过滤普通用户错误上传的方法,真正的防御手段还是在后面的服务端检测。
另外,Webshell 上传后还需要解析才能发挥作用,一些具体方法参见接下来两篇文章
Webshell 上传与解析 Part 2 —— 服务器文件解析问题
Webshell 上传与解析 Part 3 —— File Inclusion 的利用
0x06 参考
- Magic number (programming) - wiki
- Upload Attack Framework - CasperKid
- IIS WebDAV安全配置 - 瞌睡龙