Saturday, June 21, 2014

Browser Shredders Challenge #1

For some time now I haven't succeeded in triggering password autofill in any iOS browser from a downloaded HTML file (which would allow another easy way to steal passwords). There are no Same Origin Policy constraints for local HTML files, so it seems easy to just open the target website and read the password, but there are some problems:
- password autofill does not work in cross-domain frames in iOS browsers based on UIWebView
- calling window.open() overwrites the calling window, so I cannot control content while having the target website open
-  I didn't find any other way to set location.host or mainDocumentURL.host to target domain while still controlling the content

I guess there may be some solution which I overlooked, so here is the challenge for you:



A sample application with the code above - which you may run on iOS simulator - is available on GitHub. The task is to prepare a local HTML file (/tmp/challenge1.html) in such way that "You completed the challenge" line will get executed.

There is no reward unfortunately, apart from a humble "thank you" during our SyScan360 talk :-)

Exploring and Exploiting iOS Web Browsers - local HTML files

A quick summary of the possible methods for preventing UXSS when loading untrusted local HTML files into iOS UIWebView:

1. Load as plain text
This would probably break the planned functionality of the application, but you can always decide to use loadData method with mimeType text/plain and forget about all the HTML problems.

2. Content-Security-Policy headers
By using NSURLProtocol and connection:didReceiveResponse you can inject CSP headers to block JavaScript execution (also for file: URIs).
The only application implementing similar solution that I know of is currently Onion Browser. Cure53 found a way to bypass CSP in this browser, but this was due to the fact that file and data URIs were explicitly skipped before injecting the headers (it is a bit misleading that you can inject HTTP response headers for documents that are not requested through HTTP, but it really works).

3. HTML5 sandbox
Using iframe sandbox instead of CSP seems potentially less prone to bypasses, but it is a bit less convenient to implement. You first use loadHTMLString with baseURL=nil and a sandboxed iframe in content, then you run stringByEvaluatingJavaScriptFromString to point the iframe to the file you want to load.
This way your JavaScript can operate on the loaded file, but the loaded file cannot execute JavaScript (unless you allow-scripts or allow-top-navigation; any of them gives UXSS again).

4. Less-privileged baseURL
This is the most common solution used by many applications. Most of them use baseURL pointing to some domain related to the application, but an even better solution is to use about:blank. I already wrote about it before. This does not prevent JavaScript from running, but restores Same Origin Policy constraints.

Do you know other solutions? Or maybe you know how to break these above? Comments welcome!

Monday, June 16, 2014

Puffin Browser for iOS Server Side File Read Access

# Vulnerability: Puffin Browser Server Side File Read Access for iOS
# Date: 30.04.2014
# Tested on: iOS 7.0.1

# CVE: No assigned yet
# Author: Marek Zmysłowski
# http://browser-shredders.blogspot.com

1. The Puffin Browser (paid version) processing some of the web content on the server side. The vulnerability exist when the "file:///" URL is processed incorrectly, revealing the content of the server side.

2. Proof of Concept

 
4. Fix
The issue has been fixed on the server side.

5. Timeline
30.04.2014 - vulnerability reported
01.05.2014 - fix 

30.05.2014 - public disclosure

Thursday, June 12, 2014

Exploring and Exploiting iOS Web Browsers - part 1

After our Hack In The Box talk, I thought it would be a good idea to explain some of the slides in more detail. I am currently playing with iOS8 and WKWebViews, which solve a lot of issues, but not all of them. More on this soon - for now, let's stay on with UIWebViews.

UIWebView is the component used to load web content into iOS applications - basically it's Mobile Safari with the UI stripped off, leaving just the viewport part. Some of the differences:

  1. UIWebView can only view a single document at a time (+ frames)
For example, links with target="_blank" will work as target="_top", and window.open() will work   more or less the same as location.assign().

  2. There is also no UI for error events
The user will not be asked for accepting invalid SSL certificate, will not be informed the connection to the given host failed, etc. However, JavaScript-initiated alerts and prompts are shown (and are not controllable through available API).

  3. There is an API to control UIWebView content and behaviour

(By the way, you may want to take a look at this presentation from OWASP Poland meeting.)

Browsers using UIWebViews have to add the user interface - this means at least address bar and error handling. Usually to do this programmers implement UIWebViewDelegate methods:
webViewDidStartLoad:
webViewDidFinishLoad:
webView:didFailLoadWithError:

The last one causes problems usually. The most common issue is lack of address bar update within this method. This may allow an attacker to spoof the address bar by forcing some kind of an error. Apart from events like invalid SSL certificate, NXDOMAIN DNS response or simply response timeout, this method is also called when document.write() function interrupts page load or replaces loaded page.

Lack of address bar update on webView:didFailLoadWithError: was the reason for about a half of the address bar spoofing vulnerabilities we reported to browser authors. Most of the second half was due to updating address bar too early - as soon as the navigation was initiated, before the document actually started loading into UIWebView ("loading loop" from the HITB presentation is an example). By combining both techniques, an attacker can be almost sure the address bar will point to whatever she/he wishes.

See you in the next part soon.

Tuesday, June 10, 2014

Opera Coast SSL Man-in-the-Middle Vulnerability

# Vulnerability: Opera Coast SSL Man-in-the-Middle Vulenerability
# Software Link: https://itunes.apple.com/pl/app/opera-coast-web-browser/id674024845
# Vulnerable versions: 3.01 and earlier
# CVE: not yet assigned
# Author: Lukasz Pilorz
# http://browser-shredders.blogspot.com

1. Vulnerability

Opera Coast browser for iOS was vulnerable to man-in-the-middle attacks against SSL-protected web pages. The validation of the webpage certificate was performed for the domain of the main document only, skipping resources embedded from other domains.


2. Proof of Concept

https://ios.browsr-tests.com/alt/ssl.php

3. Fix
This specific issue was fixed in version 3.02.

Other potentially unfixed vectors may be related to the fact that for some cases of invalid SSL certificates for the main domain the user is alerted of an error, but the page content is still loaded in background (potentially accessing cookies or performing cache poisoning attacks). These vectors were not retested in detail.

4. Timeline


22.01.2014 - initial contact regarding SSL MITM in Coast (not this specific issue), received detailed response explaining why Opera does not consider it to be a bug
29.01.2014 - public disclosure on OWASP Poland meeting
11.03.2014 - second report with this specific issue presented (with paypal.com proof-of-concept), received immediate response confirming the bug
24.04.2014 - partially fixed version released
26.05.2014 - version 3.02 with final fix released

[CVE-2014-1315] OSX Safari uncontrolled format string

This one is for OS X Safari, so not exactly in our main field of interest, but it's really funny:
<iframe src="lets-try-format-string:%p%p%p%p%p%p..."></iframe>

CoreServicesUIAgent responsible for the format string vulnerability was fixed in OS X Mavericks 10.9.2 (Mountain Lion and previous were not affected). Exploitability was not confirmed on our side, however Apple states that it could result in arbitrary code execution. Hats off to Erik Kooistra, who reported this vulnerability independently (before I did).

[CVE-2013-7197] Yandex.Browser for iOS - Universal Cross-Site Scripting

# Vulnerability: Yandex.Browser for iOS - Universal Cross-Site Scripting
# Software Link: https://itunes.apple.com/us/app/yandex.browser/id574939428
# Vulnerable versions: 13.11-13.12
# CVE: CVE-2013-7197
# Author: Lukasz Pilorz
# http://browser-shredders.blogspot.com

1. Vulnerability

Yandex.Browser for iOS was vulnerable to Universal Cross-Site Scripting attacks, allowing a webpage to execute JavaScript on any other webpage, requiring minimal user interaction.

2. Proof of Concept

<button onclick="w=window.open('redirect.php?http://example.com');setTimeout(function(){w.document.write('<script>alert(location)</script>')},5000);">Click</button>


3. Fix

This issue was fixed in version 14.02.

4. Timeline


14.12.2013 - initial contact, multiple issues reported
27.12.2013 - Yandex response, additional data provided proving the issue is in Yandex code and not in Apple's API
10.01.2014 - Yandex confirmation and bug bounty award
24.02.2014 - version 14.02 released
30.05.2014 - public disclosure

[CVE-2013-6893] Mercury Browser for iOS - Universal Cross-Site Scripting

# Vulnerability: Mercury Browser for iOS - Universal Cross-Site Scripting
# Software Link: https://itunes.apple.com/pl/app/mercury-web-browser/id331012646
# Vulnerable versions: at least 8.1 and newer (not tested on previous versions)
# CVE: CVE-2013-6893
# Author: Lukasz Pilorz
# http://browser-shredders.blogspot.com

1. Vulnerability

Mercury Browser for iOS is vulnerable to Universal Cross-Site Scripting attacks, including the possibility to hijack passwords saved by the browser.

2. Proof of Concept

<button onclick="w=window.open('http://example.com');w.document.write('<script>alert(location)</script>');">Click</button>

3. Fix

No response from the vendor, no fix issued. The vulnerability is partially mitigated by popup blocker not allowing to open new tabs if the user does not whitelist target domain (bypassable with redirects).

4. Timeline

02.12.2013 - initial contact, no response

18.12.2013 - proof-of-concept for UXSS and password hijacking sent, no response
30.05.2014 - public disclosure