Background

ezQuake has a "security" plugin which is supposed to validate that other players on a server is using an official (unmodified) version of the game binary. This is done by sending an f_version query to the server, to which all clients will reply their client versions and a magic CRC to. The security plugin both generates this response for the player, and checks other players' responses to see if they are valid. This together with f_server, to check the server connected to, to avoid proxy cheating, and f_modifed, to check for modified data files, is supposed to prove that a player isn't cheating. Unfortunately not only is the basic idea completely flawed, ezQuake's implementation is also pretty bad and on the edge of completely useless.

Note

On the day of the release of this page, a newer version of the Ezquake "security" plugin was released. It's a new implementation. While it still has many flaws, what is described in the "implementation problems"-section may or may not apply to this new plugin. The rest remains fully valid.

The implementation notes apply to release 1144.

The design problems

f_version

The biggest problem of the design is that you're asking the client itself, running on a machine totally under the control of the user, to validate that it is genuine. This can never work, nothing prevents it from lying, no matter how much you try to put the reply through a hashing function. There are a few easy ways to break this. One is to connect two clients to a special proxy, where one client is given control over the real connection to the server, and the second client only acts as a slave to reply to f_version. The first client would be the one with the wallhack, the second one the "genuine" client. This method breaks both current Fuhquake and ezQuake, but also any future versions of these clients basing their "security" on these kinds of checks.

f_server

What the f_server check doesn't take into account, is that the IP the client *thinks* it is connected to might very well not be the real IP it is connected to. With iptables on Linux, it's extremely easy to redirect packets meant for one host to another. This means that you could connect your client to a proxy with an aimbot, while your client would still think it was connected to the real server. The f_server check is useless then.

The implementation problems

The ezQuake implementation of the security plugin has a number of flaws, which makes it easy to run a modified binary with the original security plugin and still fully validate, and also makes it easy to create completely seperate clients or even bots which get validated by genuine ezQuake clients as being an unmodified ezQuake.

Binary validation

The ezQuake security module attempts to validate that the running game binary is an official release, but doesn't try to validate the security module itself. This means that it is easily possible to modify the security module to validate a different binary than the running one. Once this is done, you can run modified ezQuake clients with the original security plugin, only with a slight modification. If you don't want to modify the security plugin, you can make a custom readlink() function and preload it with LD_PRELOAD, overriding the libc function.

The validation code

The validation code consists of two different things run through a hashing function: The client's player slot number on the server and rand(). No attempt to include globally known server state data like serverinfo or the clients' userinfo strings(name, team, colours) has been made. This means that it is possible to simply pull out 32 strings from the security module and reuse them over and over again. This way you could implement these 32 strings into any client and have that client be validated as a genuine ezQuake client.
Mark Olsen