Fortify漏洞之 Log Forging(日志伪造)

  继续对Fortify的漏洞进行总结,本篇主要针对 Log Forging(日志伪造)的漏洞进行总结,如下:

1.1、产生原因:

在以下情况下会发生 Log Forging 的漏洞:

1. 数据从一个不可信赖的数据源进入应用程序。

2. 数据写入到应用程序或系统日志文件中。

 

  为了便于以后的审阅、统计数据收集或调试,应用程序通常使用日志文件来储存事件或事务的历史记录。根据应用程序自身的特性,审阅日志文件可在必要时手动执行,也可以自动执行,即利用工具自动挑选日志中的重要事件或带有某种倾向性的信息。

  如果攻击者可以向随后会被逐字记录到日志文件的应用程序提供数据,则可能会妨碍或误导日志文件的解读。最理想的情况是,攻击者可能通过向应用程序提供包括适当字符的输入,在日志文件中插入错误的条目。如果日志文件是自动处理的,那么攻击者就可以通过破坏文件格式或注入意外的字符,从而使文件无法使用。更阴险的攻击可能会导致日志文件中的统计信息发生偏差。通过伪造或其他方式,受到破坏的日志文件可用于掩护攻击者的跟踪轨迹,甚至还可以牵连第三方来执行恶意行为。最糟糕的情况是,攻击者可能向日志文件注入代码或者其他命令,利用日志处理实用程序中的漏洞。

 

例 1 下列 Web 应用程序代码会尝试从一个请求对象中读取整数值。如果数值未被解析为整数,输入就会被记录到日志中,附带一条提示相关情况的错误消息。

...

String val = request.getParameter("val");

try {

  int value = Integer.parseInt(val);

}catch (NumberFormatException nfe) {

  log.info("Failed to parse val = " + val);

}

...

 

如果用户为“val”提交字符串“twenty-one”,则日志中会记录以下条目:

INFO: Failed to parse val=twenty-one

然而,如果攻击者提交字符串 “twenty-one%0a%0aINFO:+User+logged+out%3dbadguy,则日志中会记录以下条目:

INFO: Failed to parse val=twenty-one

INFO: User logged out=badguy

显然,攻击者可以使用同样的机制插入任意日志条目。

 

1.2、修复方案:

  使用间接方法防止 Log Forging 攻击:创建一组与不同事件一一对应的合法日志条目,这些条目必须记录在日志中,并且仅记录该组条目。要捕获动态内容(如用户注销系统),请务必使用由服务器控制的数值,而非由用户提供的数据。这就确保了日志条目中绝不会直接使用由用户提供的输入。

 

可以按以下方式将例 1 重写为与 NumberFormatException 对应的预定义日志条目:

...

public static final String NFE = "Failed to parse val. The input is required to be an integer value."

...

String val = request.getParameter("val");

try {

  int value = Integer.parseInt(val);

}catch (NumberFormatException nfe) {

  log.info(NFE);

}

..

  在某些情况下,这个方法有些不切实际,因为这样一组合法的日志条目实在太大或是太复杂了。这种情况下,开发者往往又会退而采用黑名单方法。在输入之前,黑名单会有选择地拒绝或避免潜在的危险字符。然而,不安全字符列表很快就会不完善或过时。更好的方法是创建一份白名单,允许其中的字符出现在日志条目中,并且只接受完全由这些经认可的字符组成的输入。在大多数 Log Forging 攻击中,最关键的字符是\n”(换行符),该字符决不能出现在日志条目白名单中。

 

图1.2.1:过滤引起Log Forging漏洞的敏感字符的公共方法

posted @ 2018-05-14 22:22  Xavier-Xu  阅读(13974)  评论(0编辑  收藏  举报