Information

File: common\crypto_libsodium.cpp
Function: AES_GCM_DecryptContext::Decrypt()

Throughout the code responsible for handling incoming messages there is an assumption that the maximal incoming message size is 1300 bytes:

/// Max size of UDP payload.  Includes API payload and
/// any headers, but does not include IP/UDP headers
/// (IP addresses, ports, checksum, etc.
const int k_cbSteamNetworkingSocketsMaxUDPMsgLen = 1300;
...
/// Use larger limits for what we are willing to receive.
const int k_cbSteamNetworkingSocketsMaxEncryptedPayloadRecv = k_cbSteamNetworkingSocketsMaxUDPMsgLen;
const int k_cbSteamNetworkingSocketsMaxPlaintextPayloadRecv = k_cbSteamNetworkingSocketsMaxUDPMsgLen;

However, when receiving the messages from the UDP socket, they are read with a size limit of 1300 + 1024:

// Recv socket data from any sockets that might have data, and execute the callbacks.
// EI-DBG: Actual recv buffer is 1024 MORE than the max length...
char buf[ k_cbSteamNetworkingSocketsMaxUDPMsgLen + 1024 ];
...

sockaddr_storage from;
socklen_t fromlen = sizeof(from);
int ret = ::recvfrom( pSock->m_socket, buf, sizeof( buf ), 0, (sockaddr *)&from, &fromlen );
...

This size mismatch breaks the incoming MTU assumption made when handling incoming encrypted messages, enabling an attacker to do the following:

  1. Find a game server / client that was compiled to use libsodium for the symmetric cryptography layer (default library is OpenSSL)
  2. Establish a connection with the target using the sockets protocol
  3. Send a large encrypted message, of size > 1300
  4. The encrypted message will be decrypted into a stack buffer of size 1300 bytes, leading to an overflow

Crash Trace:

*** stack smashing detected ***: <unknown> terminated

Attachments:
CVE_2020_6018_PoC_libsodium.py
steamnetworkingsockets_messages_certs_pb2.py
steamnetworkingsockets_messages_pb2.py
steamnetworkingsockets_messages_udp_pb2.py
steam_networking_sockets.py

References:
https://research.checkpoint.com/2020/game-on-finding-vulnerabilities-in-valves-steam-sockets
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-6018
https://github.com/ValveSoftware/GameNetworkingSockets/commit/bea84e2844b647532a9b7fbc3a6a8989d66e49e3