Monday, 16 July 2012

Head(er) Hunter - Beware the Misconfigured Proxy

As part of our beta testing program, we spend vast amounts of time manually poring over the traffic that flows into our tracking server. We're always looking for interesting traffic anomalies, unique signatures and in general we just find it neat to do technical deep dives on our client sites.

In a header hunting session about a week ago, we found some interesting requests, here is one of them with the incriminating stuff left out, and the other incriminating stuff snipped:

Accept: */*
Accept-Charset: *
Accept-Language: en-US
Cache-Control: no-cache
Pragma: no-cache
Referer: [SNIPPED]
User-Agent: Mozilla/5.0 (Linux; U; Android 2.3.5; en-us; ZTE-Z990G Build/GRJ22) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
x-up-calling-line-id: 1[MOBILE_NUMBER]4510

So this is interesting, a mobile customer through this particular carrier actually has their mobile number disclosed to our service (and every other site they browse to through this proxy). This should sound familiar if you follow mobile tech, as The Register wrote about this exact issue regarding O2 a UK-based carrier that was in trouble for leaking mobile customer's numbers. Read it here.

This is bad. And in this case, we disclosed this to the carrier and their security team has begun an investigation. We'll update when we hear back about the issue. This is not a new issue either, there was a presentation by Collin Mulliner (PDF) that described some of the data leaks that were occurring....four years ago! We however have a new twist on this, read on.

Hey Proxy, I Just Met You and This Is Crazy

All Carly Rae Jepsen references aside, we continued our header hunting session to see what other tidbits we could find. We soon came across some more badness, although less obvious. These were for MetroPCS and Cricket customers in the US:

Cricket Example:

GET / HTTP/1.1
Proxy-Authorization: Basic Q2xpY2tPcHRpY3MgU2F5cyBIZWxsbw==
User-Agent: Cricket-A210/1.0 UP.Browser/ (GUI) MMP/2.0
Accept-Charset: utf-8, US-ASCII, ISO-8859-1
Accept-Language: en; q=1.0, es; q=0.5
x-wap-profile: ""
Referer: [SNIPPED]
Accept: application/vnd.oma.dd+xml, application/vnd.phonecom.mmc-xml, application/vnd.wap.wmlc;type=4365, application/vnd.wap.wmlscriptc, application/vnd.wap.xhtml+xml, application/xhtml+xml;profile="", multipart/mixed, multipart/related, text/css, text/html, text/plain, text/vnd.wap.wml;type=4365, audio/mid, audio/midi, audio/x-mid, audio/x-midi, audio/qcelp, audio/vnd.qcelp, audio/mp3, audio/mpeg, audio/pmd, audio/x-pmd, audio/vnd.pmd, application/x-pmd, application/vnd.pmd, audio/evrc, application/vnd.oma.drm.message, image/bmp, image/gif, image/jpeg, image/jpg, image/png, image/vnd.wap.wbmp, image/x-up-wpng, text/css
Cache-Control: no-cache, max-age=43200
Connection: keep-alive

MetroPCS Example:

GET / HTTP/1.1
Proxy-Authorization: Basic Q2xpY2tPcHRpY3MgU2F5cyBIZWxsbyBBZ2FpbiE=
User-Agent: sam-r380 UP.Browser/ (GUI) MMP/2.0
Accept-Charset: iso-8859-1
Accept-Language: en, es
x-wap-profile: ""
Referer: [SNIPPED]
Accept: application/octet-stream, application/vnd.oma.drm.content, application/vnd.oma.drm.message, application/vnd.oma.drm.rights+wbxml, application/vnd.oma.drm.rights+xml, application/vnd.phonecom.mmc-xml, application/vnd.wap.wmlc;type=4365, application/vnd.wap.wmlscriptc, application/vnd.wap.xhtml+xml, application/xhtml+xml;profile="", image/bmp, image/gif, image/jpeg, image/png, image/vnd.wap.wbmp, image/x-up-wpng, multipart/mixed, multipart/related, text/css, text/html, text/plain, text/vnd.wap.wml;type=4365, application/x-smaf, application/vnd.smaf, audio/mid, application/, application/, application/vnd.wap.sia, application/, application/vnd.oma.dd+xml, application/vnd.oma.drm.message, application/vnd.oma.drm.rights+xml, image/bmp, image/gif, image/png, image/jpeg, image/vnd.wap.wbmp, image/x-up-wpng, text/vnd.wap.wml, text/plain, text/html, text/css
Cache-Control: max-age=43200
Connection: keep-alive

Now this doesn't look all that bad right? Except if you look a bit closer at the Proxy-Authorization header. This header is designed so that clients (i.e. your mobile phone) can sent their credentials to a proxy, and then have that proxy send the same credentials to the next proxy in the chain. So a fancy ASCII diagram would look like this:

Mobile Phone -> Credentials -> Mobile Proxy -> Credentials -> HTTP Proxy ->

Now there is nothing wrong with this, and this is how large networks can segment proxy traffic. Typically however, the next proxy in the chain has to send a Proxy-Authenticate header to request those credentials, and depending on the proxy configuration, and their ACLs (Access Control Lists) the originating proxy will either send or not send these credentials. In our case, we weren't acting as a proxy, nor do we send out a Proxy-Authenticate header, these misconfigured proxies just volunteered the information on their own. So let's break down these headers from the two requests above:


Proxy-Authorization: Basic Q2xpY2tPcHRpY3MgU2F5cyBIZWxsbw==

If we base64 decode the encoded part of the string above we get: "ClickOptics Says Hello". However, if we take the real value from the requests we trapped you get:



Proxy-Authorization: Basic Q2xpY2tPcHRpY3MgU2F5cyBIZWxsbyBBZ2FpbiE=

Again in this case you'll get: "ClickOptics Says Hello Again!". However, in the real request we get:

Implications for Click Fraud

So as always we look at how this applies to click fraud. Now because none of us wanted to break any laws, we didn't actually attempt to change any proxy settings on our phones (and we actually don't use these carriers). But under the assumption that these proxies are simply obeying a username/password style authentication scheme, it could be possible that a fraudster could harvest these credentials. Then by writing a simple Android/iPhone application, they could feed this list of credentials into the app and begin executing click fraud that would appear to be coming from multiple mobile clients.

This wouldn't prevent pure IP tracking to pick this up assuming that the proxy they exit from is the same. But we all know that you need more than just IP tracking to determine a visitor's behaviour. Also, depending on how the carrier tracks user usage, this might make it difficult for the carrier to trace back to who exactly was doing any of this nefarious business.

The other attack vector could be where a fraudster harvests these mobile numbers and stores them. Then by doing some simple math they can determine which AdSense ads would yield a higher return than the cost of sending an SMS. Then they can use a service like Twilio or any other SMS service to send out SMS messages with shortened URLs that appear to be coming from their provider ("You've Won XYZ from Carrier ABC Click Here!"). Because SMS messages have a direct cost to send (as opposed to email SPAM), folks would be pretty likely to click on them. Using a simple redirect, the unwitting mobile customer would be executing the click fraud. The redirection service could also track which mobile numbers were clicking on URLs and then re-market the SPAM to them. The unfortunate thing is that in pay-as-you-go situations, these messages will actually chew into the mobile user's budget.

Considering you can easily determine what type of phone a remote user has, sending out "Upgrade Your XYZ Phone Now" SMS messages would seem to be a pretty good attack vector as well.


Now we did try reaching out to MetroPCS and Cricket, in a variety of ways but to no avail. So we felt it was in the best interest of their customers to know that they need to enable Wifi as often as possible to avoid using these proxies until their carriers have fixed the problem. The third carrier did respond, and is actively investigating, so we'll leave them to it.

Hope you enjoyed our analysis, this is one of our first posts on some real technical behind the scenes stuff, and we hope to do more in the future!

No comments:

Post a Comment