M 404: Safeway Reversible Encryption (20 pts)

What You Need for This Project

Purpose

To examine the Safeway app and reverse its insecure encryption of stored passwords.

Responsible Disclosure

I notified Safeway of this in 2017.

Creating an Account

In a Web browser, go to https://www.safeway.com/

At the top right, click the head icon.

Create an account, making a note of the user name and password. If you already have an account, you can use that one.

Getting the Android App

You can install the app from the Play Store, as shown below.

If you can't get it from the store, you can use my archived copy.

Launch the app and log in to your account.

Observing the Stored Password

Launch Linux. Connect it to your Genymotion device with adb.

On Linux, execute these commands to find the name of the package:

adb shell
cd /data/data
ls | grep safe 
Execute this command to move into the app's directory, adjusting the package name to be correct for your system:
cd com.safeway.client.android.safeway 
Execute this command to find the stored password:
grep password -r .
The password is stored in the ./shared_prefs/accountpref.xml file, as shown below.

Execute this command to display the ./shared_prefs/accountpref.xml file, as shown below.

cat ./shared_prefs/accountpref.xml
Several encrypted items appear, as shown below.

Copy this data into a text file so you can use it later.

Pulling the APK File

Launch Linux. Connect it to your Genymotion device with adb.

On Linux, execute this command to find the name of the package:

adb shell pm list packages | grep safe 
Execute this command to find the path, adjusting the package name to be correct for your system:
adb shell pm path com.safeway.client.android.safeway 
Execute this command to pull the APK file from the phone, adjusting the path to be correct for your system:
adb pull /data/app/com.safeway.client.android.safeway-6q3b2gv68TF0mVv_jiMKlA==/base.apk 
The APK file is pulled onto your Linux system, as shown below.

Installing Jadx

On Linux, execute these commands:
sudo apt update
sudo apt install jadx 
jadx-gui
If that doesn't work, see the start of project M 402 for another way to install jadx-gui.

If you get "Hash Sum mismatch" errors, try these solutions:

In jadx-gui, open the APK file you downloaded. In the left pane, expand these items:
Source code
com
safeway
client.android
util
Click DataEncryptionUtil and scroll down to see the getRawKey method, as shown below.

M 404.1: Word (10 pts)

The flag is the word covered by a green rectangle in the image below.

Reversing the Encryption

The getRawKey method shows that this app uses AES encryption with PEBKeySpec, which implements the standard PBKDF2 algorithm to generate a key from a password and a salt.

That's easy to reverse in Python, and all the values you need are in the accountpref.xml file.

On Linux, execute these commands:

sudo apt update
sudo apt install python-pip -y
python2 -m pip install pycryptodome
nano safeway.py
Paste in this code:
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import PBKDF2

private_passwordseed = 'user_password2058718939'
private_salt = 'HpkQXYULJBvGMM2CXPLoVw=='
user_password = 'D2CF65B726D79461165E0690F0847088'

seed = private_passwordseed
salt = private_salt.decode("Base64")
secret_key = PBKDF2(seed, salt).encode("hex")
secret_key = secret_key.decode("hex")
iv = private_passwordseed[::-1]
n = len(iv)
iv = iv[n-16:n]
ciphertext = user_password.decode("hex")
cipher = AES.new(secret_key, AES.MODE_CBC, iv)
print "Password: ", cipher.decrypt(ciphertext)
Save the file with Ctrl+X, Y, Enter.

Execute this command to run the program:

python2 safeway.py
My password appears, as shown below.

Replace the private_passwordseed, private_salt, and user_password values with the ones you copied earlier from your Android phone and run the program again. You should see your own password.

M 404.2: Password (10 pts)

Find the password encoded in the data below. That's the flag.
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="user_password">2EAF39B8313BA08B9401A6215DFB613D</string>
    <boolean name="is_show_full_screen_ad" value="true" />
    <string name="clientId">F609C028E52189D3039317C96C31528429E726FCF7B98BC96D3C6C877913F682</string>
    <string name="private_userseed">user_login93214342</string>
    <string name="private_clientsecretseed">clientSecret228896712</string>
    <string name="private_accesstokenseed">access_token891623486</string>
    <string name="access_token">AE96B0ADE0B14240F9E52647C766EA64E478CD223399A0B4B1900EBF4F53785BB3BF6BE2E1E0C44EC4D1600992547D66</string>
    <string name="private_passwordseed">user_password855751249</string>
    <boolean name="is_logged_in" value="true" />
    <string name="private_refreshtokenseed">refresh_token720082475</string>
    <string name="private_clientidseed">clientId647032964</string>
    <string name="user_login">7F3FC74FB413BC0C74F8CB9C29523AF9</string>
    <string name="clientSecret">FA0B4FC1B2732B2B2EB82A13F8135FBB76D43458158783A782506D0DE02EFE65E1F61848431F9876F759EF04161B0862</string>
    <string name="private_salt">wUJQTtm3Msc3bBHpDwuT9w==</string>
</map>
Posted 2-12-21
Updated to refer to Debian instead of Kali 3-31-2021
Note re: M 402 added 4-7-2021