...stuff I do and things I like...

Tuesday, November 08 2016

iOS WebView auto dialer bug

TL;DR: iOS WebViews can be used to automatically call an attacker controlled phone number. The attack can block the phone's UI for a short amount of time and therefore prevent the victim from canceling the call. The bug is an application bug that likely is due to bad OS/framework defaults. One major issue with this vulnerability is that it is really easy to exploit. App developers have to fix their code as soon as possible. The Twitter and LinkedIn iOS apps are vulnerable (other apps might be vulnerable too). Demo videos here: Twitter and LinkedIn (embedded videos are below on this page).

About a week ago (on a Friday) I read an news post [1,2] about a guy who got arrested for accidentally DoSing 911 by creating a web page that automatically dialed 911 when visited it from an iPhone. This was most likely due to a bug with the handling of TEL URI [4,5]. I immediately thought about a bug I reported to Apple in late October 2008 [3]. I couldn't believe this bug has resurfaced so I investigated. The article said something about posting links on Twitter.
    If you think automatically dialing a phone number after clicking a link in an app is not a big issue think again. DoSing 911 is pretty terrible but there are other examples such as expensive 900 numbers where the attacker can actually make money. A stalker can make his victim dial his phone number so he gets his victim's number. Altogether things you don't want to happen.
Anyway ... I went and looked at the iOS Twitter app. I got a very simple auto phone dialer working in a very short time. I was happy and also devastated that it was that easy. I first thought I reproduced the exact bug but later after re-reading the articles [1,2] more carefully I determined that it is likely a different bug or at least a different trigger. The article reported heavy use of JavaScript and pop-ups being shown and such. My original trigger was one line of HTML (a meta-refresh tag that points to a TEL URL) due to this I decided to report the bug to Twitter via their Bug Bounty program on HackerOne. I never reported to a bug bounty program before so I was happy to gain some experience (I normally report via security@), but it is 2016 and companies pay for bugs so here we go. Twitter acknowledged that it looks like a problem within a few days.
    On Nov. 6th I updated the bug report to Twitter to add the UI blocking issue (continue reading) and uploaded a video. Today Twitter simply closes the bug as a duplicate without any comment. While this might be a simple duplicate they should have an interest in playing nice and being thankful to those who report bugs they find in their spare time. Because of this action I decided to post the full details of the issue today.

During the weekend I took some time to further investigate the issue. I determined that this might be a general issue with iOS apps the use WebViews to display content. I tested a few popular apps I had installed. Vulnerable apps need a way for users to post web links that will be opened in a WebView inside the app itself. Apps that open links in mobile Safari or Chrome would not be vulnerable (I tested this). One app I tested fairly early was the LinkedIn app since LinkedIn basically is social media for the business context. People can send messages and post updates. Updates usually are text and link. I posted a link and clicked it and yes it dialed my other phone (demo video below).

I wanted to submit the bug to LinkedIn and found that they have a bug bounty program. Unfortunately it was a private bounty and you would only be added if you previously submitted bugs. I tried to get around it but it didn't work. After some thinking I decided to not report it to LinkedIn privately but openly (parallel to this blog post). It is 2016 after all and if they don't want to add me to their program that is their choice. In general I will likely not report bugs outside of a bug bounty program if a private bug bounty program exists.

Another weekend comes I have some time and started playing with the bug again. Actually I started looking at my PoC from 2008 while trying to figure out if I report the bug to LinkedIn or not. After playing around for a bit I more or less get my old PoC working with the Twitter and LinkedIn apps. WOW!

Taking one step backwards. The original bug I reported to Twitter was triggering a phone call by visiting a website that redirect to a TEL URL. One could do this with various techniques such as: http-meta refresh, iframe, setting document.location, window.location, or an HTTP redirect (Location header). This would simply dial a number. The victim would see the dialer and the target number on the screen and of course could just cancel the call by pressing the big red button. Just causing the call is already bad since an unobservant person will be baffled (why is my phone dialing some number).

The beauty of my 2008 bug was that I could block the phone's UI for a few seconds and therefore prevent the user from canceling the call. I managed to abuse exactly the same trick to block the UI that I used in 2008. The trick is to cause the OS to open a second application while the phone is dialing the given number. Opening applications is pretty straight forward, you open a URL that causes the OS to spawn another application. This can be anything from the messages app (via the SMS: URL) or iTunes (via the itms-apps: URL). You can pretty much get any application to launch that has a URI binding. In 2008 I used a SMS URL with a really really long phone number to block the UI thread. My best guess on how this works is that the IPC subsystem actually has difficulties to move several kilobytes of URL data through the various layers into the app and the target app might also not be super happy about really large URLs. I ended-up with the code below. The code uses the combination of meta-refresh tag and window.location to execute the attack. The codes delays setting the window.location by 1.3 seconds to guarantee that the dialer is executed first. The delay cannot be too long otherwise the WebView will not execute the URL handler for launching the messages app. Basically you have to get the timing just right.

The PoC to trigger this bug.

Below two video demonstrations of this attack. You can clearly see that the UI is not responsive for a short amount of time. The time is long enough to make somebody pickup on the other side (especially service hot lines automatically pickup).

Normal good app behavior:
Apps should normally check the URL schema before executing it and show the user a pop-up dialog before executing an app on the device. Some examples are shown below:

Mobile Safari asking before calling the Apple Support number. This is how good apps should behave!

Dropbox showing a warning but not showing the target number. Ok but could be better.

The Yelp app normally behaves like Safari but if you hit it with an HTTP redirect it does not show the target number. I just included this for the fun of it.

App developers should review their use of WebViews to determine if they are vulnerable to this attack. Vulnerable apps need to be fixed. Service providers like Twitter and LinkedIn can inspect links posted to their sites for containing malicious code and prevent those links from being posted to their service.

Apple should change the default behavior of WebViews to exclude execution of TEL URIs and make it an explicit feature to avoid this kind of issues in the future. I reported this issue to Apple.