Coding Range

(Fixed) CS:GO server takeover vulnerability

February 22nd, 2013

Counter-Strike: Global Offensive yesterday updated to version which fixes a nasty bug that could have been used to take over a random remote server.

CS:GO (14/02/2013) introduced the console variable sv_workshop_allow_other_maps. The default setting was true. When a server was idling empty, the matchmaking server could tell it to download and run any map on CS:GO’s Steam Workshop. This sounded great - it provided a way to players to be able to try out new maps while providing another way for server admins to fill up their empty servers.

Unfortunately, CS:GO also includes a map entity that’s been in the Source engine the entire time - point_servercommand. This entity lets the map run any command on the server. Adjust gravity, kick players, change the remote console password, shut down the server, etc. I put together a test map a couple of nights ago that consisted of 6 walls, 8 spawn points, a handful of lights, a logic_auto (to run when the map loaded) and a point_servercommand. The logic_auto entity triggered the point_servercommand with two server commands:

  • rcon_password "testing" set the server’s remote console password to “testing”.
  • sv_gravity 10 changed the gravity to 1/8th of it’s normal value, to prove that the point_servercommand had run. Possibly the server had some hyper-paranoid security plugins, and I wanted to make sure that the map had actually tried to execute the commands.

After testing the map on a local server, I uploaded the test map to Steam Workshop and asked Matchmaking to put me in a server running that map. Unfortunately for GamePlanet New Zealand, Steam picked one of their servers, and surprise surprise, I suddenly had full remote console / admin access.

I also tried embedding a Valve Server Plugin (VSP, a .so or .dll file that exposes a plugin to Source Dedicated Server), but fortunately Valve were smart enough not to let the game load a binary plugin from a map.

Monday night I mentioned within virtual hearing range of a Valve employee that this might be possible. Tuesday night I verified it. Thursday it was patched, though it wasn’t mentioned in the update notes. Only later on the HLDS mailing list was it pointed out that:

point_servercommand was amended to only function when a map is played offline.
It was deemed a server security vulnerability.

Great work, Valve.