Extracting a Saved Session Token From an Android App Sandbox
Le défi
Vous avez un shell adb sur un appareil Android. Une appli bancaire stocke sa session connectee dans son bac a sable de donnees prive. Naviguez jusqu'au repertoire de donnees de l'appli, lisez les preferences enregistrees et soumettez le jeton de session que l'appli a garde sur le disque.
Ce que tu vas apprendre
- Locate an Android app's private data under /data/data/<package>
- Recognise SharedPreferences XML files in the shared_prefs folder
- Read a saved session token from a preferences file
- Use grep to find a key like session across the sandbox
- Explain why plaintext tokens in app storage enable session hijacking
Compétences testées
Prérequis
- Comfortable with basic shell commands (ls, cd, cat, grep)
- Know that an Android package id looks like com.acme.bank
- Understand that apps store local data in a private sandbox
Comment ça marche
Every Android app gets a private storage sandbox at /data/data/<package>. Inside it, the shared_prefs folder holds the app's SharedPreferences - simple key/value settings written out as plain XML files. Apps use this store for everything from a dark-mode flag to, less wisely, a logged-in session token. The directory is private in the sense that other apps cannot read it, but it is still just files on disk.
That distinction matters the moment someone has file-level access. A rooted device, an unencrypted backup, a forensic image, or - as here - an adb shell can all walk into /data/data/com.acme.bank/shared_prefs and open auth.xml. The banking app saved its session there as <string name="session">sess_4f91c2ad7e_prod</string>. Nothing about reading it requires breaking the app; the value is sitting in clear text alongside the username.
A session token is a bearer credential: presenting it is enough to act as the logged-in user, no password required. So a token recovered from local storage can often be replayed straight against the app's API to hijack the account. That is why storing a live session in plaintext preferences is treated as a real vulnerability rather than a cosmetic one - the sandbox boundary protects against other apps, not against someone holding the device's filesystem.
Erreurs fréquentes
- Looking in the databases folder first. The token here is in
shared_prefs/auth.xml, not the SQLiteaccounts.db- prefs are the simplest place an app stashes a session. - Reading the wrong app's sandbox.
com.android.systemuiis system UI, not the bank; the target package iscom.acme.bank. - Opening settings.xml instead of auth.xml.
settings.xmlholds theme and locale; the login session lives inauth.xml. - Assuming the token is encrypted. It is stored as a plain string the app reads back verbatim, so reading the file is enough.
Comment s'en protéger
Local app storage is not a safe place for a bearer credential. The fixes keep the token out of readable files and limit the damage if storage is exposed:
- Store session tokens with the Android Keystore or
EncryptedSharedPreferencesso the value on disk is encrypted at rest, not plain XML. - Keep session tokens short-lived and bind them to the device so a copied token expires quickly and cannot be replayed elsewhere.
- Exclude sensitive files from backups (set
android:allowBackup="false"or use backup rules) so the token is not exported in a cleartext backup. - Detect rooted or tampered devices and refuse to persist long-lived credentials on them.
If a session token has been exposed on disk, invalidate that session server-side and force re-authentication - a leaked bearer token is usable until the server stops honouring it.