Android security testing

基础知识

Android 基本机构

  • 安卓分4层吧,底层为linux,上层是安卓本地库,主要为C或者C++,有sqllite,webkit (The Webkit rendering engine was used prior to Android version 4.4 to load these web pages. On the latest versions (after 4.4) of Android, it is done using Chromium) 之类的东西,通过安卓应用程序框架展示为程序员,同时这一层还有安卓运行时,以核心java和Dalvik虚拟机,再上面就是应用程序与框架,程序员使用此框架API开发更加复杂的应用程序

Android app 包结构

  • AndroidManifest.xml:

The AndroidManifest.xml file is the control file that tells the system what to do with all the top-level components (specifically activities, services, broadcast receivers, and content providers described below) in an application. This also specifies which permissions are required. This file may be in Android binary XML that can be converted into human-readable plaintext XML with tools such as android-apktool, or Androguard which we will cover in the upcoming post.

  • META-INF directory:

    • MANIFEST.MF: the Manifest File
    • CERT.RSA: The certificate of the application.
    • CERT.SF: The list of resources and SHA-1 digest of the corresponding lines in the MANIFEST.MF file.
  • lib: the directory containing the compiled code that is specific to a software layer of a processor, the directory is split into more directories within it:

    • armeabi: compiled code for all ARM based processors only
    • armeabi-v7a: compiled code for all ARMv7 and above based processors only
    • x86: compiled code for X86
    • mips: compiled code for MIPS processors only
  • res: the directory containing resources not compiled into resources.arsc (see below).

  • assets: a directory containing applications assets, which can be retrieved by AssetManager.

  • classes.dex: The classes compiled in the dex file format understandable by the Dalvik virtual machine

  • resources.arsc: a file containing precompiled resources, such as binary XML for example

How to root or install a custom Rom in your device:

  • unlock bootloader
  • Installing recovery softwares like TWRP or CF
  • Installing the Super Su app.
  • Flashing the custom ROM to the phone.

What happens when an app is run?

When the Android Operating System boots, a process called Zygote is started and
it listens for new app launch requests. Whenever a user clicks on an application, Zygote is used to launch it. Zygote creates a copy of itself using a fork system call when it receives a request to launch a new app. This process of launching a new app is considered more ef cient and faster. The newly launched app process loads all the code that is required for it to run. What we read earlier is that the classes. dex le contains all the byte code compatible with Dalvik Virtual Machine. In the latest version of Android devices starting from Android 5.0, the default runtime environment is ART. In this new runtime environment, the classes.dex le will be converted into something called OAT using a tool called dex2oat.

Sandbox

In the traditional linux system, we are able to see both the processes under the same User ID.
Now, it’s not true in the case of Android app. Every single app installed on your device will have a separate User ID (UID). This ensures that each application and its resources are being sand-boxed and will not be accessible to any other application.
Note: Applications signed with the same key (it is possible if two apps are developed by the same developer), can access each other’s data.
If you notice the le permissions in the preceding output, each application’s directory is owned by itself and they are not readable/writeable by other users.

SSL certificate pinning

  • 一些有用的参考:
    refer link
    refer link
    refer link
    offical link

  • 使用HttpURLConnection
    首先,获取访问地址的URL对象;
    然后,利用该url实例的openConnection()方法获取HttpURLConnection实例;
    之后,利用HttpURLConnection实例,可以设置HTTP请求所使用的方法,主要有两种,GET和POST,分别是请求数据和提交数据;
    之后,可以进行一些自由的设置,比如设置连接超时时间、请求超时时间等;
    最后,调用getInputStream()方法即可获得服务器传输过来的输入流了。可以对该输入流进行读取。
    读取完之后,需要关闭HTTP连接,调用disconnect()方法。

String result = null;
HttpURLConnection urlConnection =null;
try {
URL requestedUrl = new URL(url);
urlConnection = (HttpURLConnection)requestedUrl.openConnection();
if(urlConnection instanceof HttpsURLConnection) {
((HttpsURLConnection)urlConnection).setSSLSocketFactory(sslContext.getSocketFactory());
}
urlConnection.setRequestMethod("GET");
urlConnection.setConnectTimeout(1500);
urlConnection.setReadTimeout(1500);
lastResponseCode = urlConnection.getResponseCode();
result = IOUtil.readFully(urlConnection.getInputStream());
lastContentType = urlConnection.getContentType();
} catch (Exception ex) {
result = ex.toString();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
}

但我们的证书是自签名的,这意味着SSLContext中默认的TrustManager是不会信任服务端证书的,并且也无法达成SSL连接。
如果你尝试着在网络上搜索如何实现自信任证书的HTTPS连接,可能会得到很多错误的建议,绝大多数的答案都是教给开发者直接信任任何证书就可以了。这当然算是一个误导了,也是不安全的,因为这样做会有被中间人攻击[译注1]的风险。
我们真正想做的是创建一个自定义的TrustManager,这个TrustManager可以信任我们的自签名证书,并且能被我们的自定义SSLContext使用.因此我们需要一份服务端证书链的副本,这个副本必须包括CA的自签名证书,至少也是CA签署的中级证书。如果你正常地导出服务器的证书,你会得到一个文件,这个文件包含有三个证书- CA认证的证书,中级证书和服务器的证书。这是OK的,额外的证书不是必须的,但也不会有坏处

  • 如何使用HttpsURLConnection

我们把证书装载到KeyStore中,使用KeyStore来生成一个TrustManger的数组,然后使用这些TrustManager来创建SSLContext。

Test methodology

1 利用Qark,Mobsf等综合性扫描软件对APP进行一次全面扫描

2 利用Burp等工具分析应用数据,检查certificate pinning和各种传输问题和服务器端问题,例如session,xss,injection,logic flow等

With SSL pinning, it is assumed that the app knows which servers it communicates with. We take the SSL certificate of this server and add it to the application. Now the application doesn’t need to rely on the device’s trust store, rather it makes its own checks verifying if it is communicating with the server whose certificate is already stored inside this application(看机制,不一定存在本地,可能从远处下载). This is how SSL pinning works.

3 检查手机data/data目录各种存储数据,看看有没有敏感数据,再检查unintend数据泄露问题

• Shared preferences
• SQLite databases
• Internal storage
• External storage

Example Scenarios for Unintended Data Leakage

Leaking content providers
Copy/paste buffer caching
Logging adb logcat > output.txt
URL caching
Browser cookie objects
Analytics data sent to third parties

4 使用Drozer检查攻击面,重点查看四大组件各种export,进行各种扫描,检查有无注入,目录遍历等漏洞

- Listing out all the modules : dz> list
- Retrieving package information : dz> run app.package.list
- Finding out the package name of your target application : dz> run app.package.list --filter **notes**
- Getting information about a package : dz> run app.package.info -a **com.sonyericsson.notes**
- Dumping the AndroidManifes.xml file : dz> run app.package.manifest **com.sonyericsson.notes**
- Finding out the attack surface : dz> run app.package.attacksurface **com.sonyericsson.notes**
dz> run app.package.attacksurface **org.owasp.goatdroid.fourgoats**

- Attacks on activities : dz> run app.service.info -a org.owasp.goatdroid.fourgoats -u
dz> run app.activity.start --component org.owasp.goatdroid.fourgoats org.
owasp.goatdroid.fourgoats.activities.ViewProfile

- Attacks on services : dz> run app.service.info -a org.owasp.goatdroid.fourgoats
dz> run app.service.start --component org.owasp.goatdroid.fourgoats org.
owasp.goatdroid.fourgoats.services.LocationService

- Attacks on broadcast receivers : dz> run app.broadcast.info -a org.owasp.goatdroid.fourgoats

- Running the following command will tell us if there are any injection vulnerabilities in the content providers:
dz> run scanner.provider.injection -a com.sonyericsson.notes

- Path traversal attacks in content providers : dz> run scanner.provider.traversal -a **com.adobe.reader**
dz> run app.provider.read content://com.adobe.reader.fileprovider/../../../../etc/hosts

5 使用各种hook工具进行动态测试

  • Xposed
  • Cydia
  • Frida
  • Magisk v8 (systemless) 「解鎖 -> 安裝 Magisk -> 安裝 Systemless phh’s SuperUser -> 安裝 Systemless Xposed -> 重新上鎖」
    Frida 和 Xposed 都是非常出色的框架,后面会增加一些相关博文

6 Root Dectection (systemless root)

  • 可以使用xposed或者Magisk去bypass root checking

  • Superuser.apk is the most common package many apps look for in root detection. This application allows other applications to run as root on the device.

  • Many applications look for applications with specific package names. An example is show below.

  • There are some specific applications which run only on rooted devices. Checking for those applications would also be a good idea to detect if the device is rooted.
    Example: Busybox.

  • Executing “su” and “id” commands and looking at the UID to see if it is root.

  • Checking the BUILD tag for test-keys: This check is generally to see if the device is running with a custom ROM. By default, Google gives ‘release-keys’ as its tag for stock ROMs. If it is something like “test-keys”, then it is most likely built with a custom ROM.

7 关于Debug

JDB is a Java debugger, a simple command line debugger for Java classes. It comes preinstalled with JDK.如果是native开发,要用gdb

Refer link

Checking for Vulnerability

In fact, this is the easiest part of the entire article.

  1. Decompile the application using APKTOOL to get the AndroidManifest.xml file using the following command.

apktool d vulnerableapp.apk

  1. Inspect Androidmanifest.xml file for the following line.

android:debuggable=”true”

If you find the above line in the AndroidManifest.xml file, the application is debuggable and it can be exploited.

8 Backup techniques

Now let’s use the backup technique of android to find security issues by following these steps:

  1. Backup the app data using the adb backup command.
    adb backup –f backup.ab com.whatsapplock
  2. Convert the .ab format to the .tar format using the android backup extractor.
    Android backup extractor, to convert our .ab le into .tar format.
    C:\backup>java -jar abe.jar -debug unpack backup.ab backup.tar
  3. Extract the TAR file using the pax or star utility.
  4. Analyze the extracted content from the previous step for security issues.

How to protect our apps

If your app holds sensitive data, you can stop allowing users from making a backup of the app. This can be done by placing the following line in the AndroidManifest.xml file

android:allowBackup=”false”

9 检查webview相关问题

Refer link

As mentioned in the beginning, WebView supports usage of JavaScript. If the application being loaded into WebView requires JavaScript support, it can be enabled by using the following line.

WebView webview = (WebView) findViewById(R.id.mywebview);

WebSettings webSettings = myWebView.getSettings();

webSettings.setJavaScriptEnabled(true);

Another powerful feature in WebView is exposing a Java object’s methods to be accessed from JavaScript.

This is one of the important features which requires a keen eye when implementing, as it can be exploited by passing malicious JavaScript to the application’s interface.

Below is a sample code snippet by @jduck on how it can be implemented and exploited.

https://github.com/jduck/VulnWebView/