文章难易度:★★★

文章阅读点/知识点:JXBrowserJavaScript-Java bridge 中的RCE漏洞

文章作者:WisFree

文章来源:blog.portswigger.net

【技术分享】JXBrowser JavaScript-Java bridge 中的RCE漏洞

1.png (408.46 KB, 下载次数: 13)

2016-12-12 15:42 上传

前言

我近期正在研究如何使用JXBrowser来实现一套试验性的扫描技术。当我在使用JXBrowser库的过程中,我突然想到,是否可以通过调用不同的类来攻击JXBrowser客户端,并通过一个Web页面来实现远程代码执行呢?

安全客百科-JxBrowser

JxBrowser是一款采用Java语言开发的浏览器组件。JxBrowser能在Windows、Linux、Mac OSX (Intel和PPC-based)平台上将MozillaFirefox浏览器完美地整合到Java AWT/Swing应用程序里。该库程序使用Gecko设计引擎来转换HTML文档。因而保证了它能与许多Internet标准(如HTML 4、CSS、XML、JavaScript以及其它)兼容。

2.png (347.69 KB, 下载次数: 25)

2016-12-12 15:42 上传

漏洞利用技术分析

我编写的JavaScript代码(Java Bridge)大致如下:

[AppleScript] 纯文本查看 复制代码browser.addScriptContextListener(new ScriptContextAdapter() {

@Override

public void onScriptContextCreated(ScriptContextEvent event) {

Browser browser = event.getBrowser();

JSValue window = browser.executeJavaScriptAndReturnValue("window");

window.asObject().setProperty("someObj", new someJavaClass());

}

});

上面这段示例代码是从JXBrowser网站上摘录下来的。大致来说,这段代码向浏览器实例中插入了一个脚本,然后获取到了window对象,并将其转换成了一个Java JSValue对象。接下来,代码在window对象中设置了“someObj”,然后将这个Java对象传递给JavaScript window对象,这样就设置好了我们的bridge(Java桥接模式)了!根据开发文档的描述,我们在这里只能使用公共类。当我们创建好了一个bridge之后,我们在与其交互的过程中还需要使用一些JavaScript脚本。

[AppleScript] 纯文本查看 复制代码setTimeout(function f(){

if(window.someObj && typeof window.someObj.javaFunction === 'function') {

window.someObj.javaFunction("Called Java function from JavaScript");

} else {

setTimeout(f,0);

}

},0);

我在这里设置了超时(setTimeout),它可以检测我们是否已经获取到了这个“someObj”。如果没有检测到这个对象的话,代码会不断调用这个方法,直到检测到了这个对象为止。一开始,我曾尝试使用getRuntime()方法来查看我是否可以获取到一个runtime对象的实例,并运行calc(计算器)。。我所使用的调用代码如下所示:

[AppleScript] 纯文本查看 复制代码window.someObj.getClass().forName('java.lang.Runtime').getRuntime();

但是,我得到了以下的错误返回信息:

[AppleScript] 纯文本查看 复制代码Neither public field nor method named 'getRuntime' exists in the java.lang.Class Java object(Java对象java.lang.Class中不存在公共域或getRuntime方法)

难道是因为我们无法在这里调用getRuntime方法么?于是乎,我打算用更简单的方法来尝试一下,代码如下所示:

[AppleScript] 纯文本查看 复制代码window.someObj.getClass().getSuperclass().getName();

这一次,我们的代码似乎成功运行了。接下来,我开始尝试枚举出所有可用的方法。代码和运行结果如下所示:

[AppleScript] 纯文本查看 复制代码methods = window.someObj.getClass().getSuperclass().getMethods();

for(i=0;i

console.log(methods[i].getName());

}

wait

wait

wait

equals

toString

hashCode

getClass

notify

notifyAll大家可以看到,我成功地枚举出了所有的方法。接下来,我打算尝试使用一下ProcessBuilder,看看会发生什么。但是,当我每一次尝试调用构造器的时候,代码都崩溃了。根据报错信息来看,似乎构造器需要一个Java数组来作为输入。这也就意味着,我得想办法创建一个用来保存字符串的Java数组,然后将其传递给ProcessBuilder的构造器。

[AppleScript] 纯文本查看 复制代码window.someObj.getClass().forName("java.lang.ProcessBuilder").newInstance("open","-a Calculator");

//Failed

window.someObj.getClass().forName("java.lang.ProcessBuilder").newInstance(["open","-a Calculator"]);

//Failed too

别着急,我们暂时先不管这个问题,先让我们创建另一个对象来证明这个漏洞的存在。我通过下面这段代码成功地创建了一个java.net.Socket类的实例。代码如下所示:

[AppleScript] 纯文本查看 复制代码window.someObj.getClass().forName("java.net.Socket").newInstance();

但是,当我尝试调用这个对象的时候,我再一次遇到了问题,这一次系统返回的错误信息告诉我“参数类型发生错误”。虽然我现在可以创建socket对象,但是我却无法使用它们。由于我无法向该对象传递任何的参数,所以这个对象对于我来说暂时没有任何的意义,因为它根本无法使用。接下来,我又尝试去创建并使用java.io.File类的对象,但是我又失败了。我感觉现在已经走投无路了,我虽然可以创建出这些对象,但是每当这些函数需要我提供参数的时候,我都无法提供正确类型的参数值。不仅newInstance方法无法正常工作,而且其他的调用方法也无法正确运行。

柳暗花明又一村

我需要帮助,我非常迫切地需要Java大神的帮助!幸运的是,如果你在Portswigger这样的地方工作的话,你就会发现你永远不是实验室里最聪明的那个人。在我“走投无路”的时候,我便打算向Mike和Patrick寻求帮助。我把我现在遇到的问题向他们解释了一遍:我需要创建一个Java数组,然后将这个数组作为参数传递给函数方法。接下来,我们的工作重点就放在了如何在bridge中创建数组对象。

Mike认为,也许可以使用一个arraylist来实现我们的目标,因为我们可以通过toArray()这个简单的方法来将arraylist转换为一个数组(array)对象。

[AppleScript] 纯文本查看 复制代码list = window.someObj.getClass().forName("java.util.ArrayList").newInstance();

list.add("open");

list.add("-a");

list.add("Calculator");

a = list.toArray();

window.someObj.getClass().forName("java.lang.ProcessBuilder").newInstance(a));

此次调用又抛出了一个异常(提示此方法不存在),并且系统提示我们传递过来的参数实际上是一个JSObject。所以,即使我们创建了一个ArrayList并用toArray方法进行转换,得到的也是一个js对象,所以我们传递给ProcessBuilder对象的永远都是类型不正确的参数。

接下来,我们又尝试直接去创建一个数组(Array)。但是,我们在调用java.lang.reflect.Array实例的时候又出现了问题,系统再一次报错:参数类型不正确。因为对象和方法需要的是一个int类型的参数,但是我们发送的是一个double类型的值。于是,我们打算尝试使用java.lang.Integer来创建一个int类型的值。但是,我又一次悲剧了,这次还是那该死的参数类型问题。Patrick认为,我们可以使用MAX_INT属性来创建一个大数组。可能大家以为,这一次可以得到我们所需要的int类型了,但事实并非如此,Java Bridge会将整型数据(Integer)转换为double类型。

为了解决这个问题,我们打算用下面这段代码进行尝试:

[AppleScript] 纯文本查看 复制代码window.someObj.getClass().forName("java.lang.Integer").getDeclaredField("MAX_VALUE").getInt(null);

但是这一次,我们得到了系统所抛出的一个空指针异常。在思考片刻之后,我认为,为什么不尝试发送“123”,看看函数方法是否会接受这个参数值。其实我觉得这并不会起什么作用,但是它却能够打印出我们最大的int值。接下来,我们继续尝试通过最大的int值来调用数组构造器,果然不出所料,系统再一次报错了。然后,我们决定研究下runtime对象,看看我们是否可以使用同样的技术来做些什么。Mike建议使用getDeclareField方法并获取当前的runtime属性,由于它是一个私有属性,所以我们还要将其设置为“可访问”(setAccessible(true))。经过千难万阻,我们终于成功地打开了计算器(calculator.exe)。操作代码如下所示:

[AppleScript] 纯文本查看 复制代码field = window.someObj.getClass().forName('java.lang.Runtime').getDeclaredField("currentRuntime");

field.setAccessible(true);

runtime = field.get(123);

runtime.exec("open -a Calculator");

总结

这也就意味着,攻击者可以使用这项攻击技术来对任何一个使用了JXBrowser的网站(部署了JavaScript-Java Bridge)实施攻击,并完全接管目标客户端。

我们已经私下将该漏洞报告给了TeamDev(JXBrowser的项目开发组),他们在了解到该漏洞之后,便在第一时间发布了一个更新补丁。更新补丁启用了白名单机制,并且允许开发人员使用@JSAccessible annotation。请注意,如果你的应用程序没有使用@JSAccessibleannotation的话,系统并不会强制开启白名单,而此时上述的攻击方法将仍然奏效。

java rce漏洞原理_JXBrowser JavaScript-Java bridge 中的RCE漏洞相关推荐

  1. swift golang java,解决两数之和 (Javascript, Java, C#, Swift, Kotlin, Python,C++, Golang)

    解决两数之和(Javascript, Java, C#, Swift, Kotlin, Python,C++, Golang) 给定一个整数数组,返回两个数字的索引,以便它们加起来成为一个特定的目标. ...

  2. java hashset 实现原理_深入Java集合学习系列:HashSet的实现原理

    Updated on 九月 8, 2016 深入Java集合学习系列:HashSet的实现原理 1.HashSet概述: HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持. ...

  3. java 检测硬盘原理_深入Java核心 Java内存分配原理精讲

    Java内存分配与管理是Java的核心技术之一,一般Java在内存分配时会涉及到以下区域: ◆寄存器:我们在程序中无法控制 ◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中 ...

  4. java语言 编译原理_【Java学习】深入分析Java的编译原理

    在<Java代码的编译与反编译>中,有过关于Java语言的编译和反编译的介绍.我们可以通过javac命令将Java程序的源代码编译成Java字节码,即我们常说的class文件.这是我们通常 ...

  5. java 字符串池 原理_《Java虚拟机原理图解》1.2.2、Class文件中的常量池详解(上)...

    注意: 对于某个类而言,其class文件中至少要有两个CONSTANT_Class_info常量池项,用来表示自己的类信息和其父类信息.(除了java.lang.Object类除外,其他的任何类都会默 ...

  6. java监听器的原理_[转]Java监听器的原理与实现

    监听器是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动. 监听器其实就是一个实现特定接口的普通java程序,这个程序专门用于监听另 ...

  7. 深入Java核心 Java内存分配原理精讲

    深入Java核心 Java内存分配原理精讲 Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管理与内存泄露以及Java垃圾回收方面的知识,今天我们再次深入Java核心,详 ...

  8. 从tomcat说起全面理解Java web开发原理

    从tomcat说起全面理解Java web开发原理 简介:Java开发分为Java ME,Java SE,Java EE.回顾过去这些的开发工作基本上都是围绕着Java EE的,在开发经历中分别经历了 ...

  9. Web安全常见漏洞原理、危害及其修复建议

    web安全常见漏洞原理.危害及其修复建议 一. SQL注入漏洞 原理 危害 修复建议 二.XSS漏洞 原理 危害 修复建议 三. CSRF漏洞 原理 危害 修复建议 四. SSRF漏洞 原理 危害 预 ...

  10. Web渗透各种漏洞原理

    SQL注入漏洞原理 参数是用户可控的,也就是前端传入后端的参数的内容是用户可以控制的: 参数被带入数据库进行查询,也就是传入的参数被拼接到SQL语句中,并且被带入到数据库进行查询: xss漏洞原理 由 ...

最新文章

  1. 玩转android自定义控件二——自定义索引栏listview
  2. Android中修改弹出dialog背景无色透明,弹出时有遮罩
  3. 【bzoj5082】弗拉格 矩阵乘法
  4. golang string切片解析json
  5. html tr中可以有br吗,html table tr td br 什么意思 缩写
  6. 普平数据招聘:数据中心建设项目经理(工程部 )2人
  7. python识别虚假新闻的分类器_使用NLP检测和对抗AI生成的假新闻
  8. [唐诗]正月十五日夜-苏味道
  9. CSS ::selection 选中文字效果
  10. sublime text常用快捷键整理
  11. GIMP用Path作画了解一下
  12. ubuntu搭建简单http服务器
  13. Android保存照片到相册
  14. MagicBookPro-2019-Intel版BIOS降级教程
  15. android studio 顶部菜单栏消失了如何恢复
  16. Python爬取链家北京租房房价|保存为csv格式文件
  17. python3 Python.h No such file or directory
  18. 解决路由报错Uncaught (in promise) NavigationDuplicated:
  19. APQP(advanced product quality planning先期产品质量策划)
  20. RHCE考点-个人见解

热门文章

  1. 国产Linux下的录屏软件
  2. 2020定额招投标报价评审办法及案例分享交流会圆满结束
  3. mysql的语句大全_mysql语句大全
  4. 内外网同时上怎么设置
  5. STM32F103学习笔记(7)——ISP串口下载程序
  6. openproj centos安装及其输入中文变方块乱码解决
  7. OpenProj: The OpenSource Solution for Managing Your Projects
  8. 实例:python 实现有向图找环(反洗钱、资金流)
  9. .net html5 微信支付接口,解析微信支付的实现方法(.NET版)
  10. hrm系统源码php,开源HRM源码系统下载