Cheat And Win - Samsung SSD Contest

image0

The "Fastest Game On Earth" contest is similar in concept to the SoC quiz. Every time you "catch an SSD", you get an additional chance to win an SSD. With unlimited entries, all we need to do is to replay the packet again and again. So what safeguards are in place this time?

The application is hosted at heroku. We use the chrome inspect element tool to take a look at the resources. Good sign, no flash or other binaries, the entire application runs on javascript. The next step is to use fiddler to find out which endpoints are being hit on submission and we discover that it is reaching out to "/handshake" and "/entries". A quick grep in the source code reveals the following relevant section.

return e = "52297d8e78ff8aed",
t = CryptoJS.SHA256(Math.random().toString().substr(2, 5)).toString(),
n = "//fastestgameonearth-com.herokuapp.com",
$.ajax({
   url: n + "/handshake",
   type: "POST",
   data: {publicKey: t},
   error: this._onRegistrationError,
   success: function(r) {
       var s, o;
       return r.publicKey !== CryptoJS.SHA256(e + 1 + t).toString()
           ? i._onRegistrationError()
           : (t = CryptoJS.SHA256(7182 + r.publicKey).toString(),
              o = r.session_id, r = i.$("form").serialize(),
              s = "127.0.0.1",
              $.ajax({
                  url: n + "/entries",
                  type: "POST",
                  data: r + "&entry[ip]=" + s + "&session_id=" + o + "&publicKey=" + t,
                  success: i._onRegistrationSuccess,
                  error: i._onRegistrationError
              })))

In short, the client generates a random 4 digit no. and hashes it. The "public key" is then sent to "/handshake". The server responds with a "public key" that is the hash of (52297d8e78ff8aed+public key). Upon receipt, the client double checks the "public key" received and submits the form together with a session cookie sent by the server.

What's wrong

Firstly, it not an actual PKI infrastructure. The developers used the term "public key" thinking that it would deter adversaries from trying to reverse engineer the protocol. It is simply a one-way hash function. All it does is verify the identity of the server since the server must know the key "52297d8e78ff8aed" to append.

Secondly, javascript is open source. The adversary has full access to the algorithm and can easily figure it out and write a script that can replicate the functionality.

How do we fix it

Well, I don't really advocate the use of flash since it is known to have quite a number of vulnerabilities throughout its history and is not compatible with many devices. However, a closed source binary which performs the handshake process would greatly increase the difficulty of reverse engineering it. With only the hashed values, it is far more difficult to determine that the seed is a 4 digit random no. and the key is "52297d8e78ff8aed". There are tools that can decompile flash but the difficulty is greatly increased.

There seems to be no alternative to closed source client-side applications now that flash is slowly losing popularity. It would be interesting to see how future games and contests tackle this issue.