Q
RC OD
E through a mobile application for scanning the badges of exhibitors of information security projects.
Last year we visited a large exhibition of information security projects in London. In preparation, we were sent our passes in the form of PDF-nicknames "print it yourself."
We immediately noticed two types of barcode. Interestingly, the QR code looked too dense, considering that it is enough to store only the participant's ID in it. Being inquisitive by nature, we launched a QR scanner and received the contents of the code:
{"CJe";"BHEEZST","DO";"Cvmmfuqsppg","G";"upn","KU";"Qfofusbujpo uftufs","T";"xzbuu"}
It turned out to be “almost-but-not-quite-JSON”. One of the advantages of such a short name like mine is that it catches the eye in such situations. Therefore, I immediately noticed that my name is encoded in ROT-25 (“tom” turned into “upn”). It is also known as the Caesar Cipher, where each letter is replaced by another with a fixed offset (in this case, the next in the alphabet was used instead of each letter). Having driven the string through the decoder (taking into account the JSON markup), we got:
')
{"BId";"AGDDYRS","CN";"Bulletproof","F";"tom","JT";"Penetration tester","S";"wyatt"}
This is more readable.
We break?
It is curious that the QR code stores information that seems to be related to the “BId” field in the database. Why? Well, it's pretty simple. The organizers made a mobile application for vendors, which helps them to collect contacts of participants during the exhibition. We assumed that the data is jammed into a QR code in case the Wi-Fi or cellular signal is unstable.
So far we can do little with this information, except to change our data to avoid spam from vendors from the event. It would be funny, but hardly worthy of an email to the system developer. So, we went to the Play Market and installed the appropriate application to see what it does.
And here we faced a problem: we did not have the necessary data from the organizers of the event. We thought that we could fake the server's response using MiTM proxy, and the application will let us in. We set up Burpsuite and recorded several failed login attempts, hoping to intercept traffic and play with it.
Alas, we did not succeed. The application sent all requests using SOAP, and the responses were not obvious. However, the server publishes WSDL documents for the application.
This is not the end
Why not write a fake web service so that you no longer have access to the real server of the application? A few hours later we had such a service, and all traffic was wrapped on it. Works! The application was authenticated with any data and connected to the fake event.
We scanned a couple of badges, and it looks like everything worked correctly. Progress! After wandering around the application for some time, it became obvious that it uses some kind of framework based on WebView. Having a little picked the APK, we found a number of mentions of Sencha and Ext.js, which confirmed our assumption.
And now - the most interesting. If an application consists of the usual mixture of HTML and JavaScript, can it be vulnerable to standard web attacks? We wrapped some XSS into “not-quite-JSON” that was waiting for the application, scanned them, and ...
We broke it
Excellent! An HTML injection in the "JT" field showed an image. We can add the “onerror” attribute to this tag in order to achieve the execution of the script, but we rest on limiting the maximum length of the QR code. As a result, we created a payload that downloaded the JS file from the server and launched it on the device. Here, for example, the standard test for "alert ()":
Barcode scanning triggers XSS and code execution:
We squeezed it so that it neatly fit into the maximum size of the readable QR-code, not too dense for printing on the pass. After reading the documentation for the Ext.js API and comparing it with the decompiled APK code, we were able to make a barcode that:
- Download JS file from remote server
- Reads session keys from a smartphone and sends them to our server
- Reads the contents of a cached contact database from an application that includes the names and email addresses of all whose badges were scanned by this device.
- Deletes your entry from your smartphone.
Then the attack comes down to the following: the vendor scans my QR code in exchange for a free pen, and I get a complete list of all contacts scanned by this device.
Payload:

Web server requests:

All is well that ends well
We paid attention to the vendors at the exhibition, and after some discussion, they decided not to use the app this year. Only a few people at the event took advantage of the application, while most preferred it to simple small barcode scanners. The application from Market downloaded only about 500 times. However, this is an interesting vector for XSS, which shows that you really need to filter the data before using, regardless of its source.
Although this particular application was not widely used, imagine if the vulnerability was in an application that thousands use or download millions? All these data would go to attackers who would dispose of them at their discretion: from phishing campaigns to brute-force attacks.