Middling HTTPS on iOS

Take a look at the following screen capture. There is a lock indicating that this is a "secure" browser session, however, as shown by the presence of an alert displaying the HTTPS cookie, the HTTPS browsing session has been hijacked. Markup of choice including JavaScript can be rendered and executed within the security origin of the site being targeted:

Now lets look at this simple attack example. When a request was made to https://www.wellsfargo.com, the following clear-text CONNECT request was sent by the browser, waiting to be intercepted:

CONNECT www.wellsfargo.com:443 HTTP/1.1

Host: www.wellsfargo.com

User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13D15 Safari/601.1

Connection: keep-alive

Proxy-Connection: keep-alive

Ordinarily this would have gone to the proxy server configured by the host; however, on this network a transparent intercepting proxy is capturing select CONNECT requests and instead of starting the handshake, responds with a 407 proxy authentication required:

HTTP/1.0 407 Proxy Authentication Required

Content-Type: text/html

Connection: keep-alive



<html>

<!-- attack payload of choice

executed within the security realm

of the site I'm targeting



Anything goes so I'll just show the

user their cookie and a picture of

my cat-->

<script>alert('Here is your HTTPS cookie: '+document.cookie)</script>

<img src="http://pwnprinter.com/storage/cache/images/000/016/DSC02535,medium_large.1438139480.jpg" height=800 width=1200>

...



Now if you read RFC 7235 you'll notice there's something missing in the response above, the proxy-authenticate header which typically looks something like this:

Proxy-Authenticate: Basic realm="Some Proxy"

Removing the header is done to avoid displaying an authentication dialog to the user which could tip them off that something is seriously wrong. As you've likely figured out by now, the contents of "407 Proxy Authentication Required" responses must never be rendered by the browser, especially within the secure same origin of an HTTPS site but that's exactly what happened here.

If you were paying attention above you'll note I mentioned that the intercepting proxy was looking for select CONNECTs to a particular server. This is to ensure that a trust relationship is already established by the browser so that the lock is displayed to the user in Safari, Opera, or any other browser in iOS using WebKit. If trust is not previously established the address bar will show HTTPS:// but no lock. Any markup and JavaScript payload of choice will then be executed within the security context of the HTTPS site the user is visiting with full rights to DOM security for that site. As an example, a user might visit https://www.wellsfargo.com and the attacker targets the second CONNECT request to wwww.wellsfargo.com knowing it will be for a bit of JavaScript which they replace with their own payload in the body of the 407 response. An attacker may also target responses for advertising or metrics scripts so that they don't need any previous knowledge of site delivered assets.

Why would this possibly work?

On iOS, WebKit renders the markup provided in a "407 Proxy Authentication Required." This allows a proxy server that requires authentication to give the user a soft-error after a certain number of failed authentication attempts, but because the contents of the HTTP response are rendered within a trust realm, it can be used to attack cryptography trust in WebKit.

How bad could this be?

This represents a complete failure in trust before a secure handshake and connection can even be established. As can be seen by the document.cookie alert, the attacker has full access to the target site trust in the DOM. At this point it becomes easy to steal sessions not protected with the HTTPOnly flag and in fact proxy the entire contents of a site through this vector so that the victim believes they are browsing the site they intended to visit, unknowingly having all of what they believed to be secure communication intercepted all with the lock and https:// still in the address bar. Imagine visiting your bank over HTTPS where you are asked to enter your credit-card information to validate your account. Not only would an attacker be able to steal your authentication credentials and session cookie for your bank so they can access your account, but they could further lever their attack to get your credit-card details. If leveraged against a political activist this attack could reveal their identity and be used in combination with other attacks to compromise their device.

How can this be tested?

It is relatively simple to test for this vulnerability using an intercepting proxy like The Fiddler which supports CONNECT interception. A bit of FiddlerScript after the OnBeforeResponse function is all that is needed:

if (oSession.HTTPMethodIs("CONNECT") && (oSession.PathAndQuery == "target.site.com:443")) {

var oBody = "payload of choice goes here";



oSession.utilSetResponseBody(oBody);

oSession.oResponse.headers.HTTPResponseCode = 407;

oSession.oResponse.headers.HTTPResponseStatus = "407 Proxy Authentication Required";}