Master the
basics first. I have been doing Mobile app testing for quite sometime, didn’t
note down too much data though as everything was hands on, but I will walk you
through from the basics. There are many tools out there, you can try them all
and chose what works best for you, I would say use few tools and be a master of
it.
FYI: I will only be covering
basic android pentesting here. iOS and runtime hooking and manipulation
will be posted on later days.
So what do you
do when you start with any android application, either you get the apk file
from your client or you downloaded the app from playstore, if so, use an apk
extractor and get the apk file and copy to your system.
Emulator: Either Nox app player or
Genymotion. I prefer Nox personally. Anything else which you are comfortable
with will do too. I also use a MotoG2 with cyanogenmod 12.
Nox has its own
adb and you will find it under C:\Program
Files (x86)\Nox\bin\nox_adb.exe
I generally
break down my process into three parts
1. Reversing and
static analysis
2. Dynamic
analysis
3. Storage/Database/Log
analysis
Let's go one by
one.
All the apk are
zip files so you can just extract them. Rename the .apk to .zip and extract the
contents to your test folder
and firstly go
to /res/raw , mostly you will get something interesting here. Either
config information, authentication token, admin credentials for internal app
servers anything.
Browser through
the files and folders, if you are lucky and if app is not obfuscated you can
sometimes get the entire JS files source code just like that without
decompiling.
Decompiling: You can use apktool
or if you want a visual representation I would recommend using jadx-gui.
#apktool d
vulnerableapp.apk
Examine the AndroidManifest.xml
file. This will be the starting point.
Note down your
package name from the first line of your AndroidManifest.xml and it will look
something like com.mytestapp.mycompany will come in handy later.
AndroidManifest.xml :
These are the
things to look for in the AndroidManifest.xml :
1. Android
permissions: Do you really need those permissions, does the app use it? For
example READ/WRITE_EXTERNAL_STORAGE is one permissions applications shouldn’t
use unless it is really needed. This allows the app to read and write files to
your Sdcard. If this permission is enabled then it is possible that the
application is actually storing something in sd, maybe in a dot file so that it
seems hidden which may contain sensitive information, or even crash logs.
2. android:debuggable=true.
This value must be set to "false". Else it allows user to connect to
the application using adb and execute commands or functions within the
application. Default Value is false.
3. android:allowBackup=true.
This value must be set to "false". If it is set to true we can backup
applications and restore it later. Default value is True.
4. It can also
have meta-data like API keys or token keys, but I never really saw those as
issues, maybe I am wrong.
Once the
manifest file is over, load up the apk in jadx-gui and go through all the java
files, it is possible they have hardcoded keys, passwords, developers actual
phone numbers and email addresses in comments, internal IP and URLs.
There was
actually one time when the developer name and email ID gave access to the
company's shared mail account, so every bit of information is useful.
It is possible
that the application looks as if all the codes are obfuscated but when you
install the app it actually decompiles all the code and stores it in the
sdcard.
When looking
through codes using jadx-gui or any other tool make sure to look for the
following:
1. Check for Log
storage codes
2. Codes that
saves any info in the system
3. Database
codes and what are saved in that
Make a note of
all these as these are what we will look in the final stages to get hidden gems
4. Check for
type of encryption or encoding any encryption keys can be hardcoded
5. Look for
import security, crypto.cipher codes
6. Look for
webview codes, which can be used for XSS in dynamic testing
Since I test on
a windows system with Linux subsystem enabled I directly jump into a linux
environment just by typing 'bash' and grepping out things I need.
Basically grep
for Passwords, keys, SSL codes, emulator protection, root checks
Also grep for
these for Webview
setAllowContent
setAllowFileAccess
setAllowFileAccessFromFileURLs
setAllowUniversalAccessFromFileURLs
setJavaScriptEnabled
setPluginState
setSavePassword
JavascriptInterface,
if there is jsvar then we can get XSS and do command exec, check cve2012-6636,
sdk <=17 are vulnerable
In case you
want to make any changes in the application source code first view the code in
jadx-gui. After reviewing the code in java , go back and make changes to the
smali file decompiled using apktool. Then build the apk back using
#apktool b
decompiled_folder/ -o newapp.apk
Then sign the
apk. The alias_name can be anything but make sure you use the same name in all commands.
#keytool –genkey –v –keystore androidkey.keystore –alias alias_name –keyalg
RSA –keysize 2048 –validity 100
Now we have a private key. Now lets
sign the app
#jarsigner
–verbose –sigalg SHA1withRSA –digestalg SHA1
–keystore androidkey.keystore newapp.apk alias_name
Here comes ADB
ADB:
#adb
devices //To check what all devices are
connected
#adb connect
192.168.1.2 //To connect to a particular
mobile device through IP
#adb shell //
To get a shell on the emulator or phone
#adb
push/pull //To upload and download files
to and from the device
#adb install
vulnerableapp.apk
#adb uninstall
com.package.test
Always while
uninstalling you should use the package name to uninstall.
SSL
Pinning bypass:
To check that
ssl pinning is enabled look for the following strings in the code
1.KeyPinStore
2.KeyStoreException
3.X509Certificate
4.TrustManagerFactory
Three methods almost always worked for me in bypassing SSL pinning.
Bypass Method 4: Reverse the app and remove the code. Read through SSLPinning bypass by Denis
andzakov.
Breaking Mobile
app Protection mechanism:
Root and
Emulator detection:
First get your
smali code and java codes.
File.apk (unzip
and get classes.dex)-> d2j-dex2jar -> Open in jd-gui //This is another method to get source code
File.apk->
apktool d -> you get smali files
Load in Jeb or
IDA Pro or just grep.
Emulator
Detection:
Check for
goldfish.
#grep -r
goldfish
#grep -r
goldfish smali*
Once we find
the location of this, we can go there and modify it as needed.
If we find any
emulator detection code that searches for "Build.Props" like
Build.FINGERPRINT.startsWith("generic") ||
Build.FINGERPRINT.startsWith("unknown")
like this or if
it searches for any particular string then just change that string in your
emulator Build.Prop file
You can use a
build.prod editor app or any root explorer app to search in the system file for
it and edit it.
Once in
build.prop you can edit the following things:
Edit Android Version
by locating ro.build.version.release= and changing the current Build
Version.
Edit your Model
# by locating ro.product.model= and changing your model #
Change your
product brand by locating ro.product.brand= change as needed
Please Note that
if you change the product brand, the name MUST be in ALL LOWERCASE LETTERS!!!
Once you are
done playing around, press menu, and then Save...now just exit
the app and reboot your phone.
Once
your device reboots, go to Settings> About Phone/Device and
see the changes.
Static Root
checks:
1.Look for
binary, file or directory:(Looking for SuperUser.apk):
Solution: Just
rename the binary. If the app is searching for SuperUser.apk , then rename to
notsuperuser.apk, if app is searching for /system/bin/su change to /system/bin/notsu
2.Checking
/system attributes:
App will check
for read-write permission for /system.
Solution:
change to read only using the following command:
"mount -o
ro,remount,ro /system"
3.Hashing
Files:
App create a
hash of superuser.apk and then checks.
Solution: Patch
the binary OR no-op out the check ,OR change value in memory via a debugger
4.Binary
check:
App will run
whoami and check if its root.
Solution:Replace
whoami binary on phone which does not give root
Patch out
checks in binary
Modify Value in
debugger.
Oh Yeah Drozer:
Before that a
little about Activities, services Content providers.
Activity: Touching an app is activity,
launching app. Any event that triggers a change in the Visual representation is
an activity.
Service: Long running process, running
in background like playing music
Intent
receiver: Responds to input, input can be SMS, phone reboot, losing WiFi. Intents
are ways of sending messages between different functions.
Content
Provider: Content
providers are used by applications to communicate and share data with other
applications. A misconfiguration will allow other apps to access unintended or
sensitive data.
Broadcast
receivers: Listen for something
Explicit
intent: Recipient of the intent is specified. So we can specify that only
certain app/broadcast receiver can take a particular intent.
Implicit Intent: The platform decides where it should be
delivered, like we open a link and it asks how do you want to open? Chrome or
Mozilla etc.
EXPORTED: Means your app can
interact with something else, like some other app or event.
Intent receiver
Fail: Intent receiver must not be
implicit, then any app can provide malicious/false information to that app. Any
application can also listen to intent from that app if intents are implicit
Install drozer
server in mobile device, and agent on your host machine. You can do this in
both windows and linux. For Windows machine install universal adb so that you
can directly use adb from command line.
Start the
drozer server in the mobile device.
To do that
type:
#adb forward
tcp:31415 tcp:31415
#drozer console
connect
To find the
package name type:
dz>run
app.package.list
To get details
on the application like permissions:
dz> run
app.package.info -a com.package.test
To find the attack
surface for the package:
dz> run app.package.attacksurface com.package.test
This will give
a list of attack surfaces available. We are interested in content providers
dz>run
app.provider.finduri com.package.test
Once we find
the content provider we are interested in we have to query it.
dz>run
app.provider.query content://com.package.test.Secret/mysecrets --vertical
Drozer uses
only internet permission so getting info from content providers is a
vulnerability.
We can also use
content providers to read sdcard files and do a directory traversal attacks.
All DROZER commands
Starting a session
c:\>adb forward tcp:31415 tcp:31415
c:\>drozer console connect
Retrieving package information
dz>run app.package.list -f "app name"
dz>run app.package.info -a "package name"
Identifying the attack surface
dz>run app.package.attacksurface "package name"
Exploiting Activities
dz>run app.activity.info -a "package name" -u
dz>run app.activity.start --component "package name" "component name"
Exploiting Content Provider
dz>run app.provider.info -a "package name"
dz>run scanner.provider.finduris -a "package name"
dz>run app.provider.query "uri"
dz>run app.provider.update "uri" --selection "conditions" "selection arg" "column" "data"
dz>run scanner.provider.sqltables -a "package name"
dz>run scanner.provider.injection -a "package name"
dz>run scanner.provider.traversal -a "package name"
Exploiting Broadcast Receivers
dz>run app.broadcast.info -a "package name"
dz>run app.broadcast.send --component "package name" "component name" --extra "type" "key" "value"
dz>run app.broadcast.sniff --action "action"
Exploiting Service
dz>run app.service.info -a "package name"
dz>run app.service.start --action "action" --component "package name" "component name"
dz>run app.service.send "package name" "component name" --msg "what" "arg1" "arg2" --extra "type" "key""value" --bundle-as-obj
Directory
Traversal:
dz>run
app.package.list -f vulnerableApp
com.package.test
dz>run
app.package.attacksurface com.package.test
dz>run
app.provider.finduri com.package.test
We cannot also
query to get details. it depends on the content provider.
Now our goal is
to use content provider of vulnerableApp to read file from SD using drozer.
dz>run
app.package.info -a com.package.test
This show the
permission of adobe which shows android.permission.READ_EXTERNAL_STORAGE
Since query
will not work we will try to use "read"
dz>run
app.provider.read content://com.package.test.file/../../../../mnt/sdcard/secret.txt
After
com.package.test.file which is the content provider name, we tried to do a
directory traversal to read the content of the file secret.txt which is under
mnt/sdcard. The dotdotslash(../) may vary
Check for both
read and query.
Activity:
If u get activities exported in drozer
then use:
dz>run app.activity.info -a
<package>
dz>run app.activity.start
--component <package><activity>
Exploiting
custom permission
Sometimes custom permission make it difficult for drozer to query data, to query such data we have to find the permission and add it in drozer and recompile drozer.
dz>run app.package.list
-f vulnerableapp com.package.test
dz> run
app.provider.finduri com.package.test
dz>run
app.provider.query content://com.com.package.test.db/outgoing_filters/
If it shows an
error saying permission denied and requires android.permission.CONFIGURE_SIP
Now we will
decompile vulnerableapp.apk and look how it asks for permissions
We will do this
using apktool->android manifest file.
We see that the
manifest file has permissions android.permission.CONFIGURE_SIP and one more
similar one.
Since this is
an custom permission we will copy this permissions and recompile drozer apk
with these permissions and install it and use it. So decompile
dozer apk file and open the AndroidManifest.xml and copy the extra permission
and uses lines you found in vulnerableapp
AndroidManifest.xml into the manifest file of drozer and save it. Now u
will/might have certain references to a file called string.xml and it will look
like: android:label='@string/permlab_useSip'. So we
have to get the reference string as well. To do that open strings.xml for both
the drozer.apk and vulnerableapp.apk which we had decompiled.
Location is
vulnerableapp/res/values/strings.xml and copy the permlab_useSip and
similar string which were used to your drozer's strings.xml file, save it.
Recompile the new drozer decompiled file to an apk.
#apktool b
drozer/ -o drozernew.apk
Sign it :
#jarsigner
-verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore
drozernew.apk alias_name
Uninstall the
previous drozer and install the new one
Now go to
drozer
dz> run
app.provider.query content://com.package.test.db/outgoing_fileters/ --vertical
Voila now you
will get all details.
Backup based
vulnerability:
#adb backup
com.package.test -f vuln.ab
A pop-up will
appear on phone click backup my data.
We have to
remove the first 24bytes which is the header
#dd if=vuln.ab
bs=24 skip=1| openssl zlib -d > vuln.tar
OR Download
androidbackupextractor. You will get a file abe.jar
#java -jar
abe.jar unpack vuln.ab vuln.tar
#tar -tf
vuln.tar > vuln.list
#tar -xvf
vuln.tar
Now everything
will be extracted. Go inside apps and package and basically change whatever you
want to change in the app to be reflected back. For example you can modify
preferences.xml to bypass login. Once all changes have been made now we will
convert the extracted files back to tar file.
#star -c -v -f
vuln_new.tar -no-dirslash list=vuln.list
Now we will
have our newtar file i.e vuln_new.tar
#java -jar
abe.jar pack vuln_new.tar vuln_new.ab
We need to get
the 24bytes header back again, for that do
#dd
if=vuln_new.ab bs=24 count=1 of=vuln_2.ab
#openssl zlib
-in vuln_new.tar >> vuln_2.ab
#adb restore
vuln_2.ab
Give
confirmation in our device and open the app and see the changes made.
Automated Tool:
Sometimes it is good to throw the apk into an automated scanner so your clients
don’t complain when their automated scanner finds something.
This is an
awesome tool, little difficult on the initial setup though but once done works
like a charm, better install in windows environment.
Dynamic
Analysis:
#adb logcat
> log.txt
This is the
first thing to do before starting any dynamic testing. Let logcat go on
throughout your testing process. You can also do it after the testing but if
you wanna check if some critical data is being logged as and when the
communication is happening then doing at the beginning is better.
Response
tamper: This one is really useful only for mobile based application. Keep your
response capture in Burp ON.
Since all the
codes are inside the application the app trusts the response from the server to
do further processing. You can take advantage of this to trick the application
by sending misleading responses and gain access or bypass stuff.
This actually
gave me multiple login bypass, PIN bypass, verification bypass, access to
unauthenticated information and many more. To exploit this you have to check
the difference between a valid and invalid response and change accordingly. For
example: Let's say a valid username and password combo gives a response as
"SUCCESS" and an invalid combo gives "failure". By giving an
invalid password and changing the response from "failure" to
"SUCCESS" you are actually tricking the application to believe that
the username and password you gave earlier is valid and it will let you login.
Webview vulns:
Webview using
metasploit: Try out this exploit, this was for android less than 4.2 but
application's inbuild webview can also be vulnerable so it’s a good try to get
a RCE.
Exploit: exploit/android/browser/webview_addjavascriptinterface
Most of the other vulnerabilities are same as
what you perform in a web application, assuming you are a master in web app
pentesting I am only focusing Android based exploitation.
To know what to test exactly you can follow the OWASP Mobile App check list, its for both android and iOS.
Storage/Database/Log
analysis:
First thing to
do is extract the data files from the emulator/phone.
Since you
already know the package name you can directly extract it to your local machine
C:\>adb pull
/data/data/com.package.test c:\extracted\
Make sure you
get all the files related to the application, as seen in the code analysis
there might be log files too stored in different location like sdcard. So
search and get all files. Sometimes it is possible that not all files will be
extracted like some cache file, for that you can simply cat it from your root
shell.
The first file
to look will be your shared_prefs.xml, this file might contain very
useful information, sometimes even plain text username and password.
Next will be
your .db files, this might be encrypted sometimes and you might also get the
decryption key from the codes if not hidden well.Download sqlite browser: http://sqlitebrowser.org/. An easier way to view all the db files. You might get some sensitive data
here too.
Oh yeah almost
forget the logcat output. Grep the logcat output with process ID and look
through it entirely to find if there are anything logged.
Guess this
should cover almost all of the basic. As said earlier, dynamic hooking, manipulation
and iOS is for another day.
TO DO for next android pentesting post:
Andbug debugging
Xposed framework hooking
Frida
Cydia substrate
And some Miscellaneous for you all to go through.
JEB: Is an awesome tool. For
now you can just load up the apk file and directly search for all the strings
and see where they occur in codes and it can be used for code level
manipulation as well. I am still trying to get around this though.