Analyzing an Android App With Docker and Androguard
Posted by David Weinstein
TL;DR
Have you wanted to get into analyzing Android apps—for vulnerabilities,
malware, or just for fun? Maybe you’ve experienced problems getting an
environment setup because of complex tool dependencies, long READMEs, or just
never really knew where to get started? This article can help. Using docker I
can show you how to tear apart your first Android application, and maybe even
find some vulnerabilities while you’re at it.
Dependencies
I assume you have a working docker setup. If you aren’t sure how to set it up
on your platform, try following one of these
guides.
Download the repo
First check out the code from
github by running git
clone [email protected]:dweinstein/dockerfile-androguard.git or git clone
https://github.com/dweinstein/dockerfile-androguard.git.
This repo uses a Dockerfile to declare all the dependencies that you would
need if you were going to install the
Androguard tool your self. If you want
to know how to do it all manually, you can
see for yourself.
Build
After cloning the repository, cd into the directory and you should see something like this:
12
➜ dockerfile-androguard git:(master) ls
Dockerfile Makefile README.md data-container
You can build by doing a make build
Run
Once built, you have all you need to start analyzing your first app. I even put
an app in the repository for you to have something to play with right away! Just do a make run
and you should get something like this:
12345678910111213141516171819202122232425262728
➜ dockerfile-androguard git:(master) make run
make -C data-container build
docker build -t androguard-data .
Uploading context 133.1 kB
Uploading context
Step 0 : FROM busybox
---> 769b9341d937
Step 1 : ADD apks /apks
---> Using cache
---> 595c1e66e01f
Step 2 : VOLUME ["/apks"]
---> Using cache
---> 7d40787633a5
Step 3 : VOLUME ["/notes"]
---> Using cache
---> c0dc7db54a78
Step 4 : CMD ["/bin/true"]
---> Using cache
---> 845911656aad
Successfully built 845911656aad
make -C data-container run
docker run --name androguard_data androguard-data &> /dev/null
make[1]: [run] Error 1 (ignored)
docker run -t -i --rm --volumes-from androguard_data androguard
/usr/local/lib/python2.7/dist-packages/ipython-2.0.0-py2.7.egg/IPython/frontend.py:30: UserWarning: The top-level `frontend` package has been deprecated. All its subpackages have been moved to the top `IPython` level.
warn("The top-level `frontend` package has been deprecated. "
Androlyze version 2.0
In [1]:
This is an interactive shell session where you can begin to play with the apk
which I stored under data-container/apks/test.apk. Inside the container though it’ll
show up as /apks/test.apk.
123
In [1]: ls -lh /apks/
total 128K
-rw-r--r-- 1 root root 125K Apr 23 15:10 test.apk
In [4]: analysis = AnalyzeAPK('apks/test.apk')
In [5]: analysis
Out[5]:
(<androguard.core.bytecodes.apk.APK instance at 0x1ce7c20>,
<androguard.core.bytecodes.dvm.DalvikVMFormat at 0x1cdbfd0>,
<androguard.core.analysis.analysis.uVMAnalysis instance at 0x326ed88>)
Get the application’s main
activity
(the first class that runs when the app starts…
12
In [6]: apk.get_main_activity()
Out[6]: u'com.example.gangrene.GangreneActivity'
Get all classes/methods that have the word gangrene in them:
Cool, so Feeder looks like an android
Service.
What happens when the handleMessage gets called back? Let’s decompile the
whole apk (using dad),
but focus on the Feeder class for the moment:
In [9]: a, d, dx = AnalyzeAPK("apks/test.apk", decompiler="dad")
In [10]: print d.CLASS_Lcom_example_gangrene_Feeder.get_source()
package com.example.gangrene;
public class Feeder extends android.app.Service {
final public java.util.Random randnumber;
final private long durSec;
private android.os.Looper mServiceLooper;
private int bufferLengthBytes;
private com.example.gangrene.Feeder$ServiceHandler mServiceHandler;
final private int iterations;
final public static String DTAG;
final private int fileSizeBytes;
public android.os.IBinder onBind(android.content.Intent p3)
{
android.util.Log.e("Feeder", "in onBind in Feeder service");
return 0;
}
public void onCreate()
{
super.onCreate();
android.util.Log.e("Feeder", "in onCreate in Feeder service");
android.widget.Toast.makeText(this, "service created", 0).show();
android.os.HandlerThread v0 = new android.os.HandlerThread("ServiceStartArguments", 10);
v0.start();
this.mServiceLooper = v0.getLooper();
this.mServiceHandler = new com.example.gangrene.Feeder$ServiceHandler(this, this.mServiceLooper);
return;
}
...
That’s pretty darn readable… because the APK was not
obfuscated.
But going back to what was said earlier, we’re interested in the handleMessage callback:
That’s odd, looks like an infinite loop that just closes an input stream (File)
over and over again… what a silly app. Looks like the author just wanted to
troll someone :–)
More people should use docker to deploy tools to their community. It would make
everyone’s life easier and less time would be spent dealing with dependencies
and more time getting stuff done.