先放一张图在这里
在放一张图
再放一个链接:https://www.freebuf.com/articles/web/265245.html
实践操作过 √
客户端
1. js检查 √
- 原理:通过javascript来校验上传文件的后缀是否合法,可以采用白名单,也可以采用黑名单的方式。
- 判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。
- 客户端的校验绕过:直接修改js代码或者使用抓包的方法修改请求内容绕过,可以先上传一个gif木马,通过抓包修改为jsp/php/asp,只用这种方法来检测是肯定可以绕过的。
服务端
检查后缀
黑名单
1. 上传特殊可解析后缀 √
黑名单规则不严谨,在某些特定的环境中,某些特殊的后缀名仍然会被当做php文件解析。Php|php2|php3|php4|php5|php6|php7|pht|phtm|phtml
比如,黑名单禁止上传.asp|.aspx|.php|.jsp后缀文件。
但是Apache的httpd.conf配置文件中,有这样一行内容:AddType application/x-httpd-php .php .php3 .phtml
这里上传.php、.php3、.phtml后缀的文件都可以当做php文件来执行
2. 上传.htaccess
- 原理:在Apache里,.htaccess是一个配置文件。它可以用来控制所在目录的访问权限以及解析设置。可以通过修改该文件的配置项,将该目录下的所有文件作为php文件来解析。.htaccess可以写入apache配置信息,改变当前目录以及子目录的apache配置信息。
- 应用场景:黑名单没有禁止.htaccess文件上传。
- 绕过方法:首先上传一个.htaccess文件,.htaccess文件内容如下。如果Apache允许.htaccess文件生效,并且.htaccess文件没有被重命名。那么就可以改变当前目录以及子目录的Apache配置信息,将其他后缀的文件作为PHP文件解析。
服务端允许.htaccess文件生效,需要在httpd.conf中,修改两处配置项:
- Apache加载rewrite模块
LoadModule rewrite_module modules/mod_rewrite.so - AllowOverride All(默认为None)
.htaccess文件中有两种写法
1 | <FilesMatch "xxx.png"> |
xxx.png即可作为php脚本解析
1 | AddType application/x-httpd-php .gif |
即 .gif为后缀额度文件都当做php解析
3. 后缀大小写绕过
应用场景:没有将文件后缀统一转换为大写或者是小写,而黑名单不严谨。
绕过方式:大小写绕过
比如:禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.pHp|.pHp5|.pHp4|.pHp3|.pHp2|pHp1|.Html|.Htm|.pHtml|.jsp|.jspa|.jspx|.jsw|.jsv|.jspf|.jtml|.jSp|.jSpx|.jSpa|.jSw|.jSv|.jSpf|.jHtml|.asp|.aspx|.asa|.asax|.ascx|.ashx|.asmx|.cer|.aSp|.aSpx|.aSa|.aSax|.aScx|.aShx|.aSmx|.cEr|.sWf|.swf|.htaccess
后缀文件,但是没有使用strtolower()
函数
4. 点绕过
- 应用场景:Windows平台,服务端没有使用deldot()删除文件名末尾的点。
- 利用方式:上传名为assert.php.的文件。在Windows服务器中,后缀名之后的点,在保存时,会被自动忽略
5. 空格过
应用场景:服务器为Windows平台,在对用户上传的文件名进行处理时,没有使用trim()函数去除字符串收尾处的空白字符。
利用方式:由于在Windows中文件后缀名末尾有空格会自动去掉,但是比较时,如果没有用trim()函数去除字符串收尾处的空白字符,那就可以绕过黑名单
例如:
"shell.php "
Windows会自动去掉末尾的空格变成"shell.php"
6. ::$DATA绕过 √
- 应用场景:Windows平台,没有使用str_ireplace()将::$DATA替换为空,导致可以利用NTFS文件流特性。
- 利用方式:假设xxx.php的内容为
上传的文件名 | 服务器表面现象 | 生成的文件内容 |
---|---|---|
xxx.php:a.jpg | 生成xxx.php | 空 |
xxx.php::$DATA | 生成xxx.php | |
xxx.php::$INDEX_ALLOCATION | 生成xxx.php文件夹 | |
xxx.php::$DATA.jpg | 生成0.jpg | |
xxx.php::$DATA\aaa.jpg | 生成aaa.jpg | |
可以根据情况来使用,一般就是直接::$data了 |
7. 配合解析漏洞
Apache HTTPD 换行解析漏洞(CVE-2017-15715)
Apache HTTPD是一款HTTP服务器,在它的2.4.0~2.4.29版本中存在一个解析漏洞,在解析PHP时,
1.php\x0A
将被按照PHP后缀进行解析,导致绕过一些服务器的安全策略。Apache HTTPD 多后缀解析漏洞
Nginx 解析漏洞
IIS7.5解析漏洞
IIS6解析漏洞
8. 双后缀名绕过
应用场景:黑名单、使用str_ireplace()将匹配到的黑名单中的内容替换为空。
利用方式:因为仅将黑名单中的内容一次替换为空,可以重写绕过。
xxx.phphpp,这样子去掉中间这个php后,就变成了 xxx.php
白名单
1. MIME过 √
MIME类型是描述消息内容类型的因特网标准。
HTTP头部的Content-Type字段的内容就是MIME类型。
只需要将MIME类型修改为白名单中允许的类型即可。
比如,图片上传点,允许上传gif、jpeg、png。用Burp抓包,将HTTP头部的Content-Type字段内容
1 | Content-Type: image/gif |
2. %00截断
%00是chr(0),空字符。
程序会把%00当做结束符,后面的数据直接忽略掉。
在文件上传中,利用%00截断,在文件扩展名验证时,是取文件的扩展名来验证,但是最后文件保存在本地时,%00或截断文件名,只保存%00之前的内容。
- 应用场景:白名单、上传路径可控、php.ini中的
magic_quotes_gpc
为off - 利用方式:
如果上传文件的路径为:用户可控的上传路径/随机数.白名单中的后缀
正常情况下,服务器拼接得到的上传路径为:而用户在可控的上传路径中,使用1
$img_path = ../upload/5920201223231032.gif;
%00
截断后,拼接得到的上传路径为:对后缀进行白名单检测,为gif。但是保存在服务器上的文件,却是1
$img_path = ../upload/xxx.php%00/5920201223231032.gif
xxx.php
,因为%00之后的内容被截断了。
3. 0x00截断
- 应用场景:白名单、上传路径可控、php.ini中的
magic_quotes_gpc
为offphp、版本<5.3.4 - 利用方式:如果上传文件的路径为:用户可控的上传路径/随机数.白名单中的后缀
正常情况下,服务器拼接得到的上传图像地址为$img_path =../upload/5920201223231032.gif
但是,用户如果在可控上传路径中写入一个php后缀,并且php后缀后面有一个0x00字符
服务器拼接得到的上传图像地址会变为$img_path =../upload/xxx.php[0x00]/5920201223231032.gif
对后缀进行白名单检测,为gif。但是保存在服务器上的文件,却是xxx.php,因为0x00之后的内容被截断了。
4. 0x0a截断
同3 0x00截断
检查内容
1. 文件头检查
上传具有正常文件头的图片马即可。
1 | gif的文件头为 GIF89a |
此时如果不存在上述的漏洞,只能上传图片格式的后缀,还需使用文件包含漏洞运行图片马中的恶意代码
2. 突破getimagesize()
getimagesize()函数会返回一个数组,其中下标2是图像的类型。1=GIF,2=JPG, 3=PNG。这里上传一个正常图像后缀的图片马,使用文件包含漏洞运行图片马中的恶意代码即可。
3. 突破exif_imagetype()
exif_imagetype()— 判断一个图像的类型。检查图像的第一个字节。可能返回的常量有IMAGETYPE_GIF=1
IMAGETYPE_JPEG=2
MAGETYPE_PNG=3
文件头不正确返回false
上传具有正常文件头的图片马即可。
1 | gif的文件头为 GIF89a |
然后使用文件包含漏洞运行图片马中的恶意代码。
4. 二次渲染
其它
条件竞争
条件竞争漏洞(Race condition)官方概念是“发生在多个线程同时访问同一个共享代码、变量、文件等没有进行锁操作或者同步操作的场景中。
upload-labs中的Pass-17是一个典型的条件竞争上传
代码执行逻辑:先移动,后检测,不符合再删除,符合则改名字。
因此我们可以让burp一直发包,让php程序一直处于移动php文件到upload目录这个阶段
我们同时使用多线程并发访问上传的文件,总会有一次在上传文件到删除文件这个时间段访问到上传的php文件,一旦我们成功访问到上传的php文件,那么它就会向服务器写一个shell。
顺带提一嘴防御
- 服务端文件扩展名使用白名单+文件重命名
- 对文件内容进行检测
- 对中间件进行安全配置