What happened when we hacked an expo?
In 2017 we exhibited at a major information security trade show in London. During the preparation for this we received our exhibitor passes as “print yourself” PDF files.
We immediately noticed that there are two forms of barcode here and, interestingly, the QR Code seems quite dense given that all it should be storing is a delegate ID number. Being the inquisitive sort of people that we are, we started up a QR scanner and had a look at its contents:
We were greeted with something that’s almost-but-not-quite JSON. One of the wonderful things about having a short first name is that it tends to stand out in situations like this. Immediately, I spotted my first name there as ROT-25 encoded text ('tom' had been transformed into 'upn'). This is also known as a Caesar cipher, where each letter is simply offset (here each letter had been incremented by one). Putting this string through a decoder (paying attention to ignore the JSON characters) gave us this:
Now, that’s a bit more readable.
Can we break it?
It’s interesting that the QR code stored data that is probably associated with the “BId” in a database. Why could this be? Well, it’s quite simple. The organisers provide a mobile app for vendors to use, which helps them collect contact information from delegates during the show. We guessed that the first name etc. is stored in the QR code for those times where the show's Wi-Fi or 4G signal is terrible.
At this point, there isn’t much we could do with this information other than alter our names to prevent the inevitable spam emails from vendors at the show. This could be fun, but hardly warrants an email to the ticket system vendor.
So, off to the Android App store we went. We installed the relevant app to see what it did.
Now, this was a problem, as we didn’t have a show reference or a username/password for the server. We thought that perhaps we could spoof a response from the server using a MITM proxy and the App wouldn’t care. We set up Burpsuite and captured some failed login attempts, hoping to be able to intercept the traffic and fiddle with it.
Well, we couldn’t. The App made all of its calls using SOAP requests and the responses weren’t immediately obvious to us. However, the server did appear to publish WSDL documents for the application…
Not done yet
Why not write a fake web service and never touch the actual application server? A few hours later we had a fake service running and diverted all traffic from the App to it. It worked! The app signed in using any credentials and connected itself to a fake show.
We scanned a couple of badges and everything appeared to work properly. Success! After navigating around the app for a while, it became obvious that it uses some framework based on web views, and after some digging into the APK we found a number of references to Sencha and Ext.js that confirmed this.
We encoded a few XSS attacks into the not-quite-JSON format the app expected, scanned them and...
We broke it
Excellent! Injecting HTML into the “JT” field produced an image. We could add the “onerror” attribute to this tag to get script execution but started running into problems with maximum lengths of QR Code data. Eventually we developed a payload that could pull a .js file from a remote server and execute it on the device, for example, here’s a standard “alert()” test:
Scanning the barcode triggers the XSS and remote code:
We slimmed this down until it fitted neatly into the maximum size of a readable QR code that wasn’t too dense to print on a label later. After looking through the Ext.js API documentation and combining it with the decompiled APK code we managed to produce a barcode that would:
- Pull a .js file from a remote site
- Read the session tokens from the phone and post them to our server
- Read the contents of the cached contact database the application held. This included names and email addresses of anyone that had been scanned by that device
- Remove its scan entry from the phone
The attack then boils down to this: a vendor scans my QR code in exchange for me getting a free pen, and I retrieve a complete list of all contacts they’ve scanned on that device.
Responses on the web server:
Luckily, a happy ending
We bought this to the attention of the vendors while at the show and, after some discussion, they decided to retire the application this year. Very few people at the show were using the App, with most people preferring to use the smaller simple barcode scanners, and the Android App store page only lists around 500 downloads. Still, it’s an interesting vector for XSS and goes to show that you really need to sanitise data before doing anything with it regardless of the source.
Whilst this particular app wasn’t widely used, imagine if the flaw existed on an app used by thousands, or downloaded by millions? All that data would be up for grabs for malicious actors to do with as they wish (malicious actors being hackers in this case, not an enraged thespian). Any details obtained could then be used for widespread phishing campaigns or brute-force attacks.
Trusted cyber security & compliance services from a certified provider
Get a quote today
If you are interested in our services, get a free, no obligation quote today by filling out the form below.