← All breakdowns
RCEcriticalValve

RCE on the Steam client via a Server Info buffer overflow

A malformed game-server 'Server Info' response overflowed a fixed buffer in the Steam client, giving an attacker control of execution - a reminder that memory-safety bugs in native clients are still very real RCE.

Read the original HackerOne report

A crafted response packet from a malicious game server overflowed a fixed-size buffer inside the Steam client - a memory-safety vulnerability that converted a routine game-browser feature into a remote code execution primitive running on millions of desktops.

Stay Legal

This breakdown is for educational purposes and understanding real-world vulnerabilities. Only test techniques like these on systems you own or have explicit written authorization to assess.

The Target

The Steam client by Valve is installed on hundreds of millions of Windows, macOS, and Linux machines. Among its many features is a server browser that queries game servers for status information - the "Server Info" response. This response is an attacker-controllable packet because anyone can run a game server and respond to Steam's query with arbitrary data. The client parses that data locally, making every field in a server's response a potential attack surface against the Steam client process.

The Vulnerability

The vulnerability was a stack-based buffer overflow - a classic memory-safety bug - in the code responsible for parsing a "Server Info" (A2S_INFO) response packet. The Steam client allocated a fixed-size stack buffer to hold a field from the server's response (such as the server name, map name, or game description). When copying that field into the buffer, the code did not check whether the incoming data exceeded the buffer's capacity.

An attacker who controls a game server can craft the response so that a field is longer than the allocated buffer. The excess bytes write past the end of the buffer on the stack, overwriting the saved return address or other control-flow data. When the function returns, execution jumps to an address of the attacker's choosing - typically a location containing attacker-supplied shellcode or a ROP gadget chain.

Because the Steam client runs with the privileges of the logged-in user, successful exploitation means arbitrary code execution in the context of the victim's account - read/write access to all user files, credential theft, persistence, and the ability to interact with the Steam API on the victim's behalf.

How It Was Found

The researcher reverse-engineered the Steam client's game-server query protocol (the Valve A2S protocol) and the client-side parsing code. Fuzzing or manual inspection of the buffer-handling routines for response fields revealed the missing bounds check. The attack scenario is straightforward: set up a game server (or a server emulator), connect to it from the Steam client's server browser, and observe the crash when an oversized field is sent.

An illustrative malicious A2S_INFO response (conceptual byte layout):

# Valve A2S_INFO response - attacker-controlled game server sends:
# Header: FF FF FF FF 49
# Protocol: 11
# Name field: [255 bytes of 'A' to overflow a smaller stack buffer,
#              followed by overwrite bytes targeting the saved return address]
# Map, folder, game fields: padding to maintain valid-looking structure
 
python3 -c "
import socket, struct
header   = b'\\xff\\xff\\xff\\xff\\x49'
proto    = b'\\x11'
# Name field crafted to overflow the receiving buffer
name     = b'A' * 300 + b'\\xde\\xad\\xbe\\xef'  # illustrative overwrite
payload  = header + proto + name + b'\\x00'
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto(payload, ('VICTIM_IP', 27015))
"

In practice, exploiting this reliably requires defeating mitigations (ASLR, stack canaries) - but the base overflow was confirmed to crash the client, and the researcher demonstrated a working exploit.

attacker@kali: ~
 

Impact

  • Remote code execution on the victim's machine - the attacker controls execution in the context of the Steam client process, which runs as the logged-in user.
  • The exploit is triggered simply by the victim browsing to a malicious server entry in the Steam server browser; no file download or explicit user action beyond clicking "Server Info" is required.
  • With code execution, the attacker can exfiltrate Steam credentials and session tokens, access any files the user can read, install persistent malware, and pivot to other local services.
  • The scale of exposure is enormous: Steam has hundreds of millions of registered accounts and the client is ubiquitous on gaming machines.

The Fix

Valve patched the vulnerability by correcting the buffer-handling code in the server-info parsing routine:

  1. Bounds-checked copies - replace unbounded strcpy/memcpy operations with length-aware equivalents (strncpy, strlcpy, or C++ std::string) that cannot write past the destination buffer.
  2. Input length validation - enforce protocol-defined maximum field lengths before copying; discard or truncate any field that exceeds the expected size.
  3. Compiler-level mitigations - stack canaries (-fstack-protector-strong), ASLR, and DEP/NX make exploitation significantly harder even when an overflow exists; all modern Steam client builds use these.
  4. Fuzzing the parser - game-server response parsers should be fuzz-tested against malformed and oversized inputs as a standard part of the development process.

What You Can Learn

  • Attacker-controlled data sources are not just HTTP parameters. Any data the client parses that originates from an untrusted party - game servers, peer packets, file formats - must be treated as potentially malicious input.
  • Fixed-size stack buffers + untrusted input = buffer overflow. This is a decades-old pattern. Modern languages (Rust, Go, memory-safe C++ idioms) eliminate the class entirely; C and C++ require disciplined length checking at every copy.
  • Client-side parsing is high-value attack surface. Browsers, email clients, game clients, and PDF readers all parse complex data from untrusted sources - historically a rich source of critical vulnerabilities.
  • "It only crashes" is not the end of the analysis. A crash typically indicates corrupted control-flow data; with enough effort, most crashes in critical parsing code can be turned into working exploits.
  • Compiler mitigations delay, not prevent. Stack canaries, ASLR, and NX raise the exploitation cost but do not eliminate the root cause; fixing the memory-safety bug is the only reliable solution.

Canonical Report

Full technical details are in the original HackerOne disclosure: HackerOne #470520 - RCE via malformed Server Info response overflowing a Steam client buffer

Learn the skill behind it

Exploitation & Getting a Shell

Open lesson