»Breaking Parser Logic: Take Your Path Normalization off and Pop 0days Out!«
2018-10-18, 14:15–15:00, Europe

We propose a new exploit technique that brings a whole-new attack surface to defeat path normalization, which is complicated in implementation due to many implicit properties and edge cases. This complication, being under-estimated or ignored by developers for a long time, has made our proposed attack vector possible, lethal, and general. Therefore, many 0days have been discovered via this approach in popular web frameworks written in trending programming languages, including Python, Ruby, Java, and JavaScript.

Being a very fundamental problem that exists in path normalization logic, sophisticated web frameworks can also suffer. For example, we’ve found various 0days on Java Spring Framework, Ruby on Rails, Next.js, and Python aiohttp, just to name a few. This general technique can also adapt to multi-layered web architecture, such as using Nginx or Apache as a proxy for Tomcat. In that case, reverse proxy protections can be bypassed. To make things worse, we’re able to chain path normalization bugs to bypass authentication and achieve RCE in real world Bug Bounty Programs. Several scenarios will be demonstrated to illustrate how path normalization can be exploited to achieve sensitive information disclosure, SMB-Relay and RCE.

Understanding the basics of this technique, the audience won’t be surprised to know that more than 10 vulnerabilities have been found in sophisticated frameworks and multi-layered web architectures aforementioned via this technique.

Outline

TL;DR

Writing a parser is hard, and there are lots of implicit properties and edge cases hard to cover! We proposed the attack surface on path normalization, and list several exploit techniques to break it! Based on these attack vectors, numerous 0days have been uncovered on well-known web frameworks. Including Ruby on Rails, Java Spring Framework, Java Spark, Next.js, Koa.js, Python aiohttp... and so on.

We also utilize these problems on famous web servers such as Nginx and Tomcat. The problem is very prevalent but only few people know it, so we found lot's of vulnerabilities in real world Bug Bounty Programs like Uber, Amazon, Netflix, Sky Scanner and Docker!

For the highlight, we will demonstrate how to chained 5 vulnerabilities to RCE on our Amazon case! (For more details, please check "0days" section)

Methodologies we used: Side effects and implicit properties on programming languages and built-in libraries The problem in multi-layered web architectures. The inconsistency between each layer leads various security issue * Invisible features on OS and FileSystem

P.s. The last but not least, we will release a new tool that cover problems we mentioned!

0days

  • Ruby on Rails
    • Most popular Ruby web framework. 39K Stars on GitHub
    • Vendor confirmed and waiting for the fix
  • Sinatra
    • Second famous Ruby web framework. 10K Stars on GitHub
    • CVE-2018-7212 assigned
  • Spring Framework
    • Most popular Java web framework. 21K Stars on GitHub
    • CVE-2018-1271 assigned with HIGH severity
  • Spark
    • Famous Java Rest framework. 7K Stars on GitHub
    • CVE-2018-9159 assigned
  • aiohttp
    • Famous Python asyncio framework. 5K Stars on GitHub
    • Fixed
  • Next.js
    • Most popular JavaScript Server-Side Rendering framework. 23K Stars on GitHub
    • CVE-2018-6184 assigned
  • KoaJS
    • Famous NodeJS web framework. 20K Stars on GitHub
    • Fixed
  • Resolve-Path
    • A very fundamental library on NodeJS ecosystem
    • CVE-2018-3732 assigned
  • DropWizard
    • Famous Java Rest framework
  • PostGraphQL
    • Fixed
  • WhiteNoise
  • Bug Bounty Programs
    • Amazon Collaborate System
      • Remote Code Execution
      • Chained 5 vulnerabilities. From Path Normalization bug to RCE
        • Path Normalization bug
        • -> Authentication Bypass
        • -> Code Reused(Features in Seam Framework)
        • -> Expression Language Black-Lists Bypass
        • -> Remote Code Execution
      • Vendor confirmed and waiting for a fix
    • Skyscanner.net
      • Vendor confirmed and fixed
      • Got Priority P1(Critical) and the maximum bounty in their program
    • Uber.com
      • Bypass OneLogin access control on *.uberinternal.com
      • Vendor confirmed and waiting for a fix
    • Bynder.com
      • Lots of companies(Such as Spotify, Canon, Puma...) are using as it's asset management
      • Multi-layered web architecture problem to Remote Code Execution
      • We will also introduce the CFML language and how we get code execution from Railo server
      • Vendor confirmed and fixed
    • Docker.com
      • Vendor confirmed and fixed
    • Netflix.com

Methodology / My Research

We separated our content into 3 categories 1. Attacking multi-layered architectures: The inconsistency between each layer leads various security issue 2. Side effects and implicit properties on built-in libraries 3. Breaking path normalization: Chaining features to 0day on trending web frameworks

<hr>
  1. Attacking multi-layered architectures: The inconsistency between each layer leads various security issue
    • J2EE feature
      • It's common to configure the J2EE application behind a web server such as Nginx or Apache
      • J2EE supports Path Parameter( separated by semicolon ;) in URL, and we can traverse the the path by /..;blah/
      • There is no one mentioned this before
      • For example:
      • Another example (Inconsistencies between application logic and Servlet)
        • Application use Java Servlet Filter to ensure only authenticated user can access, and only white-listed login.jsp
        • The logic is: java 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); }
        • The Java filter logic is inconsistent with router logic, and we can bypass the authentication by:
          • /context/internal_interface/ -> 401 unauthorized
          • /context/login.jsp;/..;blah/internal_interface/ -> 200 OK
          • We achieved a RCE on Amazon server by chaining 5 bugs, from this Path Normalization bug to bypass Authentication and lead to RCE
          • We also leverage this feature on Bynder(Spotify case) Bug Bounty Program to access Internal Railo manager interface and accomplish RCE!
          • We bypass the Uber OneLogin mechanism and access Internal resources in their Bug Bounty Program
    • Nginx fail
      • Misusing alias directive. For example: ``` # this is good location /static/ { alias /home/app/static/; }

        issing a suffix slash is vulnerable

        location /static { alias /home/app/static/; } - https://example.com/static/../ - Nginx normalizes `/static/../` to `/`, and does nothing - https://example.com/static../settings.py - Nginx matched the pattern `/static`, and appended `../settings.py` to `/home/app/static/` - This expose Django source code to attackers! - This problem found on several websites. For example we exploit this on Sky Scanner(a famous travel website) Bounty Program 2. Side effects and implicit properties on built-in libraries * Python2 `path.join`, Python3 `pathlib.pathjoin` `pathlib.resolve`. For example:python filename = request.match_info['filename'] try: filepath = self._directory.joinpath(filename).resolve() if not self._follow_symlinks: filepath.relative_to(self._directory) except (ValueError, FileNotFoundError) as error: raise HTTPNotFound() from error - Everyone is trying to bypass the `relative_to` check, but it is unbreakable - We leverage side effects on `joinpath` and `resolve` to perform SMB-Relay attack! - The side effect of `joinpath` change the root `_directory` if the filename is a absolute path - `os.path.join('/var/tmp/', '\\\\orange.tw\\c$')` will become `\\orange.tw\c$` - The side effect of `resolve` always read the Symlink - Leak Net-NTLM hash - SMB-Relay * Python `normpath` - `normpath` follows POSIX standard, allowing double leading slash! - `os.path.normpath('////etc/////secret_file')` -> `//etc/secret_file` - This feature seems harmless, but it can chain with the side effect of `path.join` - Our `WhiteNoise` case is about that! * Java `URL` file scheme parser bug. For example:java URL u = new URL(args[0]); String path = u.getPath() InputStream stream = u.openConnection().getInputStream(); `` - If we passfile:///var/tmp/hi?../../../../etc/secret_fileon Linux - path is/var/tmp/hi- stream is the content of/var/tmp/hi- But the behavior on Windows is weird. For the path:file:///C:/windows/temp/hi?../../../secret_file- path isC:/windows/temp/hi- stream is the content ofC:/windows/secret_file- Leverage?on Java parser can read arbitrary files * NodeJSCVE-2017-14849- Normalization fail onpath.normalize. The parser setisAboveRootflag incorrectly - Expected result ofpath.normalize("./../aa/../../")is../../, but./instead - This bug smashed the path mitigation ofExpressJS-ExpressJScheck there is no..in the result ofpath.normalize* NodeJSpath.resolve- This is similar to Pythonpath.join, it changes the root path -path.resolve('/var/tmp/sandbox/', username), ifusernamestart-with the slash, there is an arbitrary write * NodeJSsend-sendis a very fundamental library on NPM - Problem 1: Inappropriate usage. For example: * In order to be a router-free framework. Next.JS usesendwithout settingrootparameter * This is vulnerable for Path Traversal - Problem 2: Invisible feature * The implementation ofsendurl-decoded the path again. It's dangerous if developers don't know that * Windows "features" * Path normalization feature! -C:/windows/secret_file.. . . . ....is as same asC:/windows/secret_file- This can fingerprint remote OS byhttps://example.com/static/app.js.%20...* The CWD on Windows is driver separated -C:../../is a relative path but lots parser fail on parsing this - We exploit this feature on the 0day ofKoaJS* Windows NTFS / ADS features - Tilde, short file name -::$DATA-::$$Index_Allocation3. Breaking path normalization: Chaining features to 0day on trending web frameworks * Ruby on Rails 0day 1. RoR handle static assets by Gemsprockets, andsprocketssupported several protocols in path translation 2. RoR urldecoded the path twice, so double encoding works! 3. RoR failed to check absolute path byabsolute_path?, and bypassed by file protocol 4. You can read arbitrary files byhttps://example.com/assets/file:%252f//etc/secret_file5. Thesprocketsimplementation supports different content-type processing, especially ERB(Ruby template engine) 6. We can chain the Path Traversal to Server-Side Template Injection and lead to Remote Code Execution! * Spring Framework 0day 1. The normalization bug is inStringUtils.cleanPath, it splits user-supplied path by/but forgets to clean empty value 2. Spring Framework usesjava.net.URIto combine two path, butURIwill url-decode the path internally 3. Bypass the prefix check inUrlFileResource.checkResource* Spark 0day 1. Spark borrowed some code from Spring Framework. So, Spark inherited the vulnerability from Spring 2. But the root cause is different, it will introduce more on the talk! * KoaJS 0day 1. KoaJS -> Koa-static -> Koa-send -> resolve-path 2. We found the problem in parsing path likeC:../../inresolve-path3.resolve-pathnormalized the path and check there is no..- But the normalization ofC:../../is./, so the check is useless - But in NodeJS,path.resolve("C:/windows/temp/", "C:../../")isC:/4.resolve-path` is a very fundamental library, and lots of famous application suffer from this * Chaining 5 bugs to RCE in Amazon case * Chaining path normalization bug to RCE in Bynder(Spotify) case

Other

We will also cover following topics:

  1. The diversity of Java web ecosystem
    • Each stack in Java web ecosystem (Web server, servlet container, framework, JVM...) has it's own protection
    • In the Java Spring Framework 0day case, we will demonstrate how to get rid off them!
  2. The danger of NodeJS dependency
    • We found a vulnerability in resolve-path, and it's a high dependency library and lots of libraries affected

Demo

  • Demo how to chain 5 vulnerability on a Amazon server, from path normalization bug to RCE!
  • Demo how to execute arbitrary Ruby code from my Ruby on Rails Path Traversal 0day
  • Demo how J2EE fail and achieve RCE in a Bug Bounty Program
  • Demo how to pop a shell from Path Traversal to SMB-Relay(without user-interaction) in my aiohttp 0day

Previous Work