How we Outsmarted CSGO Cheaters with IdentityLogger

Gaming7356628

The World of CSGO Server Operation

I founded an Australian & New Zealand based CSGO community server called Invex Gaming, which was active from 2014 to 2019. Our community gaming servers quickly rose in popularity thanks to our amazing community, content, competitions, and custom game plugins.

Invex Gaming Analytics 2014-2019

There is a lot of work involved in maintaining a gaming community.

The list of responsibilities includes:

  • Maintaining the infrastructure for the community forums and servers themselves.
  • Managing costs and community donations.
  • Adding new content like player models and fixing their hitboxes.
  • Automating VIP systems and permissions.
  • Writing custom, unique plugins that distinguish the community.
  • Patching game exploits and bugs.
  • Preventing DDOS attacks by bad actors.
  • Handling abuse reports for players that break the server's rules.
  • World domination.

However, the most tedious task by far is identifying and banning cheaters.

A cat-and-mouse game

CSGO Dust2 Door Spinbot

Regardless of the game, there will always be cheaters. As a server operator, you can detect these cheaters using a myriad of techniques. We can use server-side code to detect actions that would be impossible for a human to perform legitimately. We can rely on the Valve Anti-Cheat (VAC) system to detect cheats, which is often criticised for its performance but does a good job at catching very blatant cheaters. We can abuse your kernel to run kernel-side anti-cheat and also mine bitcoin on the side as a "thank you" fee. Oh wait, we didn't use that last technique, but some anti-cheats certainly do!

All these detection methods are great but cannot automatically detect every cheat due to the constant back-and-forth, cat-and-mouse game that cheat developers and anti-cheat developers play together. As a last resort, we rely on manual human analysis using CSGO demos that record all in-game activity 24/7. Our admins (or a jury of your gaming peers if you prefer) make a judgement call on whether a player was cheating, leaning on the side of caution.

Once we finally catch a cheater, we must permanently ban them from our servers in the spirit of competitive integrity. The thing about cheaters is they don't like being caught. Moreover, cheaters tend to never stop cheating. I can't tell you the number of times a player was permanently banned for cheating, unbanned, then given a second chance, only to reoffend the very next day and get banned again. However, certain players are more tech-savvy and know the fundamentals of ban evasion.

Art of ban evasion

How does one evade a ban?

The core mechanics behind a ban is that some piece of identifiable, preferably unique information is used to deny you access to a service.

On the internet, this identifier is more often than not your IP address, which is essentially a number assigned to you by your ISP or server provider that allows you to interface with other machines on the internet. An example of an IPv4 IP address is 198.51.100.1.

In the Steam ecosystem, each player also needs a Steam ID to play Steam-powered games. This is a unique identifier tied to your individual Steam account that identifies you in the Steam world. An example of a Steam ID is STEAM_1:1:1111.

When a player is banned, we put their IP address and Steam ID on the naughty ban list. This means Santa won't visit you this Christmas, and also you can't play on our servers anymore if you join with this IP address or Steam ID.

Let's assume a player with the IP address (198.51.100.1) and Steam ID (STEAM_1:1:1111) is banned for cheating. We persist the details of their ban to a database and kick them off the server.

Now, the next time they re-join the server, they fail both the IP Ban check and Steam ID Ban check.

To evade this ban and continue playing, a player might decide to switch to a different steam account. Now their new Steam ID, say STEAM_1:1:2222, does not match the Steam ID they were originally banned on. However, our anti-cheat overlords have accounted for this. If a player joins with a different Steam ID but with an IP address that is already banned, the system now re-bans them, associating this new Steam ID with the previous ban. This essentially begins the process of building a fingerprint for this player. We now know this player is associated with 2 Steam IDs (STEAM_1:1:1111, STEAM_1:1:2222) and 1 IP address (198.51.100.1).

Instead, the player decides to use a VPN to change their IP address. Now their new IP address, say 203.0.113.60, does not match the IP address they were originally banned on. However, again, if a player joined with a different IP address but with a Steam ID that is already banned, the system re-bans them, associating this new IP address with the previous ban further developing the fingerprint. We now know this player is associated with 2 IP Addresses (198.51.100.1, 203.0.113.60) and 1 Steam ID (STEAM_1:1:1111).

Beyond these two identifiers, we don't have any additional identifiers for each player joining our game server. For most cheaters, this level of identification is usually enough.

🚨 BUT WAIT! 🚨

What happens if the player changes both their Steam ID and IP address in a single, decisive move?

Flusha Onetap

🏳️ ggwp. Well played indeed.

In our case, the player joins with a never-before-seen IP address (100.64.50.74) and Steam ID (STEAM_1:1:3333):

As far as the server knows this is now a completely different player. There is no way to associate them with their previous bans on their Steam IDs or IP addresses because they are using fresh, never-before-seen identifiers. Unfortunately, this means the player is free to wreak havoc. If they get banned again, they simply rotate both identifiers together at once and continue ban evading.

To mitigate this, we could maintain a list of popular VPNs and their associated IP addresses but this is extremely tedious and requires constant maintenance which is something our admin team discussed and wasn't too fond of doing.

Now you might say to yourself, surely the cheaters will run out of IP addresses or Steam accounts. They did not. In fact, our analytics later revealed our most notorious cheater had access to seemingly endless geographically distributed IP addresses and over 87 Steam accounts that had purchased CSGO.

Problematic cases of IP address fingerprinting

Now, remember while the Steam ID uniquely identifies a player the IP address does not. We've encountered scenarios where two young siblings would play on our servers but only one would cheat. This resulted in both being banned as their fingerprints were entangled. One of these players claimed that "he couldn't control his brother and he shouldn't be punished unfairly for his brother's actions". This is true and I agreed!

Another issue was shared networks like universities. Sometimes a group of players would play from their university that used a single IP address for all outbound traffic. When one individual cheated and got banned on the campus network, all other players using that network were flagged as cheaters and their Steam IDs and home IP addresses were associated and unfairly banned.

We built in an exception system for these rare cases but generally advised people not to play on networks they didn't trust.

IdentityLogger

Let's face it

In Bruges Harry Mad

I'm not being funny and I mean no disrespect.

But cheaters are cunts. They're cunts now, they've always been cunts.

And the only thing that's going to change is they're going to become bigger cunts.

Maybe have some more cunt kids.

I don't ultimately get why you would cheat in a video game. Surely, that is extremely boring and a waste of your own time? Regardless of how good or bad I am at a video game, the payoff for me is to compete with others, try to improve, and achieve a sense of pride and accomplishment!

By early 2017, the ban evasion problem on our servers had worsened significantly, taking a serious toll on the admins who were performing constant manual demo reviews which were both time-consuming and, let's be honest, boring. To this day I am thankful for all the hard work the admins did in our community. Therefore, I sat down, got out my rubber ducky, put on noise-cancelling headphones and started "engineering" to figure out a way to catch them all (the cheaters not PokΓ©mon).

Handling a simultaneous Steam ID and IP Address change

Our core issue is handling a simultaneous change of both the Steam ID and IP address. This would seemingly appear impossible since we did not have any other identifiers to rely on. At this stage I did a lot of brainstorming and analysis of the data available to us CSGO server operators. I was an active member of SourceMod, an open source modding platform for source games, and also quite comfortable with reverse engineering CSGO game binaries so I already had considerable experience in this space.

At some point I started thinking about the game's built-in web browser. CSGO offered a little basic web browser in-game (that is different from the Steam overlay browser) that allowed server operators to show a MOTD (message of the day) when people joined the server.

We'll call this browser the VGUI browser.

CSGO VGUI Browser

This browser was commonly used by server operators to display the rules of the server for new players upon joining. Interestingly, server operators had the ability to forcefully open any website on the web on a player's screen. The window could even be hidden, meaning opening a YouTube video would suddenly play audio in the background of the player spooking them. The VGUI browser was pre-authenticated with your Steam cookies so that you would automatically be logged into any Steam domains like steamcommunity.com. The browser also allowed the client-side execution of JavaScript sent from the server operator. Yes you read that right. This led to a massive Steam exploit in August 2017, in which server operators could hijack the credentials of their players via the VGUI browser but that's a topic for another day.

Cookies! πŸͺ

Recall how the VGUI browser was pre-authenticated with Steam cookies. This means it has native support for cookies, which are sticky and persist between browsing sessions by design. What happens if we store cookies on our own domain for each player each time they visit the server?

πŸ””πŸ””πŸ”” We have a winner! πŸ””πŸ””πŸ””

Testing revealed that the cookies we save via the VGUI browser were persisted even after shutting down and restarting CSGO. Furthermore, there seemed to be no expiry date limitations enforced on the cookie. Modern browsers like Chrome have enforced cookie expiry limitations upper limits. However, the VGUI browser had no issues saving cookies with expiry dates exceeding 10+ years!

Another convenient feature of the VGUI browser was that the browser could be hidden entirely. This meant the server could silently force the client to visit our website where we would fingerprint you and store some cookies, all without the player ever seeing the browser window. A silent but deadly approach.

Investigations revealed the cookie data itself was persisted in a file that was located in the Steam installation directory on the user's machine. This is crucial because it means the vast majority of cheaters will never figure out how to bypass it. They are unlikely to delete this file and neither the browser nor the game had any functionality to clear cookies.

Wonderful, we have found a way to silently persist a cookie for each player as they join the server. We now have an additional third identifier to help fingerprint each player. This identifier, which we will call the Tracking ID, is tied to the installation directory of the player. Now, in order for a player to appear to us as a "fresh player" they would need to change their Steam ID, IP address and Steam installation folder. As you can imagine, no one is going to do the latter.

Implementation details

In this section, I'll explain the technical details behind the implementation of IdentityLogger (which is also open source on GitHub).

IdentityLogger is the name of the all-in-one system which fingerprints players based on their IP address, Steam ID and Tracking ID.

The implementation of the system is quite simple. The real genius lies in the idea itself.

When a player connected to one of our servers, for example at csgo.example.com:27015, we would first perform a ban check. This ban check would check a database for their IP address, Steam ID and Tracking ID. If a ban already exists, we kick the player from the server and associate any new identifiers with their existing ban.

If the player was still with us, we would then open the VGUI browser in a hidden window. The target website to visit was our own secret web page. Although unlikely anyone would ever discover the website, we used a secret in each request to authorise the request. All the requests made in the VGUI browser are client side but the traffic itself was encrypted over HTTPS. This meant that even if one were to use a packet sniffing tool like Wireshark, you would not be able to find the raw token. The only real way of finding the token would be to inject into CSGO and log VGUI browser's access. This would require not only the inkling to do this in the first place but also strong reverse engineering skills and familiarity with the CSGO binaries. Skills basically 99.99% of our cheaters would not have.

Next, our PHP script checks if a Tracking ID cookie already exists. If not, we created one and persisted it (which would ultimately store it on disk in the vgui.browser.cookies.dat file in the Steam installation directory of the player). The Tracking ID cookies were simply 64 length random alphanumeric strings such as: TeStsCOhZO1TQsumJkDUOdMMo13ReRLEngrQTg7S49LKT2rBvgPhauzSYbegscOT

All identifiers (Steam ID, IP address, Tracking ID) would also be persisted in a database whenever a player joined the server. We used this database to maintain the identities, query results and create a web panel for admins to investigate player fingerprints.

IdentityLogger Web Panel

This database was also tightly integrated with our modified SourceBans plugin which is based on the popular ban management software for Source-based games.

Ban Evasion Prevention Example

Let's revisit the case where a player was banned with IP address (198.51.100.1) and Steam ID (STEAM_1:1:1111). Since this is a new player joining the server for the first time, they did not have a Tracking ID and a new one was generated and persisted for them. They are then banned for cheating and their IP address, Steam ID and newly generated Tracking ID are added to the ban database.

Later, the cheating player re-joins with a never-before-seen IP address (100.64.50.74) and Steam ID (STEAM_1:1:3333), thinking they will be able to evade their ban. WRONG!

Their new IP address and Steam ID pass the ban check as expected but their Tracking ID fails the ban check because it is already associated with a previous ban. So the player is immediately banned and their new IP address and Steam ID are associated with their prior ban.

We have effectively stopped the ban evasion attempt.

Furthermore, this player will continue to be instantly banned upon joining the server based on their Tracking ID, no matter what IP address or Steam ID they use. The cheater is left helpless and confused β€” afraid even. Precisely as we planned *cue diabolical laugh*.

The great ban wave of 2017

After implementing and testing the solution, we deployed the system on all Invex Gaming CSGO servers in February 2017.

The results were shocking β€” shockingly good.

Immediately, we noticed a massive spike in the number of cheaters getting banned β€” I should have bought calls. Long time well-known and trusted community members were exposed for possessing secret accounts that they were cheating on. Cheaters reached out to me personally and asked how it was possible for me to detect them as ban evading when they changed their Steam ID and IP address. Other server operators were interested in the plugin, with some offering money for it. I only shared the solution and technique with one other server operator I fully trusted based in the UK. Widespread sharing of the solution would ultimately render the technique ineffective.

It was a glorious time and I loved every minute of it. Our community earned a reputation for being "hard to cheat on" and subsequently the number of cheaters and cheater abuse reports dropped significantly on our servers.

The best part was that no one knew how we were able to do this and our admin team kept the implementation a top secret. We should have filed a patent! If cheaters learned how we were able to fingerprint them in this way, it would have been trivial for them to delete the cookies file on disk while ban evading. I am happy to report that the solution worked as expected from deployment date until October 2017 when Valve removed the VGUI browser entirely as part of their efforts to secure the game. It was only after this that I revealed the technique publicly and open-sourced the plugin.

Many years later, I remain really proud of this solution and how well it worked.


Leave a comment

(required)(will not be published)(required)

Comments

Showing 28 comments from 23 commenters.

  • Display picture for James
    James

    I've never understood this mentality with game developers. Always blaming and reacting. How about avoiding the cat and mouse problem by fixing your shit up front? Architect the game so cheating doesn't work, secure that shit up front. Build better software. If you release your shit with gaping security holes, you deserve 100% deserve the backlash. "hard to cheat on" should not be praised or glorified, the only outcome should be "impossible to cheat on".

    Reply
    • Display picture for JameIsAMoron
      JameIsAMoron

      So tell us James what kind of software did you built that you could live on and was worthwhile to even criticize ?

      when you criticize this way, first show the reader you made something good that gives you some legitimacy, otherwise you are just a moron

      Reply
    • Display picture for Bailey
      Bailey

      Spoken with the confidence of someone who has no experience in the space. Why don’t we just make space suits that let you breathe the vacuum of space? That would solve the problem of needing to bring our own air to the space station. NASA just has the wrong mentality oland isn’t solving the right problems.

      Reply
    • Display picture for AlwaysSendIt
      AlwaysSendIt

      Actual child response. "Why don't they just make it better? Are they stupid?"

      Reply
    • Display picture for GoatedWithTheSauce
      GoatedWithTheSauce

      ^

      Literally no-devs, it's piss easy to make a game impossible to cheat on, james right

      Reply
      • Display picture for GoatedWithTheSource
        GoatedWithTheSource

        You are partially correct, It is easy to make an online only bad game impossible to cheat on.

        As soon as you are trying to make a game responsive, useable and most importantly fun, Anti-Cheat has to make compromises.

        Imagine a game where the server doesn't share the locations of everyone on the map unless you can see some part of them, now your ping affects what you can see and what you cannot and the load on the server is much higher.

        There are many, many other examples of compromises that a company could make to reduce cheating in their game that would significantly impair the quality of the game, If you can come up with solutions that don't make significant compromises and have a way to implement them file a patent and start selling your solution for $$$

        Reply
        • Display picture for lol
          lol

          To GoatedWithTheSauce not you

          Reply
      • Display picture for lol
        lol

        You just said total bs, it's impossible to make a game uncheatable, because at the end of it all you can just create an bot that plays game for you better than everyone else, today's cheats are literally automation of aim by "moving" the mouse and movement by "clicking the keyboard", you cannot fix that at all, someone can just use your defined interfaces with a game and create an perfect player, that's how good cheats work nowadays, reverse engineering is a thing of a past and sadly you can't do nothing for games like CS2, because it's huge playerbase makes cheats like those profitable to implement, all other less known games having at least good netcode and small exploitability simply do not have state-of-the-art cheats implemented, because there's not big-enough market for them.

        Reply
    • Display picture for matthew
      matthew

      I get the enthusiasm. But there's technological problems with cheating. Software like 'trigger bots' look almost the same as regular skilled players from a server's perspective. In fact: just from a server's perspective alone you can't really detect good cheats. So that moves cheat detection to the client... which the client can control. If the client controls their end-point they can bypass any tampering measures you implement. There have even been new cheating techniques develop where external hardware (completely outside of the game) passes mouse inputs back to the OS which literally is undetectable from both client and server levels. So what we have here is a system that employed identity management and probably just banned cheaters. They couldn't recreate accounts since the same flagged identity was detected.

      Reply
  • Display picture for JD
    JD

    This reminds me of something FaceIT were doing way back, before they even had their own client-side anticheat. They used to download a unique, randomly generated file called "welcome.vtf" on the user's PC, then on subsequent connections query it's checksum using the sv_pure code. This let them fingerprint players across different steam accounts and IPs, similar to your cookie method. One problem with their implementation however was that any random community server could send its players a banned "welcome.vtf" file, then the next time they went to play on FaceIT servers they'd get hit with a false ban. Your solution isn't vulnerable to that.

    Reply
    • Display picture for Mo Beigi
      Mo Beigi

      That's a clever technique to use too! Using custom assets as a fingerprinting approach. Another downside of this though is a lot of players tend to delete asset folders regularly as textures and maps take up a lot of disk space over time. That could result in the fingerprint identifier being lost.

      Reply
  • Display picture for JamesIsAMoron_IsDumb
    JamesIsAMoron_IsDumb

    Now cheaters Can spoof every single HWID known to man and there’s almost nothing stoping them.

    Reply
  • Display picture for EgregiousEggplant
    EgregiousEggplant

    Storing an ID via VGUI is a stroke of pure genius! As someone who lives in a country where your IP-address is assigned dynamically every 24 hours or so, I'm not so fond of IP-bans. In the best case, I can just reconnect and rejoin a server simply by replugging my modem. In the worst case, my account gets banned because somebody clowned around on my currently assigned IP address in the past. Now if your community only targets NA, that's probably not a problem so take this 'criticism' with a grain of salt.

    Great writeup nonetheless. Thanks for sharing!

    Reply
  • Display picture for DoUCareAboutGPDR
    DoUCareAboutGPDR

    Hi! Just a quick note: your Anti-Cheat solution forces a cookie on users, which might violate GDPR since it requires user consent for non-essential cookies.

    Reply
    • Display picture for Mo Beigi
      Mo Beigi

      Hi, this community is based entirely in Australia and New Zealand; we have no European players or visitors.

      Additionally, this technique was used up until October 2017, which predates the enforcement of GDPR in 2018.

      Others have also pointed out that such activity may potentially fall under "grounds of legitimate interest" for fraud prevention, but I am personally unsure if such a solution, which does not ask for users' content, would be viable today in Europe.

      Reply
    • Display picture for NotAtTheTime
      NotAtTheTime

      At the time of the solution, GDPR wasn't in effect (Solution was feb-october 2017, gdpr came into effect in 2018)

      Reply
    • Display picture for Anon
      Anon

      I am pretty sure you can argue that cheater detection is essential in PVP multiplayer game. Especially that this cookie is random identifier stored on one computer and nothing more. GDPR is not a weapon against every organization. GDPR is about good practices inside companies and banning immoral financial models.

      Reply
      • Display picture for Gab
        Gab

        It is a persistent identifier nonetheless

        Reply
    • Display picture for Gab
      Gab

      That rule is not from the GDPR, but from the 2009 amendment of the ePrivacy directive.

      So, yes, it did violate it

      Reply
      • Display picture for Gab
        Gab

        Wait sorry, it seems that it was already present in the 2002 version, I misremembered.

        in any case, it only applied to European countries; the directive didn't try to enforce penalties on entities outside Europe, as the GDPR does (although, maybe there was still some risk for them​)

        Reply
  • Display picture for Henry
    Henry

    One other solution could be asking users to register on your server and deposit some amount of real money, e.g. 50 USD. In the agreement it could be that if they cheat, the deposit won't be returned and the account will be banned. So cheating would have a real price.

    Reply
    • Display picture for Peter
      Peter

      Simpler: Register and verification with Phone number and once per week a verification code. Problem solved.

      Reply
    • Display picture for Anon
      Anon

      This could be a good optional solution for players wanting to avoid running anti-cheat software, I can see those of us who are conscious of their invasiveness being willing to put up a deposit. If applied to everyone it would be a serious filter on the player-base, though.

      Reply
  • Display picture for jwallet
    jwallet

    Relaying on IP address only is really bad. Many providers offers dynamic IPs to their clients. So this guy probably banned legitimate players and grouped and linked all accounts with the real cheater that was caught months ago. What a shame.

    Reply
  • Display picture for patrick
    patrick

    This is something a common FiveM (a gta multiplayer server modification) server anticheat (FiveGuard) does. They store a token in localStorage as that gets persisted and many cheaters get banned from it because they couldn't figure it out :)

    Also, because FiveM uses a old version of CEF (which should probably be updated), that anticheat can also read audio device names to fingerprint users even further

    Reply
  • Display picture for Avaray
    Avaray

    Maybe I'm wrong, but I'm pretty sure that disabling MOTD entirely was possible on client side in that time.
    What if someone has it disabled? Did you just reject connection? Did you send him any message?

    Reply
    • Display picture for Mo Beigi
      Mo Beigi

      You're absolutely right! You could set the client side ConVar cl_disablemotd 0 to disable the MOTD but it was enabled by default. If a client joined the server with this setting we would kick them with a message that said "This server requires cl_disablemotd 1 to play". Most players just enabled it and re-joined the server.

      Most people just assumed it was so we could make sure to show the server rules to players as they joined which was partially true actually.

      Reply
  • Display picture for G...
    G...

    We did something similar for cs1.6 around 2k10, when i started reading i was very curious if it's the same. However our approach was simpler - when we want to ban player with this method we showed to him a MoTD which set cookie, and in server MoTD we had a script which check if cookie exists and if so we send request to server (or save flag to DB and read it from DB on server - i don't remember exactly). CS1.6 didn't have a feature to open browser in hidden window and as far as i remember it used IE 5 or 6 under the hood, so to be unbanned player had to go to IE and clear cookies which was almost impossible to figure out

    Reply