📜 ⬆️ ⬇️

Diamond Dash again

16 As soon as I read in a recent article about writing a bot for Diamond Dash on Google+, a little less than 2 million points, my hands started to write a similar bot that would achieve this goal - and, after several days of experiments, the result was really achieved .

However, now this was not enough - using a different approach , at that time my feat was already overtaken and even surpassed (the final result, judging by the article, approaches 4 million points). So I decided to take another obvious step - try to simply replace the request to the server with the result of the game. As you can see from the screenshot, the attempt ended more than successfully.

Principle


The principle of this approach to cheating is simple to ugliness. In games that require lightning-fast reactions from the player, it is inefficient to check every “move” on the server — the slightest podlagivanie Internet and fast players immediately turn into embittered players. And the load on the servers is superfluous - who wants to check a dozen requests per second from just one player? Therefore, without further ado, the creators of the game transfer the game logic to the client side - and only the calculated number of points is sent to the server. If we send a fake to the server instead of the real result - the next time we start the game, we will be able to admire a picture similar to the one I quoted above.

How to protect the server from such fakes? Strictly speaking - no way, it is impossible in this situation in principle. A request informing the server of the result of the game is created on the client - it means that we have all the rules for its formation. Nevertheless, the task for the hackers can be complicated in the following ways (and their combinations, of course):
Let's see which of these techniques was applied by the developers of the game in question.
')

Operation "interception"


We put some web traffic sniffer - for example, Fiddler . He knows how to intercept only HTTP (and even then not always), but here we have enough of it. Start the sniffer, open the page with the game, and play one game. Return to Fiddler, look.



Yeah, requests to the toy servers (ddg.wooga.com) are sparse - everything is as expected. You can clearly see the beginning of the game (request to / game / use_life / - use the heart of life that is spent with each game) and its ending ( / game / eor / - end of round), and nothing in between.

The requests at the end of the game are two - one to ddg.wooga.com/game/eor , the other to ddg.t.wooga.com/w/eor . Let's begin to dissect the first.

Request:
POST ddg.wooga.com/game/eor/?timestamp=1314395650744&signature=V5rwMEQJS_2diWc...ulj2VBs%3D&session=1100447b5bb0d08c12 HTTP/1.1
Host: ddg.wooga.com
Connection: keep-alive
Content-Length: 99
Origin: 8kubpeu8314p2efdd7ljdo-a-oz-opensocial.googleusercontent.com
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.215 Safari/535.1
content-type: application/json
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.3
Cookie: _dd_rails_session=BAh7BkkiD3Nlc3Npb25faWQGOgZFRiIljA4NmUzZDZiNjk5MGYxZDQzNWQ%3D--3e580eae77a1037b347dae6229bb6d

{"user_id":"104465643407894900734","level":21,"sound":1,"score":144768,"xp":130,"gems_removed":348}

Answer:
HTTP/1.1 200 OK
Server: nginx
Date: Fri, 26 Aug 2011 21:54:12 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Vary: Accept-Encoding
Status: 200 OK
Cache-Control: no-cache
X-UA-Compatible: IE=Edge,chrome=1
Set-Cookie: _dd_rails_session=BAh7BkkiD3GOgZFR...wNDUxNTc%3D--b85c8953db82adcb0; path=/; HttpOnly
X-Runtime: 0.009475
Content-Length: 120

{"timestamp":"1314395652","user_id":"104465643407894900734","signature":"PAfgcneDa83-fR5_-CzJWpQ="}
(hereinafter, some lines are shortened just to fit without hyphenation)

Simple and clear JSON, not encrypted. However, the timestamp , signature, and session are transmitted in the address — so there is some kind of signature. The answer, in fact, is not very informative - the server, for its part, also spits out the signature data.

Active activities


Well, let's try it out: not even starting a game , send a completely identical request, replacing only the score field value with 99999999. Fortunately, Fiddler has a suitable tool for this - Request Builder.

Strangely enough, in response we get exactly the same 200 OK, except with a different timestamp and signature. We are surprised by the careless reaction of the server, we climb to update the page with the game. Updating, we are surprised even more: the game believed us, only instead of 99 million, 16,777,215 were counted. It looks like this is a “ceiling” - in the database it is most likely stored as something like UNSIGNED MEDIUMINT (three byte integer), which has maximum value.

It seems that you can stop at this, but after such sags in terms of the “security” of the application, you involuntarily ask yourself: are there any more holes?

Go ahead


As we see, in the request to the server our user_id is passed - the identifier of our Google+ page. And the signature, apparently, is needed so that the third-party server can understand whether this user_id really belongs to us. Hmm, does he really understand this? Or maybe he is so trusting that he can “win” even on someone else’s name?

We climb to the page of one of the friends, dragging his id from the address, slip all the same request (scoring even for the timestamp fix). Yeah, it feels good here: 400 Bad Request ... But no, wait a minute:
HTTP/1.1 400 Bad Request
Server: nginx
Date: Fri, 26 Aug 2011 22:07:06 GMT
Content-Type: text/html; charset=utf-8
Connection: close
Status: 400 Bad Request
Cache-Control: no-cache
X-UA-Compatible: IE=Edge,chrome=1
Set-Cookie: _dd_rails_session=BAh7BkkiZ...Tk5NmFkOTA%3D--b96793945142dd62b0e5ea9a; path=/; HttpOnly
X-Runtime: 0.002774
Content-Length: 124

Signature mismatch! Got: V5rwMEQJS_2diQ8sdZMXBs= computed: gcLO6NdBJtwBtOwrWIpwL9LliuA=

Computed ?! In fact, the situation is approximately as follows: we are trying to log into someone else's account; without knowing the password, we enter that horrible; in response, we receive not only an error message, but also the correct password. Perfectly.

Obediently we copy the signature from the answer, we substitute in request, we send. You probably already guessed that the answer comes completely benevolent 200 OK. And quite expected result:


(above - my account, below - "experimental" friend)

Conclusion or Why all this is “unreal” cheating


The Diamond Dash game development team would probably have to be blamed for negligence - it was obviously not worth showing the correct signature in response to the erroneous one ... But you shouldn’t be too strict with them. In the end - it is only a casual toy, and cheating it can not be avoided, as already mentioned in the beginning. In fact, the only correct way to combat cheating was used in it: the rating table is made up only of the user's friends. Thus, the results of the markups remain visible only to the friends of the cheaters (however, given the bug with the signature, this is not quite the case).

Thank you for paying attention - and I hope my article will be primarily useful not for cheating, but when developing defenses against it :)

Source: https://habr.com/ru/post/127168/


All Articles