How I hacked modern Vending Machines

By Matteo Pisani

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…

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.
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.

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 ./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 informations.

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

So, first keyword search was db_name

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

Found. So I pulled if to my laptop with adb

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

and tried to open it with a DB Browser for SQLite

obviously, it was password protected

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

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…

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.

Hocus bogus.