一般情况下,用户通过包含函数将具有特定功能的函数或类包含到当前脚本中,是没有什么问题的。但是有时候,为了方便,需要动态的包含文件,这就会留下一些攻击漏洞。
通常情况下,LFI攻击威胁不大,因为本地服务器上的文件是比较确定的,攻击者想要上传带有攻击性代码的文件也不是件容易的事。RFI攻击才是我们需要防范的事。那么,RFI攻击是如何实现的呢?
首先,提供一个存在RFI漏洞的代码示例(index.php):
- <?php
- // 存在RFI漏洞的代码片段
- $file = $_GET['file'];
- include $file;
- ?>
目前看来,还没出现什么安全问题,因为还仅仅只是包含本地文件。如果是包含远程文件,问题就来了,因为攻击者是可以任意编码远程文件的。
需要说明的是,进行RFI攻击需要同时具备三个条件(被攻击机器):
- allow_url_fopen = On (默认开启)
- allow_url_include = On (默认关闭)
- 被包含的变量前没有目录的限制
第一步:设置php.ini文件,将“allow_url_fopen ”和“allow_url_include”都开启,重启Apache。
第二步:创建存在RFI漏洞的脚本文件,如上面的index.php。
第三步:在远程主机上创建一个带有攻击性代码的文本文件hack.txt(Just test),注意这个文件不能被服务器解析,如不能为PHP脚本文件。因为只是演示,文本文件被执行就能满足演示效果了。hack.txt文件内容如下:
- hahaha,You are hacked. <?php echo $_GET['a']; ?>
第四步:将攻击文件的URL带入include,进行攻击,如图所示:
可以看到,文本文件被执行。接着,我们使用其中的PHP代码,如图所示:
可以看到,文本文件中的PHP代码被成功执行,现在只是一个演示,但是已经能说明RFI攻击过程。如果攻击者在文件中放入了系统命令,后果将不堪设想。
上面提到,攻击文件不能是PHP文件,所以有些经验丰富的开发者会考虑将被包含文件的扩展名写死,如:
- <?php
- // 存在RFI漏洞的代码片段
- $file = $_GET['file'];
- include $file.'.php';
- ?>
这种方法确实能起到一定作用,但对那些有经验的攻击者来说,这不是问题。我们知道PHP引擎是有C来实现的,C中空字符就是字符串结束符,因此可以使用空字符将扩展名截断,实现RFI攻击。
理解了RFI攻击原理,防御也就简单了。在配置层面,保持PHP的默认设置,将“allow_url_include”关闭;在代码层面,如果一定要动态包含文件,最好明确规定包含哪些文件,进行白名单比对。同时,也可以在包含函数中加入目录限制。
没有评论:
发表评论