很多应用都维护着一系列面向授权用户、通过 HTML 界面展示的日志,因而成为了攻击者的首要目标,这些攻击者试图伪装其他攻击、误导日志读者,甚至对阅读和分析日志监测应用的用户安装后续攻击程序。
日志的脆弱性取决于对日志编写过程的控制,以及是否确保对日志条目进行任何监控或分析时,日志数据被看作非置信数据源。
简单的日志系统可能使用file_put_contents()函数向文件中写入文本行。比如,程序员可能采用以下格式的字符串来记录登录失败的情形:
sprintf("Failed login attempt by %s", $username);
那么万一攻击者使用诸如“AdminnSuccessful login by Adminn”形式的用户名呢?
如果把来自非置信输入的该字符串插入日志中,攻击者就能顺利将其失败登录伪装为管理员用户无辜的失败登录。如再成功添加一次重试,数据的可信度甚至会更高。
当然,重点在于攻击者可以添加各种日志条目,还可注入XSS矢量,甚至还能注入字符,扰乱日志条目在控制台的显示。
注入的目标也可能为日志格式解释程序。如果分析器工具使用正则表达式解析日志条目,将其分解成数据字段,那么,注入的字符串可以通过精心构造以确保正则表达式与注入的多余字段相匹配,而非正确字段。例如,以下条目便可能造成问题:
$username = "iamnothacker! at Mon Jan 01 00:00:00 +1000 2009"; sprintf("Failed login attempt by $s at $s", $username, )
更过分的使用日志注入的攻击者可能试图建立目录遍历攻击,使日志出现在浏览器中。正常情况下,向日志消息中注入PHP代码并在浏览器中打开日志文件便可成功进行代码注入,攻击者可用精心设计并随意执行这类代码注入。这一点无需多讲。如果攻击者能在服务器上执行PHP,那么问题就大了,此时你的系统最好有足够的深度防御来将损害降至最低。
最简单的日志注入防御方法是利用受认可的字符白名单对所有出站日志消息进行清理。比如,我们可以将所有日志限制为字母数字字符和空格。不属于该字符列表的消息可能被认定为有害消息,进而出现有关潜在本地包含漏洞(LFI)的日志消息,以便告知你攻击者可能进行的尝试。这种方法很简单,适用于简单文本日志,此类日志消息无法避免非置信输入的出现。
第二种防御则是将非置信输入部分编码为类似base64的编码,其中保存着数量有限的认可的字符描述,同时还可在文本中存储大量信息。
路径遍历(也称目录遍历)攻击通过读取或写入 web 应用的文件而试图影响后端操作,其方法为注入能控制后端操作所采用文件路径的参数。照此,通过推进信息披露以及本地/远程文件注入,这类攻击可以顺利取得成功。
我们将分别对这类后续攻击进行阐述,但路径遍历是使这些攻击达成的根本漏洞之一。尽管以下功能特定于操纵文件路径这一概念,但值得一提的是,许多PHP函数都不仅仅接受单纯的文件路径。譬如,PHP中的include()
或file()
等函数能接受URI。这似乎很违反常理,但这使得以下两种采用绝对文件路径(即不依靠相关文件路径的自动加载)的函数调用方法带来相同的效果。
include(‘/var/www/vendor/library/Class.php’); include(‘file:///var/www/vendor/library/Class.php‘);
关键在于,在相关路径处理的同时(php.ini和可用自动加载器的 include_path
设定 ),类似的PHP函数在各种形式的参数操纵下显得尤其脆弱,其中包括文件URI 方案替换——一旦文件路径初始处注入了非置信数据,攻击者便可注入HTTP或 FTP URI。后面我们将在远程文件包含攻击中对这一点进行进一步阐述,现在继续探讨文件系统路径遍历的问题。
路径遍历缺陷的各种情况有一个共同特点,即文件路径因受操纵而指向不同的文件。这一点通常通过向参数注入一系列 ../
(点-点-斜线)序列来实现,上述参数被整个添加或插入到 include()
、require()
、file_get_contents()
等函数,甚至在有的人看来不那么可疑的函数中,比如DOMDocument::load()
。
点-点-斜线序列允许攻击者使系统导航或回溯至父目录。因此像/var/www/public/../vendor
这样的路径实际上会指向/var/www/public/vendor
。/public
后的点-点-斜线序列会回溯到该目录的父目录,也就是/var/www
。从该简单示例可以看出,利用这一方法,攻击者便可读取通过网站服务器可访问的/public
目录以外的文件。
当然,路径遍历不仅仅用于回溯。攻击者也可注入新的路径元素,从而访问无法通过浏览器访问的子目录,无法访问的原因可能为子目录或其父目录之一中的.htaccess
中的deny from all
指令。PHP的文件系统操作不考虑Apache或其他网站服务商是如何配置并控制非公共文件和目录的入口的。
原文地址:http://phpsecurity.readthedocs.org/en/latest/Injection-Attacks.html#log-injection-also-log-file-injection
本文系 OneAPM 工程师编译整理。OneAPM 是应用性能管理领域的新兴领军企业,能帮助企业用户和开发者轻松实现:缓慢的程序代码和 SQL 语句的实时抓取。想阅读更多技术文章,请访问 OneAPM 官方博客。
本文转自 OneAPM 官方博客