Saturday, 12 October 2013

SQL Injection in Android Applications

A lot has been talked about the threat of SQL Injection attack for web applications but we don’t find many instances that point to the relevance of this attack in the case of mobile applications.

Aren't mobile applications prone to this attack?
The answer is yes, in this article we will see why SQL Injection flaw manifests in android applications and how can we mitigate it.
Let’s look at hybrid and browser-based applications first. A hybrid android application that loads a web application in its “webview” faces the threat of SQL injection if the application that it loads is vulnerable to it.
Consider a similar hybrid android application that loads a web portal as shown below. On launching the application it displays a web login page.



Now, if a SQL Injection flaw exists on this web page we can exploit it using this mobile interface in a similar manner as we would do it using a web browser.
Let’s see how.
We will try to enter a SQL Injection attack vector i.e. “‘ OR ‘1’ = ‘1’ #  and attempt to bypass the authentication. Here a true condition is used instead of a valid login ID in-order to manipulate the backend query and succeed it.

Woo! Observe that the attack vector succeeds and a valid login is obtained without valid credentials, as depicted in the screenshot below.

This means that the server side code that handles the login request has a SQL Injection vulnerability.

The case that we have seen here illustrates a server side SQL injection flaw that was exploited on a mobile interface. Similar flaws can exist in many “hybrid” and “browser-based” mobile application that loads the web application. This is server side SQL injection flaw.

Is this the only kind of SQL Injection flaw applicable to mobile applications?
No, there could be instances where even the native code is vulnerable to this attack. We will see the case of Android applications here.
Android application uses a light weight SQLite database and an extensive set of API provided by android SDK to process it.
A classic example of the use of SQLite database by android applications is in the case of local authentication.
Consider a case of an android application that stores the user data locally on the device and implements client-side authentication logic. Though local authentication is an insecure design in itself it has been used in this example just for the sake of illustrating the SQL Injection attack.
On launching the application it throws up a native login screen:


On successful login it takes the user to the next screen, as shown below. 

And in case the login is invalid it disallows access to the next screen and alerts the user.  


Now, consider bypassing this local authentication using SQL Injection technique?

Let’s attempt it. We will use the same attack vector that we used in the case of the server side flaw i.e. “ ‘ OR 1=1 --


  Bingo!! The application grants access to the next screen, as shown in the below screenshot. This means that the attack vector succeeded and the application got hacked.


This is client side SQL Injection flaw.
Let’s understand it in more detail.
Why did the attack occur in general?
The root cause of SQL Injection vulnerability is use of dynamic or concatenated SQL queries. If the SQL queries are constructed by concatenating user supplied inputs it leads to this flaw. The user can then supply SQL attack vectors instead of valid inputs and manipulate the backend SQL query.

What went wrong in that Android application?

Let’s look at vulnerable piece of code that led to the attack.

The authentication logic of the application is written within the “check_login” method, which fires a SQL query to authenticate the user. And the flaw lies in the way that SQL query is formed and executed.

We will see 3 different instances of the “check_login” method in order to get familiar with most of the insecure implementations that can be present in Android applications.

Insecure implementation 1: Vulnerable use of “rawQuery” method

In this implementation the “getReadableDatabase” method returns an instance of SQLiteDatabase class. And then its “rawQuery” method is used to execute the login SQL query as shown below.

Observe that the SQL query is formed in a concatenated fashion with the values of the username and password fields and the resultant string is passed as an argument to the “rawQuery” method.














As the user inputs are concatenated with the login query the SQL attack vector sent by an attacker as an input (“OR 1=1” in our case) is able to modify the backend query and yield desired results. Thus, we could bypass login authentication using a true condition.
Similarly, there is one more method of “SQLiteDatabase” class that is often use to execute SQL queries called “execSQL” that takes SQL string as an input and executes it. However it does not result any cursor values unlike “rawQuery”. Use of “execSQL” to run concatenated SQL queries will also lead to this flaw.

Mitigation:

The only fool proof way of preventing SQL Injection is the use of parameterized queries i.e. instead of using concatenated SQL queries we must use parameterized SQL queries. The parameterized queries are formed using place holders (“?”) in the place of input values wherever they are expected in the query. These place holders are then bound with the corresponding user inputs while processing it. This way the SQL query is not influenced by the input and SQL injection attack is mitigated.

But, does android provide any such API to write parameterized queries?

Yes, definitely. Observe that “rawQuery” that takes 2 arguments. The first argument takes the SQL query and the second argument is used to supply the input values that must be bound to the place holders present in the query, if the query supplied is parameterized as shown below.





So, in order to prevent SQL Injection we must write the SQL queries in a parameterized way.
And in the case of “execSQL” an overloaded method is present that takes 2 arguments, one for the query and other for the bind variables.

Make use appropriate “rawQuery” and “execSQL” methods that take bind values as input, as illustrated above.
Insecure Implementation 2: Use of concatenated SQL queries in the selection criteria.
There are some methods provided by Android APIs that offer a different way of querying the database. One of such instances is the "query" method of "SQLiteDatabase" class. Here, the table to be queries, the columns to be returned and the condition used to fetch the data (i.e. where clause condition) are taken as separate arguments. Here, even if a complete SQL query is not taken as a single argument but the chances of SQL Injection vulnerability exists. The developers usually make a mistake of adding a concatenated string in the argument related to the where clause condition leading to a SQL Injection hole as shown below.

Similar is the case with the “query” method of the “SQLiteQueryBuilder” class , as shown below:


 
















Mitigation:

Observe the method invocation snippet shown above carefully and note that the argument next to the where clause condition is set to null. However, this argument is supposed to take bind variables value in case the condition supplied is parameterized. Though the API provides a mechanism to use parameterized conditions but it does not enforce it.

Use parameterized where clause condition and pass the bind variables separately while using the "query" and all such methods like - update, delete, etc. that have similar implementations.
Insecure Implementation 3: Use of SQLStatement
This is an alternate way of executing SQL queries, here an instance of “SQLiteStatement” class is used to execute the SQL query. The SQL string is passed as an argument to "compileStatement" method which returns the instance of the SQLiteStatement class.
The SQL query is then executed by calling the execute method of the statement class.
As the “compileStatement” method takes a single argument, developers often supply a concatenated SQL query to it creating a hole for this vulnerability, as shown below.














Mitigation:
Even though “compileStatement” method takes only one argument, a parameterized query can be passed to it. And later the bind variable values can be bound to the inputs with the help of the “bindString” method.
As a thump rule always read the description of the method carefully given in the Android developer guide before using them. Most of the methods that are used to write SQL queries give an option to write parameterized queries and add bind variables. But they don’t enforce it. So be cautious about SQL Injection, use only parameterized SQL queries at all the places in the application.

Tuesday, 7 May 2013

A SDL Story


I want to put forth one of my onsite audit experiences with you. It came after successfully completing a secure code review activity for a mid-sized e-commerce company in United States. This visit was special as it laid the foundations of SDL (Secure Development Lifecycle) process in that organization.
The important goals of my visit were to:

1) Plan out a process to audit their applications on a continuous basis
2) Render some crucial secure design solutions to their design teams
3) Address any key security issue raised by the development team

To meet all my objectives I had to be in close proximity to the development teams. I had to understand their development process, internal team structures, identify key people involved in their team and interact with them. A series of meetings with module leads and design teams got me very close to their entire operational structure. The development teams had just received our initial audit report and they were busy toiling with it. On the other hand I was trying to put all the efforts to ensure that they were comfortable in implementing the corrections. Their internal security team did not understand much of the application code layout and I was the only key point of contact for their development teams to solve security related issues of the application. I was working very closely with their internal security team and had become a trusted security advisor to their development teams by then.  It was getting a very fruitful engagement for all of us day by day.

To meet my first and very important objective of planning a process for a periodic audit of their applications, I had to understand -
  • Where to look for the code changes?
  • Who makes the code changes?
  • How to understand the code changes?
  • When should the audit team start auditing the code changes?
  • Whom should the audit team present the security suggestions?
The best way for me was to dig into their SDLC process and get my hands onto their change management systems and repositories. I understood that they maintained their code changes in a tabular format in an online portal, which was called as “release grids”. I requested for an access to all of their repositories, including their release grids. I found the grids very helpful as they maintained all the code changes for any release in it. And it was something that would have been very helpful for me and my audit team. They tracked code changes in the form of tickets (an ID number for the change).

However, just having the change information would have not solved my problem. Each release had thousands of code changes including ones like minute UI modifications that do not require to be reviewed for security considerations. So my aim was to identify a way for my audit team to pick out important code changes (like important bug fixes and feature changes) from the vast pool of changes for any release. I knew that this step was important as manually reading the grids would be tough and would result in unnecessary wastage of time during periodic audits. Moreover, for any 3rd party auditor to understand the terminology used by the development teams and identify the code changes would have been cumbersome. On pondering on this point I concluded that the best solution for this problem was to integrate security audits in their development process. And this initiative then marked a need to establish a secure SDLC there.

At that time to my revelation even their management teams were taking efforts to streamline their development process. Their main challenges areas included:

1)       Establishing correlation between development teams of different modules
2)      Bringing accountability in code checkout (there was no authorization work flow in place at that point of time)
Looking at the momentum generated within their teams to revamp the development process even I approached them with my notion of integrating development process and security reviews. I highlighted my problem areas and proposed an integrated secure development process for them. I presented my plan on the following grounds:
1)      Need to integrate with the development process – To give an ongoing security support to their application, the audit team should be able :
a.       Know when the ticket (ID for a code change) is initiated – Requirement Phase
b.      Understand the proposed change for the ticket – Design Phase
c.      Suggest security requirement for the change – Development Phase
d.      Perform overall review and give our inputs – QA Phase
I explained them the importance of this integration and showcased a need to adapt a secure development approach and work flow within their team.
2)      Build adaptable and centralized security solutions - As per my observation as the application design was complex, incorporating a security requirement at the end of the development was tedious. It was leading to extra efforts to the design and development teams. Hence, there was a need for the security auditors to work closely during the end to end development of the feature and give the security suggestions wherever needed.
3)      Build a strong security knowledge base – I highlighted a need to develop application specific security best practices to waive out repetitive errors.
4)      Mandate Security Reviews - As per my observation in the current SDLC the security reviews were being carried out randomly and in order to bring overall security of the application it was crucial to review every important code change.
The management was all thrilled and impressed with this initiative and was eager to kick-off this new secure development process. They wanted me to guide them in putting this whole thing in action within their teams. This was a novel and exciting experience for me too; I was now venturing into putting my ideas to practice. However, as they say challenges never end, the next big road block for waiting for me. The internal teams knew less about security and making them adapt to this practice seemed like a challenge. The best solution to this problem was to spread security awareness to all their internal teams and make them understand security vulnerabilities and best practices. However, though the plan was good but it didn’t seem to be doable quickly. The management on the other hand insisted on having an immediate phase out of the integrated development process. On further brainstorming I came to a conclusion of building a repository of all security requirements/practices that the design and development teams could follow.

With my knowledge of the applications I could build:
1)       Overall secure best practices and guidelines for the applications
2)      List of possible and predictable feature changes in their key applications and their corresponding security requirements.
The management for very receptive to this unique and suitable documentation and decide to launch the secure SDLC process with it. Thus the security requirements became a part of their development specs and showed up in their release grids.
I was very happy about the whole activity as my efforts could bring security more close to the development team in an organization and help change their perception towards security.

Though SDL requires a great amount of discipline and coordination across different team and it must be done diligently to get a secure output at the end. SDL is a wonderful concept and more and more organizations must step towards it J

Sunday, 10 March 2013

Cracking Authorization Logic in Android

With increase in the demand of mobile applications we can see a variety of applications in the market. Also businesses now-a-days prefer to make complex functionality available to the user through the medium of mobile applications. As the nature of applications get complex their implementation and design too gets complicated. And in applications that require authorization or in other words role based access controls the chances for design flaws to exist are prominent. I came across one such insecure implementation that I have demonstrated below. 

 Here, the logic to determine access to different features of the application is dependent on a configuration file that comes shipped with the application bundle i.e. apk file. 

 We will see how to crack it and gain access to features that are hidden or forbidden to the user. 

The initial screen that appears to the user when we start the application is shown below.






















Now the user logs in to the application. This being a hybrid application it makes a call to the web server and authenticates the user.






















Once the login is successful the user is given access to the application. Note that the user – “Bob” is able to access to ONLY 2 features of the application viz. Funds transfer and View History.





















However, Bob is aware that other uses of the same application get access to more than 2 features after login. Well, they could be some privileged users of the application. But, Bob is not happy with it. He somehow wants access to all the features of the application and he decides to crack it.

He uses a tool called – “apktool”, which is a reverse engineering tool for android and tries to unpack the “.apk” file. The steps are really simple, go to the directory where you have “apktool” and type “apktook d <name of the apk file to be unpacked> <name of directory to place the contents>”












Once the command is executed it unpacks the application in the specified directory – “Decompiled” in this case.

















The unpacked directory is shown below, observe that it gives access to the entire “res” (i.e. resource) directory of the application.




























Bob is happy to see that and he continues to browses the contents within the “res” directory. To his surprise he observes that there is a file named – “accessdata.xml” that has something like names of different menus and their status as “ON” or “OFF”. He has found a treasure here :) This could probably be the access control configuration.



































He observes that the menus to which he has access are marked as “ON” and the other menu is kept as “OFF”. He changes the 3rd menu to ON and saves the file.

































He recompiles the file using the same apktool, as below. This time he uses the mode “b” of the apktool.














Bob now has a recompiled application with a new access control configuration. But can he install this “apk” file in this device? 

No, with the process of recompilation he has lost of developer signature. He wonders how to resolve this issue until he figures out a tool called “SignApk”.

He signs the application with “SignApk” using the following command. It is pretty straightforward; all you need to do it use the command below and specify a new name for the apk file, “MyBankSigned.apk” as in this case.








The signed apk is shown below.


















Bob firsts uninstalls the application that he already has.





















And excitedly installs his new apk into the device using “adb”.












Now, Bob logins into the application.





















Bingo!!! He gets access to the 3rd Menu, which is not authorized to access.





















Bob can now proceed to create new account in the system.

Why did Bob succeed? 

This is because the application had insecure access control logic. It relied on some configuration files and took access control decision based on it.

Observe that the “MenuDisplay” activity that loads after successful login loads the configuration from the raw file.  



























The configurations i.e. “item and value” pairs are picked from the xml file (accessdata.xml) and stored it in a “menuconfig” object.





















Depending on the value obtained from the configuration file the menus are either made visible or disabled for the user.

























This leaves a big hole in the application that the users can easily change the values of the configuration file which is in clear text and alter the functionality of the application.

Thus, applications that make use of clear text values from configurations files, database, and preference files are all subject to such attacks.

So what is the solution for this problem?

Create different “apk” files for different user types/roles and distribute it to the users. Every user who belongs to a particular user type will then get a specific apk file that has no logic to make any access control decision. And then there will be no scope for the user can to manipulate any value stored in any file to influence the functionality of the application.

If the above solution is NOT feasible following technique can be used.

For Online Access -
(This applicable for application that can make a call to the web server.)

A) Instead of fetching the access rights information locally, fetch it from the remote server and load the menu controls based on the server response.
B) To maintain data integrity, create a checksum of the access right information at server and send it along with response.
C) Validate the checksum at the client end before loading the menu controls

For Offline Access –
(This applicable for application that does not make call to the web server.)  

A) Store the access rights information in an encrypted format in the database/files.
B) To maintain data integrity, create a checksum of the access right information and save it separately in the file.
C) Validate the checksum before loading the menu controls based on the flags.