Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Taint analysis for Android Java code #2390

Merged
merged 9 commits into from
Aug 19, 2023
75 changes: 75 additions & 0 deletions Document/0x05c-Reverse-Engineering-and-Tampering.md
Original file line number Diff line number Diff line change
Expand Up @@ -1272,6 +1272,81 @@ Now you can run the validate binary in your Android device to verify the solutio

To conclude, learning symbolic execution might look a bit intimidating at first, as it requires deep understanding and extensive practice. However, the effort is justified considering the valuable time it can save in contrast to analyzing complex disassembled instructions manually. Typically you'd use hybrid techniques, as in the above example, where we performed manual analysis of the disassembled code to provide the correct criteria to the symbolic execution engine. Please refer to the iOS chapter for more examples on Angr usage.

### Taint Analysis

Taint analysis is an information flow analysis technique that tracks the flow of sensitive information within a program. For example, it can determine whether geolocation data collected in an Android app is being transmitted to third-party domains.

In taint analysis, data flows from a "source" to a "sink". A source is where sensitive information originates, and a sink is where this information is ultimately utilized. For instance, we can determine if the device ID retrieved by a `getDeviceId()` function is transmitted as a text message via another function `sendTextMessage()`. In this scenario, `getDeviceId()` is the source, and `sendTextMessage()` is the sink. If a direct path exists between them, it's called a _leak_.

In large applications, manual information flow analysis can be very time consuming and inaccurate. Taint analysis automates this, with two main methods: static and dynamic. The former examines code without running it, offering broad coverage but potentially yielding false positives. In contrast, dynamic analysis observes real-time application execution, providing actual context but possibly overlooking untriggered issues. A thorough comparison of these techniques is beyond this section's scope.

There are multiple tools which perform taint analysis on native code, including [Triton](https://github.com/jonathansalwan/Triton "Triton") and [bincat](https://github.com/airbus-seclab/bincat "bincat"). However, in this section, we'll primarily focus on Android Java code and utilize [FlowDroid](https://github.com/secure-software-engineering/FlowDroid "FlowDroid") for the taint analysis. Another notable tool supporting taint analysis for Android apps is [GDA](https://github.com/charles2gan/GDA-android-reversing-Tool/wiki/GDA-Static-Taint-Analysis "GDA").

FlowDroid is an open-source tool based in [soot](https://github.com/soot-oss/soot "soot"), a framework dedicated to analyzing and translating Java bytecode for easier analysis. The tool handles the nuances of Android app lifecycles (like `onCreate`, `onStart`, `onPause`, and others) and its UI components during analysis and performs taint analysis that is:

- **Context-sensitive**: Distinguishing between calls to the same method based on their specific execution contexts.
- **Object-sensitive**: Identifying individual objects, even when they're of the same class.
- **Flow-sensitive**: Recognizing the sequential order of code execution.

FlowDroid tool is versatile and can be used in two ways: as a standalone command line tool for quick analyses or as a library for more complex investigations. For our demonstration, we'll utilize the command line tool to perform taint analysis on the [InsecureShop v1.0]( https://github.com/hax0rgb/InsecureShop/releases/tag/v1.0 "InsecureShop") application.
cpholguera marked this conversation as resolved.
Show resolved Hide resolved

The InsecureShop app accepts a username and password as input and stores them in the app's shared preferences. In our taint analysis, we're interested in how this stored username and password are used. In this context, the username and password are the sensitive information, and reading from shared preferences is the source. The sink in this analysis could be various operations, such as sending info over the network, transmitting info via an `Intent`, or storing info in an external file.

To use FlowDroid, firstly, we need to provide an input list of potential sources and sinks to evaluate for. In our case, _reading from shared preferences_ will be the source, while _adding parameters to an `Intent`_ will be the sink. The configuration file will look as follows (we'll name it "source_sink.txt"):

```Jimple
<android.content.SharedPreferences: java.lang.String getString(java.lang.String, java.lang.String)> -> _SOURCE_

<android.content.Intent: android.content.Intent putExtra(java.lang.String,java.lang.CharSequence)> -> _SINK_
<android.content.Intent: android.content.Intent putExtra(java.lang.String,char)> -> _SINK_
<android.content.Intent: android.content.Intent putExtra(java.lang.String,java.lang.String)> -> _SINK_
```

To invoke FlowDroid via the command line, use the following command:

```shell
java -jar soot-infoflow-cmd/target/soot-infoflow-cmd-jar-with-dependencies.jar \
-a InsecureShop.apk \
-p Android/Sdk/platforms \
-s source_sink.txt


[main] INFO soot.jimple.infoflow.android.SetupApplication$InPlaceInfoflow - The sink virtualinvoke r2.<android.content.Intent: android.content.Intent putExtra(java.lang.String,java.lang.String)>("password", $r5) in method <com.insecureshop.AboutUsActivity: void onSendData(android.view.View)> was called with values from the following sources:

[main] INFO soot.jimple.infoflow.android.SetupApplication$InPlaceInfoflow - - $r1 = interfaceinvoke $r2.<android.content.SharedPreferences: java.lang.String getString(java.lang.String,java.lang.String)>("password", "") in method <com.insecureshop.util.Prefs: java.lang.String getPassword()>

...

[main] INFO soot.jimple.infoflow.android.SetupApplication$InPlaceInfoflow - The sink virtualinvoke r2.<android.content.Intent: android.content.Intent putExtra(java.lang.String,java.lang.String)>("username", $r4) in method <com.insecureshop.AboutUsActivity: void onSendData(android.view.View)> was called with values from the following sources:

[main] INFO soot.jimple.infoflow.android.SetupApplication$InPlaceInfoflow - - $r1 = interfaceinvoke $r2.<android.content.SharedPreferences: java.lang.String getString(java.lang.String,java.lang.String)>("username", "") in method <com.insecureshop.util.Prefs: java.lang.String getUsername()>

...

[main] INFO soot.jimple.infoflow.android.SetupApplication - Found 2 leaks
```

The output also uses the [jimple intermediate representation](https://www.sable.mcgill.ca/soot/doc/soot/jimple/Jimple.html "Jimple") and reveals two leaks in the application, each corresponding to the username and password. Given that the InsecureShop app is open-source, we can refer to its source code to validate the findings, as shown below:

```java
// file: AboutActivity.kt

fun onSendData(view: View) {
val userName = Prefs.username!!
val password = Prefs.password!!

val intent = Intent("com.insecureshop.action.BROADCAST")
intent.putExtra("username", userName)
intent.putExtra("password", password)
sendBroadcast(intent)

textView.text = "InsecureShop is an intentionally designed vulnerable android app built in Kotlin."

}
```
cpholguera marked this conversation as resolved.
Show resolved Hide resolved

FlowDroid is not only versatile in performing taint analysis but can also generate call graphs, as illustrated in [this blog post](https://medium.com/geekculture/generating-call-graphs-in-android-using-flowdroid-pointsto-analysis-7b2e296e6697) by Navid Salehnamadi. Taint analysis is especially beneficial for automating data flow analysis in intricate applications. However, given the complexity of some apps, the accuracy of such tools can vary. Thus, it's essential for reviewers to find a balance between the accuracy of tools and the time spent on manual analysis.

## Tampering and Runtime Instrumentation

First, we'll look at some simple ways to modify and instrument mobile apps. _Tampering_ means making patches or runtime changes to the app to affect its behavior. For example, you may want to deactivate SSL pinning or binary protections that hinder the testing process. _Runtime Instrumentation_ encompasses adding hooks and runtime patches to observe the app's behavior. In mobile application security however, the term loosely refers to all kinds of runtime manipulation, including overriding methods to change behavior.
Expand Down