惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
雷峰网
雷峰网
罗磊的独立博客
T
The Blog of Author Tim Ferriss
阮一峰的网络日志
阮一峰的网络日志
量子位
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
人人都是产品经理
人人都是产品经理
GbyAI
GbyAI
Cisco Talos Blog
Cisco Talos Blog
Engineering at Meta
Engineering at Meta
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
A
About on SuperTechFans
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Cloudflare Blog
Know Your Adversary
Know Your Adversary
T
Threat Research - Cisco Blogs
Spread Privacy
Spread Privacy
D
DataBreaches.Net
T
The Exploit Database - CXSecurity.com
K
Kaspersky official blog
Cyberwarzone
Cyberwarzone
爱范儿
爱范儿
U
Unit 42
Security Latest
Security Latest
M
MIT News - Artificial intelligence
月光博客
月光博客
Scott Helme
Scott Helme
G
Google Developers Blog
有赞技术团队
有赞技术团队
T
Tor Project blog
宝玉的分享
宝玉的分享
Y
Y Combinator Blog
博客园 - Franky
H
Hackread – Cybersecurity News, Data Breaches, AI and More
aimingoo的专栏
aimingoo的专栏
The GitHub Blog
The GitHub Blog
V
V2EX
B
Blog
Apple Machine Learning Research
Apple Machine Learning Research
S
Securelist
博客园 - 三生石上(FineUI控件)
Blog — PlanetScale
Blog — PlanetScale
TaoSecurity Blog
TaoSecurity Blog
Stack Overflow Blog
Stack Overflow Blog
P
Proofpoint News Feed
腾讯CDC
D
Docker
Google Online Security Blog
Google Online Security Blog

Orange

[EN] Confusion Attacks: Exploiting Hidden Semantic Ambiguity in Apache HTTP Server! [中文] Confusion Attacks: Exploiting Hidden Semantic Ambiguity in Apache HTTP Server! CVE-2024-4577 - Yet Another PHP RCE: Make PHP-CGI Argument Injection Great Again! 從 2013 到 2023: Web Security 十年之進化與趨勢! A New Attack Surface on MS Exchange Part 4 - ProxyRelay! Let's Dance in the Cache - Destabilizing Hash Table on Microsoft IIS! A New Attack Surface on MS Exchange Part 3 - ProxyShell! A New Attack Surface on MS Exchange Part 2 - ProxyOracle! A New Attack Surface on MS Exchange Part 1 - ProxyLogon! A Journey Combining Web Hacking and Binary Exploitation in Real World! How I Hacked Facebook Again! Unauthenticated RCE on MobileIron MDM 你用它上網,我用它進你內網! 中華電信數據機遠端代碼執行漏洞 An analysis and thought about recently PHP-FPM RCE(CVE-2019-11043) Attacking SSL VPN - Part 3: The Golden Pulse Secure SSL VPN RCE Chain, with Twitter as Case Study! Attacking SSL VPN - Part 2: Breaking the Fortigate SSL VPN Attacking SSL VPN - Part 1: PreAuth RCE on Palo Alto GlobalProtect, with Uber as Case Study! A Wormable XSS on HackMD! Hacking Jenkins Part 2 - Abusing Meta Programming for Unauthenticated RCE! Hacking Jenkins Part 1 - Play with Dynamic Routing HITCON CTF 2018 - One Line PHP Challenge Google CTF 2018 Quals Web Challenge - gCalc Pwn a CTF Platform with Java JRMP Gadget PHP CVE-2018-5711 - Hanging Websites by a Harmful GIF How I Chained 4 vulnerabilities on GitHub Enterprise, From SSRF Execution Chain to RCE!
How I Chained 4 Bugs(Features?) into RCE on Amazon Collaboration System
http://blog.orange.tw/ · 2018-08-10 · via Orange

Hi! This is the case study in my Black Hat USA 2018 and DEFCON 26 talk, you can also check slides here:

In past two years, I started to pay more attention on the “inconsistency” bug. What's that? It’s just like my SSRF talk in Black Hat and GitHub SSRF to RCE case last year, finding inconsistency between the URL parser and the URL fetcher that leads to whole SSRF bypass!

There is also another very cool article Bypassing Web-Application Firewalls by abusing SSL/TLS to illustrate how “inconsistency” be awesome by @0x09AL

So this year, I started focus on the “inconsistency” which lies in the path parser and path normalization!
It’s hard to write a well-designed parser. Different entity has its own standard and implementation. In order to fix a bug without impacting business logic, it’s common to apply a work-around or a filter instead of patching the bug directly. Therefore, if there is any inconsistency between the filter and the called method, the security mechanism can be easily bypassed!

While I was reading advisories, I noticed a feature called URL Path Parameter. Some researchers have already pointed out this feature may lead to security issues, but it still depends on the programming failure! With a little bit mind-mapping, I found this feature could be perfectly applied on multi-layered architectures, and this is vulnerable by default without any coding failure. If you are using reverse proxy with Java as your back-end service, you are under threat!

Back to 2015, it was the first time I found this attack surface was during in a red teaming. After that, I realized this was really cool and I’m curious about how many people know that. So I made a challenge for WCTF 2016.
(I have checked scanners in DirBuster, wFuzz, DirB and DirSearch. Until now, only DirSearch joined the pattern on 1 May, 2017)

WCTF is a competition held by Belluminar and 360. It’s not similar to general Jeopardy or Attack & Defense in other CTF competitions. It invites top 10 teams from all over the world, and every team needs to design two challenges, so there are 20 challenges! The more challenges you solved, the more points you got. However, no one solved my challenge during the competition. Therefore, I think this trick may not be well-known!

This year, I decide to share this technique. In order to convince review boards this is awesome, I need more cases to prove it works! So I started hunting bugs! It turns out that, this attack surface can not only leak information but also bypass ACL(Such as my Uber OneLogin bypass case) and lead to RCE in several bug bounty programs. This post is one of them!
(if you are interested in other stories, please check the slide ASAP!!!)

↓ The inconsistency in multi-layered architectures!
img

Foreword


First, thanks Amazon for the open-minded vulnerability disclosure. It’s a really good experience working with Amazon security team(so does Nuxeo team). From the Timeline, you can see how quick Amazon’s response was and the step they have taken!

The whole story started with a domain collaborate-corp.amazon.com. It seems to be a collaboration system for internal purpose. From the copyright in the bottom, we know this system was built from an open source project Nuxeo. It’s a very huge Java project, and I was just wanting to improve my Java auditing skill. So the story begins from that…!


For me, when I get a Java source, the first thing is to read the pom.xml and find if there are any outdated packages. In Java ecosystem, most vulnerabilities are due to the OWASP Top 10 - A9. known vulnerable components.
Is there any Struts2, FastJSON, XStream or components with deserialization bugs before? If yes. Congratz!

In Nuxeo, it seems most of packages are up to date. But I find a old friend - Seam Framework. Seam is a web application framework developed by JBoss, and a division of Red Hat. It HAD BEEN a popular web framework several years ago, but there are still lots of applications based on Seam :P

I have reviewed Seam in 2016 and found numerous hacker-friendly features! (Sorry, it’s only in Chinese) However, it looks like we can not direct access the Seam part. But still remark on this, and keep on going!

1. Path normalization bug leads to ACL bypass

While looking at the access control from WEB-INF/web.xml, we find Nuxeo uses a custom authentication filter NuxeoAuthenticationFilter and maps /* to that . From the filter we know most pages require authentication, but there is a whitelist allowed few entrance such as login.jsp. All of that is implemented in a method bypassAuth.

protected boolean bypassAuth(HttpServletRequest httpRequest) {
    
    // init unAuthenticatedURLPrefix

    try {
        unAuthenticatedURLPrefixLock.readLock().lock();
        String requestPage = getRequestedPage(httpRequest);
        for (String prefix : unAuthenticatedURLPrefix) {
            if (requestPage.startsWith(prefix)) {
                return true;
            }
        }
    } finally {
        unAuthenticatedURLPrefixLock.readLock().unlock();
    }

    // ...

    return false;
}

As you can see, bypassAuth retrieves the current requested page to compare with unAuthenticatedURLPrefix. But how bypassAuth retrieves current requested page? Nuxeo writes a method to extract requested page from HttpServletRequest.RequestURI, and the first problem appears here!

protected static String getRequestedPage(HttpServletRequest httpRequest) {
    String requestURI = httpRequest.getRequestURI();
    String context = httpRequest.getContextPath() + '/';
    String requestedPage = requestURI.substring(context.length());
    int i = requestedPage.indexOf(';');
    return i == -1 ? requestedPage : requestedPage.substring(0, i);
}

In order to handle URL path parameter, Nuxeo truncates all the trailing parts by semicolon. But the behaviors in URL path parameter are various. Each web server has it’s own implementation. The Nuxeo’s way may be safe in containers like WildFly, JBoss and WebLogic. But it runs under Tomcat! So the difference between the method getRequestedPage and the Servlet Container leads to security problems!

Due to the truncation, we can forge a request that matches the whitelist in ACL but reach the unauthorized area in Servlet!
In here, we choose login.jsp as our prefix! The ACL bypass may look like this:

$ curl -I https://collaborate-corp.amazon.com/nuxeo/[unauthorized_area]
HTTP/1.1 302 Found
Location: login.jsp
...

$ curl -I https://collaborate-corp.amazon.com/nuxeo/login.jsp;/..;/[unauthorized_area]
HTTP/1.1 500 Internal Server Error
...

As you can see, we bypass the redirection for authentication, but most pages still return a 500 error. It’s because the servlet logic is unable to obtain a valid user principle so it throws a Java NullPointerException. Even though, this still gives us a chance to knock the door!

P.s. Although there is a quicker way to open the door, it’s still worth to write down the first try!

2. Code reuse feature leads to partial EL invocation

As I mentioned before, there are numerous hacker-friendly features in Seam framework. So, for me, the next step is chaining the first bug to access unauthorized Seam servlet!

In the following sections, I will explain these “features” one by one in detail!

In order to control where browser should be redirected, Seam introduces a series of HTTP parameter, and it is also buggy in these HTTP parameters… actionOutcome is one of them. In 2013, @meder found a remote code execution on that. You can read the awesome article CVE-2010-1871: JBoss Seam Framework remote code execution for details! But today, we are going to talk about another one - actionMethod!

actionMethod is a special parameter that can invoke specific JBoss EL(Expression Language) from query string. It seems dangerous but there are some preconditions before the invocation. The detailed implementation can found in method callAction. In order to invoke the EL, it must satisfy the following preconditions:

  1. The value of actionMethod must be a pair which looks like FILENAME:EL_CODE
  2. The FILENAME part must be a real file under context-root
  3. The file FILENAME must have the content "#{EL_CODE}" in it (double quotes and are required)

For example:
There is a file named login.xhtml under context-root.

<div class="entry">
    <div class="label">
        <h:outputLabel id="UsernameLabel" for="username">Username:</h:outputLabel>
    </div>
    <div class="input">
        <s:decorate id="usernameDecorate">
            <h:inputText id="username" value="#{user.username}" required="true"></h:inputText>
        </s:decorate>
    </div>
</div>

You can invoke the EL user.username by URL

http://host/whatever.xhtml?actionMethod=/foo.xhtml:user.username

3. Double evaluation leads to EL injection

The previous feature looks eligible. You can not control any file under context-root so that you can’t invoke arbitrary EL on remote server. However, here is one more crazy feature…

To make things worse, if the previous one returns a string, and the string looks like an EL. Seam framework will invoke again!

img

Here is the detailed call stack:

  1. callAction(Pages.java)
  2. handleOutcome(Pages.java)
  3. handleNavigation(SeamNavigationHandler.java)
  4. interpolateAndRedirect(FacesManager.java)
  5. interpolate(Interpolator.java)
  6. interpolateExpressions(Interpolator.java)
  7. createValueExpression(Expressions.java)

With this crazy feature. We can execute arbitrary EL if we can control the returned value!
This is very similar to ROP(Return-Oriented Programming) in binary exploitation. So we need to find a good gadget!

In this case, we choose the gadget under widgets/suggest_add_new_directory_entry_iframe.xhtml

  <nxu:set var="directoryNameForPopup"
    value="#{request.getParameter('directoryNameForPopup')}"
    cache="true">
  <nxu:set var="directoryNameForPopup"
    value="#{nxu:test(empty directoryNameForPopup, select2DirectoryActions.directoryName, directoryNameForPopup)}"
    cache="true">
  <c:if test="#{not empty directoryNameForPopup}">

Why we choose this? It’s because that request.getParameter returns a string that we can control from query string! Although the whole tag is to assign a variable, we can abuse the semantics!

So now, we put our second stage payload in the directoryNameForPopup. With the first bug, we can chain them together to execute arbitrary EL without any authentication! Here is the PoC:

http://host/nuxeo/login.jsp;/..;/create_file.xhtml
?actionMethod=widgets/suggest_add_new_directory_entry_iframe.xhtml:request.getParameter('directoryNameForPopup')
&directoryNameForPopup=/?#{HERE_IS_THE_EL}

Is that over yet? No really! Although we can execute arbitrary EL, we still failed to pop out a shell. Why?
Let’s go to next section!

4. EL blacklist bypass leads to RCE

Seam also knows that EL is insane. Since Seam 2.2.2.Final, there is a new EL blacklist to block dangerous invocations! Unfortunately, Nuxeo uses the latest version of Seam(2.3.1.Final) so that we must find a way to bypass the blacklist. The blacklist can be found in resources/org/jboss/seam/blacklist.properties.

.getClass(
.class.
.addRole(
.getPassword(
.removeRole(

With a little bit studying, we found the blacklist is just a simple string matching, and we all know that blacklist is always a bad idea. The first time I saw this, I recalled the bypass of Struts2 S2-020. The idea of that bypass and this one is the same. Using array-like operators to avoid blacklist patterns! Just change:

"".getClass().forName("java.lang.Runtime")

to

""["class"].forName("java.lang.Runtime")

Is it simple? Yes! That’s all.

So the last thing is to write the shellcode in JBoss EL. We use Java reflection API to get the java.lang.Runtime Object, and list all methods from that. The index 7 is the method getRuntime() to return a Runtime instance and the index 15 is the method exec(String) to execute our command!

OK! Let’s summarize our steps and chain all together!

  1. Path normalization bug leads to ACL bypass
  2. Bypass whitelist to access unauthorized Seam servlet
  3. Use Seam feature actionMethod to invoke gadgets in file suggest_add_new_directory_entry_iframe.xhtml
  4. Prepare second stage payload in HTTP parameter directoryNameForPopup
  5. Use array-like operators to bypass the EL blacklist
  6. Write the shellcode with Java reflection API
  7. Wait for our shell back and win like a boss ._./

Here is the whole exploit:

img

OK, by executing the Perl script, we got the shell!

img

The fix


I will illustrate the fix from 3 aspects!

1. JBoss

As the most buggy thing is on Seam framework. I have reported these “features” to security@jboss.org in Sept 2016. But their reply is:

Thanks very much for reporting these issues to us.

Seam was only included in EAP 5, not 6, or 7. EAP is near the end of maintenance support, which will end in Nov 2016, [1]. The upstream version you used to test was released over 3 years ago.
During maintenance support EAP 5 only receives patches for important or critical issues. While you highlight that RCE is possible, only on the precondition that the attack can first upload a file. This seems to reduce the impact to moderate.

I think we will not bother to fix these security issues at this stage of the Seam project lifecycle.

[1] https://access.redhat.com/support/policy/updates/jboss_notes/

We do appreciate your efforts in reporting these issues to us, and hope that you will continue to inform us of security issues in the future.

So due to the EOL, there seems to be no official patch for these crazy features. However, lots of Seam applications are still running in the world. So if you use Seam. I recommend you to mitigate this with Nuxeo’s fix.

2. Amazon

With a rapid investigation, Amazon security team isolated the server, discussed with the reporter about how to mitigate, and listed every step they have taken in detail! It’s a good experience working with them :)

3. Nuxeo

After the notification from Amazon, Nuxeo quickly released a patch in version 8.10. The patch overrides the method callAction() to fix the crazy feature! If you need the patch for your Seam application. You can refer the patch here!

Timeline


  • 10 March, 2018 01:13 GMT+8 Report to Amazon security team via aws-security@amazon.com
  • 10 March, 2018 01:38 GMT+8 Receive that they are under investigating
  • 10 March, 2018 03:12 GMT+8 Ask that can I join the conference call with security team
  • 10 March, 2018 05:30 GMT+8 Conference call with Amazon, get the status and the step they have taken for the vulnerability
  • 10 March, 2018 16:05 GMT+8 Ask if it’s possible public disclosure on my Black Hat talk
  • 15 March, 2018 04:58 GMT+8 Nuxeo released a new version 8.10 that patched the RCE vulnerability
  • 15 March, 2018 23:00 GMT+8 Conference call with Amazon, know the status and discuss public disclosure details
  • 05 April, 2018 05:40 GMT+8 Reward the award from Amazon