How I hacked modern Vending Machines

“Hitting and kicking” the bundled App of their widest European distribution company.

PREFACE

Indisputably, Vending Machines are objects of cult. Delicious morsels of Hackers, always. In the beginning they worked offline with coins only, then, NFC- keys/cards models started spreading. If I say “COGES” I’m sure that better times will come to someone’s mind. But… In a bunch of years things changed radically. You distract and a moment after, find the world superseded by things connected to the internet…

STORY

One day I decided to interrupt seasoning myself in the bat-cave and direct to my hometown to get some sunlight, so I went to the University to salute an old professor.

“Go to have a coffee!” — he said— and we started chit-chatting while walking through the main corridor.

Once arrived…

Me: “let me pay, I have coins!”.

Him: “wait wait! let me use the Vending Machine’s App to pay, the coffee will be cheaper”.

BLE + NFC

Brain: “Mmm… Virtual wallets are cool stuff…”.

Excellent.

HOT-POT

Soul: “I dare you to Hack into that!”

~$ White Hat inner voice: “just pats on the shoulder if no bug bounty reward”.

~$ Grey Hat inner voice: “ok, I’ll do that for educational purposes only”.

~$ Black Hat inner voice: “c’mon man, let’s screw that HEAP, great Jupiter!”.

Later in that day…

Pwnie express.

ANALYSIS

Needless to say that I picked up my dirty rooted Android smartphone (with USB Debugging Enabled), installed the targeted App from the Play Store and dumped the original *.apk to my laptop via adb.

# adb pull /data/app/com.sitael.vending-1/base.apk ./Argenta.apk

I decompiled the *.apk with apktool

# apktool d ./Argenta.apk -o ./Argenta

and extracted Java sources with jadx

# jadx ./Argenta.apk

Firstly, I made the *.apk debuggable by editing the AndroidManifest.xml file by adding android:debuggable="true" property to the application <tag>

Then, I rebuilt the *.apk

# apktool b ./Argenta

created a new key with keytool

# keytool -genkey -v -keystore Argenta.keystore -alias Argenta -keyalg RSA -keysize 2048 -validity 10000

signed the *.apk with jarsigner using the generated key

# jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore Argenta.keystore Argenta.apk Argenta

lastly, I zip-aligned it to make it runnable

# zipalign -v 4 Argenta.apk Argenta-signed.apk

and I installed the final *.apk

# adb install ./Argenta-signed.apk

I ran the App on the smartphone and I started looking at logs with logcat by filtering them via its package name

# adb logcat --pid=`adb shell pidof -s com.sitael.vending`

Nothing special found, so I started to comb through the source codes seeking for juicy information.

Looking better at AndroidManifest.xml file, I found references to RushOrm

So, first keyword search was db_name

Cool. I booted up the Root Explorer on the phone seeking for argenta.db

Found. So I pulled it to my laptop with adb

# adb pull /data/data/com.sitael.vending/databases/argenta.db ./

and tried to open it with a DB Browser for SQLite

obviously, it was password protected

REVERSE-ENGINEERING

Step back to the source codes, looked at RushAndroidConfig.java

where I found the methods used to configure the database.

My attention was caught by this.encryptionKey = getDeviceId(context);

I moved to its definition and…

Found that the targeted App used the phone’s IMEI (*#06#) as encryption key for the SQLite database.

Abracadabra.

Boom baby.

After a couple of seconds of inspection, I opened to the UserWallets table

and edited the walletCredit field writing changes

then I pushed the database with pumped credit back to the phone

# adb pull ./argenta.db /data/data/com.sitael.vending/databases/argenta.db

VERDICT

In the meantime, while I felt like “Robin Hood” (nostalgic and explicit reference to Age Of Empires cheat code for +1000 gold) I developed an Android utility to quickly dump/restore/tamper the targeted App’s database on the fly.

then I went back to my University again to finally test the Hack

Dear diary…

CONCLUSION

From zero-credit account, I could:

> Inflate the App’s credit.

> Buy stuff.

> Get the remaining credit updated.

> Go back to zero-credit state.

> Inflate the credit again.

> Start over.

With a macro inspection of all the reversed sources I found huge portion of clean code — without obfuscation — that meant no great counter-measures adopted to protect user data and make the App secure at all.

A month ago…

The White Hat inner voice of me picked up the phone and called the company behind this shame to report the vulnerability. I gently suggested them to toss the current architecture and develop a better and secure one from scratch.