📜 ⬆️ ⬇️

The history of hacking a browser game. Return control

Good day. I am engaged in audit of security of web applications. In simple terms - penetration tests for websites. Sometimes in my practice there are interesting and informative cases that I would like to describe in the form of such articles, but rarely (for me this is the first case) there are situations when a client authorizes the publication of such material with a detailed description of all the problems and actions taken. Naturally, here you will not find any specific names, the name of the company-customer, etc. Probably no one will ever allow me to mention such data. I hope that for you, dear readers, this article will be interesting and useful.

Foreword

The initial situation was as follows. Lived and developed a browser game with a relatively high on-line. The project was monetized at the expense of purchases by players of virtual things for real money. One day, a cracker appeared among the players, who, having found several vulnerabilities in the game engine, began to upset the game balance in various ways. He increased the amount of money, both at home and at other players, he enhanced gaming experience for everyone, generated rare game items. Naturally payments from users almost immediately disappeared. Why pay for something if it is distributed for free? The developers tried to deal with this, even hired a person who, for $ 200, took to eliminate “all vulnerabilities” in the code, but there was no result. Their patience finally collapsed when the attacker leaked the database dump + all the source codes of the game and posted them on one public forum, with a proposal to use the game who wants absolutely free wherever they want. And if earlier, in the process of dealing with a hacker, the game was somehow developing, now it was simply impossible to do that - any new modules or new modules could immediately leak into the network.

Initial inspection

The game was based on a VPS running Debian with administration hosted by the host. From the latter, besides the server itself, was given a control panel and PhpMyAdmin.
The configuration of the internal software is very conducive to cracking. Setting up PHP allowed both opening and connecting external files (allow_url_fopen / include), although for the operation of the game neither one nor the other was required. Safe mode (safe_mode) has been disabled, the open_basedir option is not set. Functions such as system (), exec (), and others that provide the execution of system commands are not allowed using disable_functions. The error output was enabled, and there was no question of logging.
As for the web server (Apache), under its management several sub-domains related to the game were spinning - a forum, a test site and so on. The web server’s work with PHP was carried out in FastCGI mode, but the main trump card in terms of security — running scripts with the rights of their owners — was negated by a simple factor — the same user owned the contents of all subdomains. At this point, it became clear that vulnerabilities do not have to be in the engine of the game itself, they can also be located on peripheral domains.
In MySQL, the situation was similar. For each of the subdomains had its own database, and the work of the scripts with them went through the same user.
Access to the server from the outside was carried out using SSH and FTP. And if I can’t say anything bad to the first one, then with FTP the situation was completely different. Once on FTP, the user immediately got access to the contents of all subdomains. In addition, here, in the root of FTP, was a folder with database backups. They were all up to user passwords. There were also archives with FTP logs. The apogee of all this, as many have probably guessed, was that the login and password were the same on SSH, FTP and MySQL.
After a closer look, another not-so-good moment came up. The game engine was developed without using a version control system. Everything went right “live”, and if it was necessary to create a backup copy of the file, it was called something like script_name111111111.php right on FTP, and then uploaded fresh script_name.php. Work on the engine has been going on for quite a long time, and there have been dozens of such “rolling” files. Their presence greatly complicated the search for web-shells and other backdoors that the attacker could download. And the analysis of the source code, regarding the presence of vulnerabilities in it, was simply not possible. In general, it was necessary to urgently correct the situation.

Attempt number one

It is necessary to mention one handicap, so to speak, which worked for us. By the time the developers turned to me, the development of the game almost fell, the number of players fell and the cracker himself was bored with sitting in it. He came in once a day, spent about an hour doing all kinds of correspondence and left. He started to act actively only when the developers started to act - they introduced some additions, blocked his account, etc. That is, it was possible to say with confidence that until we start making noticeable, for him, changes to the server software and games, the cracker will not begin to move himself.
Based on this, it was necessary to act in such a way that the attacker, after the realization of the changes concerning the protection, could in no way influence them. Therefore, in the first place, we were engaged in maximizing the area of ​​its influence.
At first, it was decided to limit access from outside to all vital services (VPS, PMA, SSH, FTP, MySQL control panel) by IP addresses. Then the system created users for each subdomain, and all their contents were moved to the appropriate home directories. Similarly acted with the database. Now the attacker could not have control over one site, somehow affect the other.
I almost forgot. We have removed the rights 777 from all directories which had them. Sites have become completely separated from each other.
Then corrected the PHP configuration. The functions for launching OS commands, as well as the ability to connect and read files via URLs, have become prohibited. The output of errors was turned off, simultaneously turning on their entry to the file (error_log). Unfortunately, for reasons related to the features of the engine, it did not immediately turn on safe mode (safe_mode), or at least install open_basedir. Therefore, further it was necessary to work without their help.
Oddly enough, all our actions in no way attracted the attention of the attacker.
Apparently he was bored by the end of the lasagna on the server and he did not go anywhere except for the game itself. It gave some more time. Just at this point, the developers removed all the backup scripts and it was possible to start analyzing the web applications used.
Immediately, one very popular problem was discovered - the contents of directories with libraries, configuration files, etc. were accessible from outside. Of course, this is not a critical gap (the same configuration files were PHP scripts and direct access to them did not give anything), but if their contents are accessible from the outside, they are a good place to store malicious code. When access to such folders is closed, the number of places to search for "gifts" from the attacker is sharply reduced. In the case of the game engine, we left the possibility of accessing from the outside into one directory with scripts and several with JS-files, styles and images. In the latter, they simply banned the execution of scripts. Thus, there was only one folder where the execution of the PHP code could be caused by an external user. In principle, an attacker could make dangerous changes to some internal script, and try to access his code from publicly available scripts. But we also solved this problem, though not immediately (more on this below).
The very source code of the game turned out to be simply stuffed with blind SQL injections. For all the time of our cooperation several dozens of them were discovered. The person hired to eliminate them, which I already mentioned at the beginning of the article, tritely attributed to each variable in the query the use of the function mysql_real_escape_string (). But for some reason he did not take into account the fact that the developers expected the presence of numeric values ​​in these variables, so in the SQL queries the places of their inclusion were not framed with quotes. Consequently, in spite of the screening with the means of mysql_real_escape_string (), injections could be used, the main thing is not to include the special requests in dangerous requests. characters.
Interestingly, no malicious scripts were detected on any domain at that time, although we expected at least one. Later, we managed to find out what the hacker did through PMA.
As a final touch, we decided to connect to PHP a logger of information on all incoming requests (write serialized GET / POST / SERVER / COOKIE / SESSION-arrays) using the auto_prepend_file option, and provoke the attacker with another ban. There were problems immediately with the logger. Although the average online by then was not great, the players made so many requests that the logger ate up the place on the hard disk not by days but by hours. As a solution, we tried to use compression of the recorded data with gzip. It helped. Taking into account the free space on the hard drive + 1GB in reserve, the logger could work for about 17 hours. In this regard, it was decided to write a log for each hour separately, and in the middle of the day to merge all existing log files to the local computer, simultaneously erasing their originals. Since the attacker after the ban would have acted in a maximum of 24 hours (he appeared in the game every day), then it would be necessary to download logs only 2-3 times. So it happened.
')
Attempt number two

At the appointed time, we turned on the logger, checked if the data was recording normally, changed all the old passwords and banned the intruder. It is time to wait. After about 12 hours, he made himself felt. To our surprise, the hacker again banned himself and continued to play.
Immediately after that, we began a discussion of all the measures taken in order to understand what we missed. And they quickly found one slip. It was simple and banal - the passwords on all managing services were changed, but they forgot about the admin panel. There are old passwords.
Then I decided to pay attention to the source codes of the game itself. You never know there could have been downloaded by an attacker after a recent provocation. I just had the last working version on the hard drive. I began to download the engine from FTP and compare the copies locally. Not a single file was changed, but one new script appeared (the analysis of logger records, which was carried out later, showed references to it). It was a web shell. By the date of its creation, I immediately understood what was going on. Checking the source code I went folder by folder, handing in developers found vulnerabilities and looking for suspicious scripts. When about half of the entire volume was studied, the attacker uploaded the web shell to a directory, the contents of which I checked at the very beginning. Accordingly, no one found it immediately. And the attacker was able to use it to remove the ban. Here it became clear that you need to somehow solve the issue with monitoring the integrity of the file structure of the engine. Since they did not start using the version control system (they introduced it later), I had to get out with a bash script that was run once every 10 minutes by the crown, and checked for new / deleted files, and also checked the checksums of the scripts with the original amounts. I described its prototype in one of my articles - anton-kuzmin.blogspot.com/2011/01/blog-post.html .
Now that the shell has been removed, the passwords are changed again (this time all), and the bash script is running, the moment of the next ban has come.

Conclusion

The measures taken acted. The attacker registered a new character in the game, but even after a day (and up to the current time) his account remained as simple as the other players. The server’s file structure didn’t change anymore, the game balance began to recover slowly, and the developers began to massively apply the updates they had prepared earlier, but didn’t want to upload to the server until the hacker problem was resolved.
By the way, the cracker did not immediately calm down. He posted the same day on the forum, where he usually laid out the insides of the game, another dump, which was quite old, under the guise of the freshest. After that, for some reason, he contacted one of the developers and began to convince him that access to the server had not yet been lost. But when he asked for confirmation of this (for example, to give the password of one of the administrators), he either did not respond at all, or gave some irrelevant data.

PS

At the end of this article I would like to highlight several important rules for developers and administrators of web applications. For some, they seem banal, but I'm sure that some can be useful.
1) Limit PHP to the maximum. Disable OS command execution functions, enable safe mode, disable modules that you do not use. Log interpreter errors, disable their output on production servers.
2) When creating backups, delete any sensitive information from them, such as user passwords, answers to secret questions, connection details to the database.
3) When hashing data, use non-simple schemes such as a single call to md5 () or sha1 (). You should not use solutions taken from popular web engines. Organize their decoding can already most of the programs involved in working with hashes. If you use your unique scheme, even if it will be 7 calls to md5 () in a row, the attacker most likely will not be able to decipher anything. After all, if the scheme you are using is not in any well-known program, then it will have to either write a separate module specifically for your case, or order it for money. Think about how many percent of the total number of intruders will do it? Do not forget about complex passwords.
4) In applications, use a hard division into administrative and simple accounts. That is, that in the same game, the administrator could not enter using the details of the admin panel, and vice versa.
5) If you decide to store any passwords directly in the application code, store not their own, but their hashes.
6) Privileged user passwords must be unique for your application. Very not good consequences can be promised when, for example, a moderator has a password for entering the main application and for accessing the forum is the same.
7) Use for the work with the database ready libraries such as PEAR :: MDB2. In them, the shielding function of the data entering the query is automatically called, which prevents many problems. Similarly, the situation with frameworks. If you already have to put the data in the SQL query directly in the code (for example, use mysql_query ()), then enclose each value in quotes with quotes and do not forget about mysql_real_escape_string ().
8) Avoid setting 777 permissions on web application directories. Although it all depends on the situation. Sometimes without this in any way.
9) Prohibit the execution of scripts in directories that are accessible from the outside and do not have any scripts inside. It can be folders with JS-files, CSS-styles, fonts, images, etc. And for directories (and their contents), which users should not refer to, generally close access. If possible, it is better to take them out of the web directory.
10) It is highly desirable to store all restrictions and settings related to the web server in the common configuration file (httpd.conf), and disable the settings “on-site” (by means of .htaccess). This will provide a centralized storage of configuration, and also will not allow the person who accessed the site to change anything in relation to its specific directories. If there is no such possibility, and you, for example, use .htaccess, then try to set such rights and the owner on it so that it is impossible to make changes there on behalf of the web server.
11) Restrict access to important services and control panels by IP addresses.
12) Use a version control system.
13) Place domains and databases for applications located on them, so that they have no influence on each other. That the malefactor, having cracked one site, could not get through it on another.
14) Do not install all sorts of anti-hacker scripts and similar modules, without thoroughly testing them beforehand. Especially thoroughly study them if you are going to put together 2-3 such scripts. Most often this leads to big problems.
15) If an attacker suddenly contacts you after a reflected attack and starts convincing you that your actions are useless, carefully check everything he tells you. Maybe he's just bluffing.
16) In the event of any incidents, if it is impossible to detect a vulnerability by web server logs, try logging all the data from all users. This can be done using self-written scripts, as well as individual modules of the web server.

And two separate rules concerning the control of users in online games, which I came to while working on this case:
1) Automate the calculation of the amount of play money (received, spent) and experience, keep their daily statistics. Once a day, collect this data and compare it with the last day. So within a week you will determine the average percentage of their total increase in 24 hours during the normal course of the game. As soon as a dishonest player appears, who has managed, for example, to accrue a huge amount of game currency to himself, you will immediately know about it.
2) Log all operations with gaming items. A thing was created by killing a monster, a thing was transferred, a thing was sold - write everything down. Similarly to the preceding paragraph, you can, at a certain time interval, choose things from the base that did not have any history before the player appeared. That is, they appeared almost out of nowhere. By the way, the same mechanism will help to return stolen items to owners, and quickly catch dishonest players.

I hope that in the process of reading this article you learned something new and it turned out to be useful to you. I will be glad to answer any of your questions.

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


All Articles