Skip to main content

Hard-Coded Data / APK File

An Android app can be configured in many different places. Typically, these are kept in SQLite Databases, JSON, or XML files. The main configuration file will be the AndroidManifest.xml file which will define all permissions, intents, services, etc.

We have two places to evaluate the application; the installed app on the device and the APK file. It is recommended to look in both places, since the installed app that has been used will have additional data that the APK may not have. The APK analysis is great for learning about the configuration, and reviewing the SMALI and Java/Kotlin code of the app.

Review Androidmanifest.xml

The AndroidManifest.xml file is the main application configuration.

To review the AndroidManifest.xml:

apktool d -o App/ ExampleApp.apk
cat App/AndroidManifest.xml

Every app project will have an AndroidManifest.xml file which describes essential information about the app. For instance, any app components (activity, service, provider, & receiver), as well as any permissions or hardware features.

App Components

Review the file for any app components that are exported or have intent filters (which means exported by default).

grep "<activity" App/resources/AndroidManifest.xml | grep -oE 'android:name="(.*?)"'

grep "<provider" App/resources/AndroidManifest.xml | grep -oE 'android:name="(.*?)"'

grep "<service" App/resources/AndroidManifest.xml | grep -oE 'android:name="(.*?)"'

grep "<receiver" App/resources/AndroidManifest.xml | grep -oE 'android:name="(.*?)"'

Permissions

grep uses-permission App/AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
<uses-permission android:maxSdkVersion="18" android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.godaddy.gdm.investorapp.permission.C2D_MESSAGE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE"/>
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
<uses-permission android:name="android.permission.CAMERA"/>

Backups & Debug

If the following command returns no data, meaning that there is no "backup" entry, then it is effectivly set to 'true'.

cat App/AndroidManifest.xml | grep -oE 'android:allowBackup="\w*"'

If the app is debuggable, then it will likely log excessive information, exposing sensitive data.

cat App/AndroidManifest.xml | grep -oE 'android:debuggable="\w*"'

Search for Databases

Typically, mobile databases are dynamically created when the application first launches. The only thing you can get from the APK file is whether the app uses a particular database:

grep -riIE 'sqlite|sqlite3|sqlcipher|couchbase|realm' App/sources

Search for JSON/XML/Text Files

To search for these usage:

find App -maxdepth 3 -iname \*.xml | grep -viE '\/res\/'
find App -maxdepth 3 -iname \*.txt
find App -iname \*.json
find App -iname \*.html
find App -iname \*.txt
find App -iname \*.js
find App -iname \*.md

Search for Certificate Files

While rare, the app may included certificates with the app.

find App -iname \*.cer
find App -iname \*.pem
find App -iname \*.cert
find App -iname \*.crt
find App -iname \*.pub
find App -iname \*.key
find App -iname \*.pfx
find App -iname \*.p12
find App -iname \*.pkcs7

Root & Frida Detection

grep -rIiwE 'RootDetector\.isDeviceRooted|com\.noshufou\.android\.su|com\.thirdparty\.superuser|eu\.chainfire\.supersu|com\.koushikdutta\.superuser|eu\.chainfire\.|com\.saurik\.substrate|de\.robv\.android\.xposed\.installer' App/sources
grep -rIiwE '\.contains\("test-keys"\)|\/system\/app\/Superuser.apk|isDeviceRooted\(\)|\/system\/bin\/failsafe\/su|\/system\/bin\/su|\/system\/xbin\/su|\/sbin\/su|\/system\/sd\/xbin\/su|\/system\/xbin\/which|RootTools\.isAccessGiven\(\)' App/sources
grep -rIiwE 'frida|frida-server|fridaserver|27047|LIBFRIDA' App/sources

Hardcoded Sensitive Information

Caution: This may provide false positives!

grep -rwiE 'password\s*=\s*|pass\s*=\s*|username\s*=\s*|secret\s*=\s*|key\s*=\s*|token\s*=\s*' App/smali* | grep -viE 'support|androidx|google|kotlin|chromium|xwalk'
grep -rE 'PRIVATE KEY|ssh-' App/smali* | grep -viE 'support|androidx|google|kotlin|chromium|xwalk'
grep -riE '(Head\w*: Auth\w*:)' App/smali* | grep -viE 'support|androidx|google|kotlin|chromium|xwalk'
grep -riE '(?i)stripe(.{0,20})?[sr]k_live_[0-9a-zA-Z]{24}' App/smali* | grep -viE 'support|androidx|google|kotlin|chromium|xwalk'

Biometrics Usage

grep -rwi BiometricPrompt App/sources/com/godaddy | awk -F\: '{ print $1 }' | sort -u
grep -rwi BiometricPrompt App/smali*/com/godaddy | awk -F\: '{ print $1 }' | sort -u

BuildConfig.java & Constants

find App/sources/com/godaddy -iname buildconfig.java | xargs cat

find App/sources/com/godaddy -iname \*constants\*.java | xargs cat

Pasteboard Usage

Check to see if the app monitors the clipboard.

grep -riIE 'content\.ClipboardManager|OnPrimaryClipChangedListener|setPrimaryClip' App/sources/com/godaddy

grep -riIE 'content\.ClipboardManager|OnPrimaryClipChangedListener|setPrimaryClip' App/smali*/com/godaddy

Firebase Usage

Check if the app utilizes Firebase for backend database:

grep -rihI "firebaseio.com" App/res* | awk -F\> '{ print $2 }'

If the app does use Firebase, then check that proper access controls are in place:

curl -o /dev/null --silent --head --write-out '%{http_code}\n' ${DBURL}/.json

Example:

% curl -o /dev/null --silent --head --write-out '%{http_code}\n' https://gdm-android-investorapp.firebaseio.com/.json
405

In this case, we get a response code of 405 which means method is not allowed. This indicates the instance is not misconfigured. If you get a 200 response code, then it is misconfigured, and you should see the JSON data.