Wednesday, June 12, 2024

I know security researchers haven't been looking at games because one of them has been literally telling you that it's RCE-ing you for 20 years and you're just finding out today

This is a pretty bad case of "better late than never," since I've known about this problem for almost as long as it's been around.  This is about a directory traversal/RCE vulnerability in Unreal Tournament (CVE-2024-34492).

Really, there's not much point in disclosing a vulnerability in a 25-year-old game except for some kind of closure, but I think the sheer obviousness of this (and another thing I'll get to in a second) is amazing evidence of how much game developers have dodged a bullet from sheer disinterest in games as attack vectors.

That disinterest is starting to wane though.  There have been a few high-profile incidents lately, and it's really past time for developers to start taking the security of their products seriously before they turn into serious problems.

I reported this issue to Epic's security team in August 2022.  They didn't respond, but they did delist Unreal Tournament from sale shortly after.  Not sure if the two are related.  I reported this to the OldUnreal team currently maintaining Unreal Tournament 90 days ago, so I think responsible disclosure time has passed.

Anyway, this originally started in 2005 when someone discovered the "DLL trick" and used it for UTDC, a third-party community-created anti-cheat mod, and the same trick was later used by the ACE anti-cheat mod.

Normally, when you connect to an Unreal Tournament server, it downloads any mods that the server is running, and it drops them into a cache directory with a hash-based filename and adds it to a lookup list that maps it to what the server says its filename is.  Only a few file types are permitted to be downloaded from the server in the first place, and DLLs are not one of them.

Older Unreal Engine games also support native DLLs corresponding to their packages, supplying functions that are executed by native code in the DLLs.

For quite a while, if you connect to an Unreal Tournament server, you'd be greeted with an NPLoader popup that looks something like this:

 

If "native mods" isn't setting off alarm bells I don't know what will.  The game client is not supposed to be downloading DLLs, yet somehow this mod is capable of "installing" DLLs by itself.

The way this works under the hood is that in Unreal, most assets are converted to internal formats, but music files are just raw binary blobs that are copies of the original file.  Someone had the idea to import a DLL as a music file from Unreal Tournament's System directory, then have the mod load the Editor package and export the asset, which dumps it into the client's System directory, causing the game to load it the next time it connects.

There is no restriction at all on the import path, so this can really drop any file anywhere on the user's machine.  Also, while this popup dialog is nice, it is completely unnecessary - A mod an export a file with no user interaction whatsoever.

The simplest solution to this would be to update the game client to forbid the client from loading the Editor package.


This probably isn't the only serious problem with older Unreal titles.  I've seen evidence that the UnrealScript loader, despite being strictly typed, does almost no validation of the bytecode at all, which means UObject pointers can be converted to integers and vice versa via constructed bytecode, which is almost certainly RCE-able by forging a UObject pointer into an attacker-controlled buffer somehow.

I might write a later piece on how to secure your game against malicious mods, especially if you're going to allow mods to contain code, but for now: Don't play Unreal Tournament on untrusted servers.

No comments:

Post a Comment