What happened when we hacked an expo?

Tom Wyatt Headshot
Tom Wyatt
Penetration Tester
06/07/2018

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.

Toms Badge

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:

QR scan code

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:

QR code output

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.

App screenshot

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…

Great Idea meme

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.

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

Now, this is interesting. If this application is a web view consisting of the usual mix of HTML and JavaScript, could it be vulnerable to standard web attacks?

We encoded a few XSS attacks into the not-quite-JSON format the app expected, scanned them and...

Displaying a fake ID

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:

coding an alert

Scanning the barcode triggers the XSS and remote code:

XSS Vulnerability

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:

  1. Pull a .js file from a remote site
  2. Read the session tokens from the phone and post them to our server
  3. 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
  4. 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.

Payload:

Payload

Responses on the web server:

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

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.

Tom Wyatt Headshot

Meet the author

Tom Wyatt Penetration Tester

Tom is a penetration tester and ethical hacker who writes insightful articles on all things ethical hacking and red team testing.

10 Steps to Cyber Security

Find out how to secure your business in 10 steps with our free best practice infographic.

Download now

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.

(1,500 characters limit)

For more information about how we collect, process and retain your personal data, please see our privacy policy.