Joshua Rubin of zvelo recently explained his research in the security of Google Wallet. Rubin discovers that a lost or stolen Android phone with Google Wallet configured could be as bad as lost a credit card.
Google Wallet is currently the only public available NFC-based payment system. It's officially available in Samsung Nexus S 4G on Sprint network. NFC is using Secure Element (SE) to store/encrypt the sensitive data, such as credit card number. It's designed to resist hacking and protect stored data.
To access SE, Google Wallet requires a 4-digit PIN at the first time launching the application. By design, if the phone is stolen, Google Wallet can lock it up completely after a few failed PIN attempts.
viaForensics first came out with a
report questioning the security of Google Wallet. Then zevelo researched more in this topic and indeed found the security flaw in the Google Wallet.
As we investigated the data stored in the per-app (sqlite3) database used by Google Wallet, we became intrigued by the contents of the “metadata” table that contained only 3 rows but a large “blob” of binary data in each. The name alone, “metadata,” just seemed like a poor attempt at “security by obscurity” which as we already know, “is no security at all.”
One row in this table has id ‘gmad_bytes_are_fun’ and this appears to be a sort of encrypted file system used for storing data via the SE. The contents of the binary data in this row likely includes the complete credit card information and certainly needs further vetting, but it was not this row that interested us.
Another row had an id of ‘deviceInfo’ and appeared to have much more non-null data. However, this binary data had to be parsed somehow to uncover its contents. After some more digging, we realized that this data was compiled using Google’s own “Protocol Buffers.” This is an open library for serializing data for messages passing between systems. In order to use this data, we had to define a “message format” in a “.proto” file (
Protocol Buffer Basics: Java). With our custom “.proto” file in hand, we were able to uncover the contents of the binary data and were shocked at what we found. Unique User IDs (UUID), Google (GAIA) account information, Cloud to Device Messaging (C2DM, also known as “push notification”) account information, Google Wallet Setup status, “TSA” (this is probably related to “Trusted Services” not the “Transportation Security Administration”) status, SE status and most notably “Card Production Lifecycle” (CPLC) data and PIN information.
The CPLC data is a vital part of the communication with the SE. However, it was yet another binary blob that would have to be deciphered, or perhaps it just acts like a “key” to unlock the SE and has no decipherable data within.
The lynch-pin, however, was that within the PIN information section was a long integer “salt” and a SHA256 hex encoded string “hash”. Knowing that the PIN can only be a 4-digit numeric value, it dawned on us that a
brute-force attack would only require calculating, at most, 10,000 SHA256 hashes. This is trivial even on a platform as limited as a smartphone. Proving this hypothesis took little time.
Google Wallet allows only five invalid PIN entry attempts before locking the user out. With this attack, the PIN can be revealed without even a single invalid attempt. This completely negates all of the security of this mobile phone payment system.
I am surprised to hear that Google Wallet is using sqlite db as the storage engine to save data, instead of their own db engine. Sqlite is a very good, light weight relational database, but just not strong enough to be as the base for secure database. Sqlite is open source database and all data is in one data file. It's both good and bad. Here's the link for the report from zevelo.