log4shell 漏洞是如何工作的?

信息安全 log4shell 金迪
2021-08-16 07:38:46

Log4shell正在制造新闻。广泛使用的日志工具 Log4J 中的一个漏洞使许多服务器甚至一些桌面应用程序面临远程代码执行的风险。

这个漏洞是如何工作的?什么样的错误使它成为可能?它是关于格式字符串和${jndi:...}的,但为什么这样的字符串会导致远程代码执行?

我正在寻找适合没有任何 Log4J 或高级安全问题经验的 IT 专业人员的级别的解释。有点像您如何向新手 Web 开发人员解释 SQLi 或 XSS。

1个回答

简而言之-据我了解,该漏洞是由以下原因引起的:

  • 将用于记录的数据视为可信数据,即使它们可能来自不受信任的来源(例如记录 HTTP 请求的用户代理)
  • 结合 log4j2 中强大的字符串扩展
  • 使用 LDAP 或 RMI 触发远程序列化 Java 对象的加载
  • 这会在实例化(反序列化)加载的对象时导致代码执行

详细 - 有几个设计问题会导致问题:

  • log4j 允许在日志字符串中进行字符串扩展,例如${date:YYYYMMDD}. 不幸的是,这个功能在 log4j 2.15.0 之前默认启用,即使日志记录通常包括不受信任的用户输入,例如logger.debug(userInput). 出乎意料的是,不受信任输入的字符串扩展甚至可以与参数化语句一起使用,例如logger.debug("user said: {}", userInput).
  • 远程攻击者不仅可以包含和触发像日期这样看似无害的扩展,而且还可以使用Java 命名和目录接口 (JNDI)进行动态名称查找- 即${jndi:ldap://host:port/whatever}. 这是一种强大的机制,具有多年以来已知的巨大潜在攻击面 - 请参阅Blackhat 2016的演讲。
  • 这种潜在的大型攻击面来自使用 LDAP 或 RMI 从远程系统加载序列化 Java 对象的能力。这些对象的实例化需要反序列化,这可能导致代码执行。这可以通过利用已安装类中的错误来完成,例如2015 年 Apache Commons 中这个著名且广泛存在的问题或者在某些情况下,它甚至可以通过从远程加载未知类的代码来完成。换句话说:Java 的高度灵活性使安全问题成为可能

请注意,这里没有一个意外漏掉的实际错误。一切都按设计工作。在涉及记录不受信任的数据的实际用例中,只有设计不能提供必要的稳健性。