Valve Patches 10-Year Old Flaw in Steam Client

A remote code execution (RCE) vulnerability that existed in the Steam client for at least 10 years was fully patched only in March this year, according to security firm Context Information Security.

In July last year, Valve added modern exploit protections (Address Space Layout Randomisation – ASLR) to the Steam client, thus partially patching the RCE. According to Context senior researcher Tom Court, exploitation following this patch would have simply crashed the client.

Before that, however, all of the 15 million active Steam clients were vulnerable to RCE, the researcher claims.

The flaw was essentially a remotely triggered heap corruption within the Steam client library. The bug resided in “an area of code that dealt with fragmented datagram reassembly from multiple received UDP packets,” Court explains.

The Steam client communicates using a custom protocol that uses UDP and the bug resulted from the lack of a check to ensure that “for the first packet of a fragmented datagram, the specified packet length was less than or equal to the total datagram length.” The check, however, was present for all subsequent packets carrying fragments of the datagram.

Because the steam client had a custom memory allocator and lacked ASLR on the steamclient.dll binary, the bug could have been abused for remote code execution.

An attacker looking to exploit the issue would first have had to learn the client/server IDs of the connection, along with a sequence number. Next, the attacker would have had to spoof the UDP packet source/destination IPs and ports, as well as IDs, and increment the observed sequence number by one.

Steam uses a custom memory allocator that divides the large blocks of memory requested from the system allocator and then performs sequential allocations with no metadata separating the in-use chunks. Each large block has its own freelist, implemented as a singly linked list, the researcher explains.

Depending on the size of the packets used to cause the corruption when the buffer overflow occurs in the heap, the allocation is controlled by either Windows or Steam, with the latter found to be much easier to exploit.

“Referring back to the section on memory management, it is known that the head of the freelist for blocks of a given size is stored as a member variable in the allocator class, and a pointer to the next free block in the list is stored as the first 4 bytes of each free block in the list,” the researcher explains.

The heap corruption allows an attacker to overwrite the next_free_block pointer if a free block exists next to the block where the overflow occurs. If the heap can be controlled, the attacker can set the overwritten next_free_block pointer to an address to write to, and all subsequent allocation will be written to this location.

Because packets are expected to be encrypted, “exploitation must be achieved before any decryption is performed on the incoming data,” Court says.

This is achievable by overwriting a pointer to a CWorkThreadPool object stored in a predictable location within the data section of the binary, which allows the attacker to fake a vtable pointer and associated vtable, thus gaining execution, and a ROP chain can be created to execute arbitrary code.

“This was a very simple bug, made relatively straightforward to exploit due to a lack of modern exploit protections. The vulnerable code was probably very old, but as it was otherwise in good working order, the developers likely saw no reason to go near it or update their build scripts,” the researcher notes.

Court also points out that developers should periodically review aging code to ensure they conform to modern security standards, even if they continue to function.

Valve was alerted on the bug on February 20 this year and addressed it in the beta branch in less than 12 hours, but the patch landed in the stable branch only on March 22.

The views expressed in this post are the opinions of the Infosec Island member that posted this content. Infosec Island is not responsible for the content or messaging of this post.

Unauthorized reproduction of this article (in part or in whole) is prohibited without the express written permission of Infosec Island and the Infosec Island member that posted this content--this includes using our RSS feed for any purpose other than personal use.