Attacking Secondary Contexts in Web Applications

Security considerations when using modern routing technologies for web servers by Sam Curry

security
software
web applications
JavaScript
  1. Home
  2. Google Slide
  3. Attacking Secondary Contexts in Web Applications

Attacking Secondary Contexts in Web Applications

Security considerations when using modern routing technologies for web servers by Sam Curry

security, software, web applications, JavaScript

Attacking Secondary Contexts in Web Applications

Sam Curry

whoami

Sam Curry (@samwcyo)

Full time bug bounty hunter (3 years on-and-off)

Passionate about application security/research (run blog @ samcurry.net)

How I previously thought all HTTP servers worked...

Application files are stored/accessed in webserver folder

/var/www/html/

/usr/share/nginx/html/

… etc …

GET /index.html

Tries to load in /webserver/index.html

GET /folder/index.html

Tries to load in /webserver/folder/index.html

Very straightforward and simple

Different ways web applications do routing

Not actually dealing with stored files, rather using defined routes

Different ways web applications do routing

Sent across middleware and proxies, sometimes through load balancers...

Different ways web applications do routing

Fetching content from APIs

Sending a 2nd HTTP request

Usually a different host

Common lack of input validation

Sometimes carries auth info to API

Underlying authentication models

Sometimes not present…

Methods for identifying application routing

Directory traversal

Does “/api/../” return something different than “/”?

Fuzzing using control characters

%23 (#), %3f (?), %26 (&), %2e (.), %2f (/), %40 (@)

Double/triple URL encoding

Does the behavior suddenly change for certain directories?

Why does “/images/” return different headers than “/”?

Are there any nice bits of information we can catch?

“internal.company.com:8080 returned the following: ‘500 internal server error’”

Identifying application routing - Examples

We can identify /favicon.ico* is being served through CloudFront

What if this was being served through an S3 bucket?

GET /favicon.ico/..%2f..%2fattackersbucket%2fxss.html

(Proxied as https://s3.amazonaws.com/yahoo-bucket/favicon.ico/../../attackersbucket/xss.html)

Identifying application routing - Examples

Requesting the webroot behaves totally normally

Browsing to /api/v1/ reveals different behavior

Different headers, content-type, etc.

We can confirm the routing is separate via traversing backwards to “/” on the API server via “/../../../”

Common issues with secondary contexts

Data is being served across extra layers

Introduces translation issues like HTTP request smuggling

CRLF injection in weird places

Developers do not expect users to be able to control parameters/paths

Functionality you would normally see in a development environment is accessible (?debug=1, /server-status)

Information disclosure

Internal HTTP headers, access token

SSRF and XSS via manipulating response content

Finding an open redirect in 2nd context = server issuing/potentially rendering arbitrary request

Additionally, Apache, NGINX, and many other HTTP servers have proxy functionalities for paths where HTTP requests are forwarded.

Identifying application routing - Examples

Passing in “%23” turns into “#” and makes the underlying request fail as the parameters are dropped

What control do we have over the second request?

How could this be exploited by an attacker?

Identifying application routing - Examples

Traversing backwards allows us to overwrite the API paths

Indexing for user ID is based on the session cookie

Identifying application routing - Examples

We can traverse the internal API, overwrite the user ID, then read a victim’s file

All other API calls are also accessible GET /files/..%2f..%2f + victim ID + %2f + victim filename

Common issues attacking secondary contexts

APIs will oftentimes not normalize request URLs

Impossible to traverse API calls

Common issues attacking secondary contexts

Underlying authentication makes access control issues impossible

Even if an API is internal, there isn’t any benefit besides widened attack surface

Identifying application routing - Examples

HTTP request loads the specified invoice PDF

IDOR doesn’t work, returns 404 (somewhat interesting)

Are they doing anything weird/exploitable here?

Identifying application routing - Examples

GET /my-services/invoices/..%2finvoices%2fINV08179455/pdf

This works (200 with PDF content)

GET /my-services/invoices/..%2f..%2fmy-services%2finvoices%2fINV08179455/pdf

This doesn’t (404 without PDF content)

This doesn’t really prove anything, but it’s interesting

If it were traversing on the same box/normally, it’d likely load both

This is probably worth at least investigating a little bit

Identifying application routing - Examples

There’s a possibility a directory before “/invoices/” is indexing our uploads (/:userid/invoices/:invoiceid)

If we can guess this directory, we can potentially view other users invoices

Lots of things to guess here...

Identifying application routing - Examples

Intruder (0-1000000) not working

Email not working

Username not working

Error message on another part of the app discloses the following… {"error":"Id [email protected]#vj does not have permission to modify the domain example.com."}

Moment of truth...

… but ...

Identifying application routing - Examples

Attacker can read anyones PDF if they know their…

Email address

Invoice number

An alright bug… I guess....

Is this behavior anywhere else on the app?

Identifying application routing - Examples

Definitely a more interesting part of the website

How is payment information fetched?

Identifying application routing - Examples

Maybe this is stored the same way, but if so…

What is the directory name?

How can we retrieve that unique ID?

Identifying application routing - Examples

Maybe this is stored the same way, but if so…

What is the directory name? (/paymentmethods/)

How can we retrieve that unique ID?

Identifying application routing - Examples

Maybe this is stored the same way, but if so…

What is the directory name? (/paymentmethods/)

How can we retrieve that unique ID? (trick with /subscriptions/)

GET /subscriptions/:id + Same trick from before = Traversing to view payment method IDs

https://www.luminate.com/subscriptions/..%2f..%2f + email + %2f + id

Identifying application routing - Examples

GET /my-services/edit-payment-method?uid=../../ [email protected]%23vj/paymentmethods/2c92a00871083a4600fa287ce52fe

Identifying application routing - Examples

Escalated severity from reading users invoices to reading payment information

The only piece of information we need is the victim’s email address

The subscription ID can be brute forced

We obtain the payment ID from the subscription ID traversal

Exploring all possibilities

Although directory traversal is useful for these types of bugs, it isn’t necessary for various attacks

In some cases, API calls behave similarly to a SQL query evaluating to true/false

Impact of course varies per case, but there are lots of interesting possibilities

Case Study - Authy 2FA bypass

Authy - 2FA service, installable library

User -> [Client -> Authy]

Case Study - Authy 2FA bypass

When reading the response from Authy, the server only checked for…

JSON {“success”:true}

HTTP 200 OK

How is the users token sent to Authy? this._request("get", "/protected/json/verify/" + token + "/" + id, {}, callback, qs);

GET /protected/json returns both 200 OK and JSON {“success”:true}

Is it really that simple?

Case Study - Authy 2FA bypass

Universal 2FA bypass for huge portion of Authy libraries (credit: Egor Homakov, @homakov)

Review

Lots of unique opportunities in attacking secondary contexts

Requests often sent internally

Often less restrictive environments

Authorization sometimes seemingly arbitrary (200 v.s. 403 when you control route)

Very complicated problem for developers

Requests sent between servers with different behaviors

Hard to isolate internal APIs where user data isn’t dangerous

Sanitizing for paths is relatively difficult 2-3 proxies deep

Lots of new research relative to similar approaches

Using “Max-Forwards” header to figure out more information about your requests (https://www.agarri.fr/blog/archives/2011/11/12/traceroute-like_http_scanner/index.html)

Thank you Kernelcon!

Questions? Maybe answers?

@samwcyo

Sam Curry

Attacking Secondary Contexts in Web Applications
Info
Tags Security, Software, Web applications, JavaScript
Type Google Slide
Published 03/05/2024, 16:15:54

Resources

Ransomware Overview