Reverse engineering the Costa App bean QR codes

Reverse engineering the Costa App bean QR codes

Reverse engineering the Costa App bean QR codes was always going to be a challenge but here goes!

What we know

  • That this exercise is highly unlikely to lead to free Coffee as the QR codes are likely generated at the point of sale and stored in a database centrally somewhere as the machines are Internet-enabled
  • In any event it does lead to free Coffee this would be reported to Costa as a bug immediately and any further investigation would cease.
  • That the price of Medium or Large drinks varies from machine to machine
  • That the QR codes continue to work days and even weeks after the initial purchase even if they have been collected, meaning the app must be checking either that the data held on the QR codes matched given criteria, a checksum for example, or more likely that the QR codes are being matched against an entry in a database which doesn’t clear out used QR codes.
  • That when ordering the same drink from the same location there are similarities between the QR codes as shown below.

The Green shaded areas are the same with the differences shown in light brown.

2022 01 11 08 24 06 WinMerge Untitled left Untitled right
QR code data for the same drink ordered from the same machine within a few minutes of each other
2022 01 11 08 24 11 WinMerge Untitled left Untitled right
QR code data for the same drink ordered from the same machine within a few minutes of each other
  • That the data held on the QR codes look to possibly be some form of base64 encoded string separated by full stops with = as padding.
  • That when the data from the QR Code is split up by full stop and is passed through a base 64 decoder you get back JS Data as below, JS Data then formatted with https://www.prettifyjs.net/
6VHKntKNERSLLW8qMw+eTUqZyvG6Ii7B8EbnIK0aL8Y=.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtYWNoaW5lTm8iOiIxMzI2NTEwOSIsInNpdGVJZCI6IjYyNTU4MDAxIiwia2V5SWQiOiIxMDkzMDEwMTgxMjM4MjgiLCJkcmlua0lkIjoiTEFUVC1MQzEtSC0xQ0FSLUMtU0MwMSIsImFtb3VudCI6MjgwLCJjdXJyZW5jeSI6IkdCUCIsInRpbWVzdGFtcCI6IjIwMjItMDEtMDZUMTY6MDE6MjgiLCJndWlkIjoiNzk1ZTQwNDMtZTkzNy0zMWU3LTJhNWMtZGM5MjZjMTBlYjhmIn0=.DlUEnnCuK+4qdy7MIFWG7i5u4dErBeUEIh55wsVOgNk=

{
“alg”: “HS256”,
“typ”: “JWT”
}

{
“machineNo”: “13265109”,
“siteId”: “62558001”,
“keyId”: “109301018123828”,
“drinkId”: “LATT-LC1-H-1CAR-C-SC01”,
“amount”: 280,
“currency”: “GBP”,
“timestamp”: “2022-01-06T16:01:28”,
“guid”: “795e4043-e937-31e7-2a5c-dc926c10eb8f”
}

The JS Code looks to contain all the information from the point of sale, i.e. the machine unique ID, the unique ID of the site, the drink chosen, the price paid, currency paid in, a date/time and a GUID that I would suspect would be unique to each drink purchase.

The drink in question looks to be a large ( “amount”: 280 (Large drinks sell at either £2.75 or £2.80 and Medium drinks sell at either £2.40 or £2.50 from the machine I have used)) Caramel Latte ( “drinkId”: “LATT-LC1-H-1CAR-C-SC01″ )

It crossed my mind to wonder how many drinks could be sold using the GUID and for them to not have duplicated. It turns out its a LOT. Providing Costa are doing some form of checking when they create the GUID to ensure a duplicate value is not generated on the off chance the total number of unique GUIDs calculated as there are 122 random bits (128 – 2 for variant – 4 for version) so this is 2^122 or 5,316,911,983,139,663,491,615,228,241,121,400,000 possible combinations or five undecillion three hundred sixteen decillion nine hundred eleven nonillion nine hundred eighty-three octillion one hundred thirty-nine septillion six hundred sixty-three sextillion four hundred ninety-one quintillion six hundred fifteen quadrillion two hundred twenty-eight trillion two hundred forty-one billion one hundred twenty-one million four hundred thousand cups of Java!

  • That when looking at the first few lines of the JS Code we can see that part (or more likely all) of the data held on the QR Code looks to be a JSON Web Token (with bits being base64 encoded). We can bob this code into a JSON Web Token decoded and get the same info as we get from decoding the separate base64 parts, this can be seen here.
  • Unfortunately as we do not have the 256bit HMACSHA256 secret Costa used to sign the QR Code data we aren’t able to re-sign new payload data so that the Costa App recognises it as being a legitimate claim. Well done Costa on a truly ingenious way of passing data in plan sight but fully secure 10/10!
2022 01 18 11 22 10 JSON Web Tokens jwt.io and 4 more pages Work Microsoft​ Edge
  • This still leaves the first part of the QR Code data shown in green, it cannot be decoded from base64 so unsure as to what this part is. Investigations will continue….
6VHKntKNERSLLW8qMw+eTUqZyvG6Ii7B8EbnIK0aL8Y=.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtYWNoaW5lTm8iOiIxMzI2NTEwOSIsInNpdGVJZCI6IjYyNTU4MDAxIiwia2V5SWQiOiIxMDkzMDEwMTgxMjM4MjgiLCJkcmlua0lkIjoiTEFUVC1MQzEtSC0xQ0FSLUMtU0MwMSIsImFtb3VudCI6MjgwLCJjdXJyZW5jeSI6IkdCUCIsInRpbWVzdGFtcCI6IjIwMjItMDEtMDZUMTY6MDE6MjgiLCJndWlkIjoiNzk1ZTQwNDMtZTkzNy0zMWU3LTJhNWMtZGM5MjZjMTBlYjhmIn0=.DlUEnnCuK+4qdy7MIFWG7i5u4dErBeUEIh55wsVOgNk=

Known URLs / Ports

https://costa-platform.com / 23.55.6.191 (Akamai Technologies, Inc.)

costalimited.d3.sc.omtrdc.net

Collected QR Codes

19/01/2022 - Costa Jct 41 M1 - Regular Mocha 
iWgoFdiNztSrkda1LdV8OrkpUjzF0YZgYLpuNLUkPPI=.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtYWNoaW5lTm8iOiIxNTQ4MTA4MiIsInNpdGVJZCI6IjYwNDk3MDA2Iiwia2V5SWQiOiIxMTMyNjAzMTkxNDM3NTYiLCJkcmlua0lkIjoiTU9DQy1NQzEtSC0wMDAwLUMtQ0IwMSIsImFtb3VudCI6MjUwLCJjdXJyZW5jeSI6IkdCUCIsInRpbWVzdGFtcCI6IjIwMjItMDEtMThUMTY6MDE6MjEiLCJndWlkIjoiZGNiMTQzOGMtZTNiYS02NzNhLTVhYmEtYTVhNjZhMGZlMGU2In0=.L0NOQpu27V/KGHagEp+g5oD+ZqF11Pv0vItTHAktdKI=

{
“alg”: “HS256”,
“typ”: “JWT”
}

{
“machineNo”: “15481082”,
“siteId”: “60497006”,
“keyId”: “113260319143756”,
“drinkId”: “MOCC-MC1-H-0000-C-CB01”,
“amount”: 250,
“currency”: “GBP”,
“timestamp”: “2022-01-18T16:01:21”,
“guid”: “dcb1438c-e3ba-673a-5aba-a5a66a0fe0e6”
}

06/01/2022 - Costa at end of parkway - medium caramel latte
6VHKntKNERSLLW8qMw+eTUqZyvG6Ii7B8EbnIK0aL8Y=.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtYWNoaW5lTm8iOiIxMzI2NTEwOSIsInNpdGVJZCI6IjYyNTU4MDAxIiwia2V5SWQiOiIxMDkzMDEwMTgxMjM4MjgiLCJkcmlua0lkIjoiTEFUVC1MQzEtSC0xQ0FSLUMtU0MwMSIsImFtb3VudCI6MjgwLCJjdXJyZW5jeSI6IkdCUCIsInRpbWVzdGFtcCI6IjIwMjItMDEtMDZUMTY6MDE6MjgiLCJndWlkIjoiNzk1ZTQwNDMtZTkzNy0zMWU3LTJhNWMtZGM5MjZjMTBlYjhmIn0=.DlUEnnCuK+4qdy7MIFWG7i5u4dErBeUEIh55wsVOgNk=

{
“alg”: “HS256”,
“typ”: “JWT”
}

{
“machineNo”: “13265109”,
“siteId”: “62558001”,
“keyId”: “109301018123828”,
“drinkId”: “LATT-LC1-H-1CAR-C-SC01”,
“amount”: 280,
“currency”: “GBP”,
“timestamp”: “2022-01-06T16:01:28”,
“guid”: “795e4043-e937-31e7-2a5c-dc926c10eb8f”
}

2022 01 13 15 33 03 QR Code Generator Create Your Free QR Codes and 2 more pages Work Microsof
04/01/2022 - Rontec garage near Kings School - caramel latte
RuxGSlzz1dNziTyuCZ0iKF4pMR8WxzJld1r+U/ZxjkA=.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtYWNoaW5lTm8iOiI4MjAwNTMyNCIsInNpdGVJZCI6IjYzMDg2MDQ5Iiwia2V5SWQiOiIxMTQxNDEyMjAxMjUyMzIiLCJkcmlua0lkIjoiTEFUVC1NQzEtSC0xQ0FSLUMtVFAwMSIsImFtb3VudCI6Mjc1LCJjdXJyZW5jeSI6IkdCUCIsInRpbWVzdGFtcCI6IjIwMjItMDEtMDRUMDc6MjA6MjYiLCJndWlkIjoiMDM5OGZkZmQtZTYyYS04ZDg4LWI2M2QtNTA1OTY5NGNlODRhIn0=.0uRep1JpShAubc2zelgAcYx0PEwbwlIBYl4y/1NSs8c=

{
“alg”: “HS256”,
“typ”: “JWT”
}

{
“machineNo”: “82005324”,
“siteId”: “63086049”,
“keyId”: “114141220125232”,
“drinkId”: “LATT-MC1-H-1CAR-C-TP01”,
“amount”: 275,
“currency”: “GBP”,
“timestamp”: “2022-01-04T07:20:26”,
“guid”: “0398fdfd-e62a-8d88-b63d-5059694ce84a”
}

2022 01 13 15 33 41 QR Code Generator Create Your Free QR Codes and 2 more pages Work Microsof
11/1/2022 - Spar Manvers - 2 x caramel latte
sf12FtQsb0281Lb3Hkr8rh9ORBDdNroAQ/mI/oC3HdY=.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtYWNoaW5lTm8iOiIxNDA0NzU5OSIsInNpdGVJZCI6IjYwMDA4MDcxIiwia2V5SWQiOiIxMDcyMTA5MjAxMDQ1NTMiLCJkcmlua0lkIjoiTEFUVC1NQzEtSC0xQ0FSLUMtU0MwMSIsImFtb3VudCI6MjUwLCJjdXJyZW5jeSI6IkdCUCIsInRpbWVzdGFtcCI6IjIwMjItMDEtMTFUMDc6MTU6MzMiLCJndWlkIjoiYTA2MDIyYTktMmQ5NS1lMTc4LTUwZWMtNDk0ZjY1ZTVmMmM5In0=.Y4b55t5X4z3p/0Jt4HqbKFZ2JkKOKoNvdsrCI4kCieo=

{
“alg”: “HS256”,
“typ”: “JWT”
}

{
“machineNo”: “14047599”,
“siteId”: “60008071”,
“keyId”: “107210920104553”,
“drinkId”: “LATT-MC1-H-1CAR-C-SC01”,
“amount”: 250,
“currency”: “GBP”,
“timestamp”: “2022-01-11T07:15:33”,
“guid”: “a06022a9-2d95-e178-50ec-494f65e5f2c9”
}

2022 01 13 15 34 18 QR Code Generator Create Your Free QR Codes and 2 more pages Work Microsof
1ChphnZRKePjf14USDRICuEABbI8AN0O3iuHnki97yQ=.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtYWNoaW5lTm8iOiIxNDA0NzU5OSIsInNpdGVJZCI6IjYwMDA4MDcxIiwia2V5SWQiOiIxMDcyMTA5MjAxMDQ1NTMiLCJkcmlua0lkIjoiTEFUVC1NQzEtSC0xQ0FSLUMtU0MwMSIsImFtb3VudCI6MjUwLCJjdXJyZW5jeSI6IkdCUCIsInRpbWVzdGFtcCI6IjIwMjItMDEtMTFUMDc6MTc6MDEiLCJndWlkIjoiZmI0ZWIwZTQtOTQ3Ny03ZjNjLTQyM2UtOWZjOTE0ZGM2MGU5In0=.b3Fb+SkuCqTjcFQ5BXC+4YqEa1dWdloi4FifBiDNMiA=

{
“alg”: “HS256”,
“typ”: “JWT”
}

{
“machineNo”: “14047599”,
“siteId”: “60008071”,
“keyId”: “107210920104553”,
“drinkId”: “LATT-MC1-H-1CAR-C-SC01”,
“amount”: 250,
“currency”: “GBP”,
“timestamp”: “2022-01-11T07:17:01”,
“guid”: “fb4eb0e4-9477-7f3c-423e-9fc914dc60e9”
}

2022 01 13 15 35 23 QR Code Generator Create Your Free QR Codes and 2 more pages Work Microsof

 

If you found this article helpful, would you consider buying me a Coffee?

Leave a Reply

Your email address will not be published.