Enumerating Cinema Tickets

This is a hack I disclosed around a year ago to the company in question. It involves the company SF, which has a near monopoly on mainstream cinema in Sweden. They have theatres in most Swedish cities.

The attack I found involves the free-ticket coupons they offer as a gift which you can either buy or get from various sources. Such as a magazine subscription, some event or whatever. They're pretty common.

/images/cinemavoucher.png

What the voucher looks like.

Note the 11-digit numbers in the bottom right in the picture above. You should be able to spot a problem. The first 7(!) digits are all the same. My guess is that these are to identify a series of vouchers. When I did my initial attack I guessed that just the first 5 numbers were part of the series and assumed that the rest were randomly distributed. Even so, the keyspace is very small once you'd found a series to enumerate. With my initial assumption: 1000000 possible combinations with a large amount of actual tickets distributed within said numbers. I'm guessing at least 1000 of these numbers were valid tickets which would give roughly a 1 in 1000 chance of guessing a valid ticket. Assuming we can make 1 guess every second to a validation function, it would take us 16 minutes to find a ticket.

Luckily I found a validation function on the SF-website which let me do so. Very user-friendly. Maybe too user-friendly. On the SF-website, you can book your seat online. During the booking process you are allowed to input any number of vouchers to pay for your seats. They've implemented this as an asynchronous callback which executes as soon as you input your ticket numbers individually to give you direct feedback. Note that you can send a list of vouchers and it will return a response for each voucher.

/images/callback.png

A typical request

/images/callbackresponse.png

... and a typical response.

Exploiting this callback, I was able to validate up to 100 vouchers at once. Going to far above that triggered the ASP.NET request size limit. I had to jump through a few hoops to get there, since the session would be blocked because of too many vouchers being attempted. Ironically it would still reply with the validity of each voucher. So with each request I had to make a new session, which meant emulating the 3-4 steps required during the booking process. In the end, I still managed a rate of around 10 vouchers per second. Scripting this in python I pulled out over a hundred vouchers within a few hours.

/images/bruteforcecinema.png

Disclosure

I disclosed this security hole in September 2013 and got a response quickly. As proof I sent a list of 100 vouchers that I had pulled out. I was thanked for my services and received a compensation of 10 vouchers.

Afterthougths and Defences

It is now December 2014, so more than a year has passed since acknowledgement of the problem. As far as I can see though, the vulnerability has not been fixed. I patched my script and it still runs.

I understand the difficulty that SF faces in having to patch the issue though, since they probably have hundreds of thousands of vouchers in circulation which they can't revoke. The first step should have been to change up the voucher numbering though, which I don't see any changes in. What I have seen a change in, is that they seem to be moving towards magnetic stripe cards instead of paper vouchers. At least for private costumers. Company customers still get the paper voucher. This makes it only a bit harder to manufacture "fake" vouchers, but the problem still exists since the same type of 11-digit codes are used. I believe the exact same attack could be used against these cards, but I've only looked at it briefly. Thankfully though, the vouchers have an expiration date. So SF could begin phasing out the old vouchers and introduce new ones with a larger keyspace. One such way would be to introduce letters A-Z and make the code an alphanumeric code instead. This would increase the keyspace by several magnitudes (10^n vs 35^n).

Another thing that SF could do is restrict the validity function even more. 100 vouchers per request is far too high to be considered normal. They could look at using CAPTCHA's, which they already do for the separate voucher validation function they have outside the booking process. A web application firewall might be able to detect the bad behaviour too and limit the rate further.