How It Started
So one day I was browsing ZDI (usually its the same sort of targets, lots of Foxit bugs, Adobe, Ivanti, etc) and noticed a couple entries by @izobashi (ZDI-22-537, ZDI-22-538) for Epic Games Launcher, there were two things that stood out:
- It wasn’t patched at time of advisory release (which means no patch in 120 days since reporting it, maybe unpatched forever?)
- It was file overwrite and file deletion bugs which can be leveraged for LPE, and affected the installer (these bugs are common and very familiar to me)
Now as a gamer (albeit not one with Epic’s launcher installed) I’ve had the displeasure of noting multiple vulnerabilities in gaming related software (alongside a strong dislike for anti-cheats in my kernel or acting as a hypervisor, though I understand why they do), I figured I’d check now if I can find these same bugs in the latest version of Epic’s launcher.
Although we don’t have a PoC or really any detailed information from the ZDI listings, the bugs are familiar enough that we can jump right in with our trusty ProcMon and see what we find.
Finding the bugs
After installing Epic’s launcher I immediately find the installer in C:\Windows\Installer (shh! its a secret directory), I know this is Epic’s MSI due to the signature matching Epic as expected:
The reason bugs in installers are common can be noted to a few factors:
- They typically auto-elevate to SYSTEM (even if you’re just a lowly non-administrative user)
- They can be executed in install / remove / repair modes that perform various operations, including file operations (copy, rename, delete) and can run arbitrary bundled scripts
- People don’t spend security $$$ on hardening their installers? (I don’t know, but it sure seems like it)
Before we go any further, lets configure our ProcMon, but first — why ProcMon?:
- Tells us what processes are doing (to an extent)
- What files they’re accessing
- What permissions they’re operating at
- What files / registry entries they’re reading / writing / deleting
- Is filterable
- Write rules to only show / capture what you’re interested in
Now to configure ProcMon, what are we looking for exactly?:
- File creation/opening events that satisfy the following:
- Operating on folders or files we can control
- Why? So we can redirect them via symlinks of course
- If it overwrites a file in C:\windows\system32, how would our lowly non-admin user control it?
- If it overwrites a file in C:\users\lowly_user\Desktop that we can control, its a different story!
- (Or any other location we have write or similar access to)
- Why? So we can redirect them via symlinks of course
- ?? (There are more potentially interesting events, like paths or files that don’t exist that we may create, etc… but for this exercise we don’t care)
- Operating on folders or files we can control
Now you may think if we exclude the following folders, that’d be good enough to meet our requirements above:
The point of the above is:
- Capture
CreateFile
andLoad Image
operations - Ensure username contains
NT
(e.g. NT SYSTEM) - Exclude folders we can’t modify / control:
- C:\ProgramData\Microsoft
- C:\Program Files*
- C:\Windows\
Can you think what the problem with the above excluded directories is?
..
…
….
Well actually there are multiple (for example, C:\windows\temp is typically user-writable! Meaning we actually can have some control over the contents of this directory, yet in the above filters we exclude it, although this isn’t an issue for this particular example).
The actual issue is excluding all of C:\Program Files
, because Epic actually applies a permissive DACL on c:\Program Files (x86)\Epic Games\Launcher
and its subfolders! (Not a great thing to do in general…)
This can be verified with icacls:
(Tip: Enumerate ACLs on everything -> install software -> enumerate again -> diff!)
Ok so lets ensure the path C:\Program Files (x86)\Epic Games\Launcher
is included in our procmon filter and start capturing (In this case I’m going to remove the exclude for C:\Program Files
and specifically include the launcher path above — once we have the trace we can play with the filters to see other interesting events too, like searching for operations that begin with Set
to see renames, deletions, etc).
Lets right click the .msi file and press Repair
, wait for it to complete and see if anything interesting happens.
Well that’s a lot.
To be honest its not surprising, the .msi in repair mode is there to, well, “repair” its files (which is typically achieved by replacing them with a pre-packaged good version).
Since the ACLs on this folder are weak, what would happen if we were to redirect one of these files elsewhere?
To test this, I’m going to show the two 0-days, first is the file overwrite.
Lets start by grabbing the symbolic testing tools from GPZ and compile them.
Now lets turn a folder (in this case, C:\Program Files (x86)\Epic Games\Launcher\Engine\Binaries\Win32
into a symlink pointing to \RPC Control
:
(If you can’t delete Win32, try stopping Epic’s running processes first)
Ok now lets try the repair operation again and see what happens.
Ok so its looking for a DLL in our Win32 folder, however Win32 now points to \RPC Control
and there doesn’t exist any \RPC Control\msvcp140_2.dll
for the target to obtain a handle to.
Lets try creating this, and redirecting it to C:\Windows\System32\License.rtf
as an example, now lets first note the size of our License.rtf
file:
Ok so yours is likely not 7 bytes like mine, but note that mine only allows modification by Administrators or higher, users just have RX.
Now lets create the link to it:
Now press Retry
on the msi error, and you’ll notice it continues and pops up another error (for a different DLL!)
However, note that License.rtf has been overwritten!
This is the first 0-day, arbitrary file overwrite!
To ensure this sticks, we can now delete Win32, recreate it as a regular folder (mkdir Win32
) and press Retry, this should cause the installer to continue without any more errors and leave the file overwritten.
However, we can turn this into an arbitrary deletion vulnerability by causing the target to now delete License.rtf!
We can do this by simply pressing Cancel
instead of retry! The target MSI will rollback its operations, and this will cause it to delete the overwritten file entirely!
With these two bugs (file overwrite + file deletion) we can actually leverage them for LPE, there’s other posts on achieving this (e.g. https://www.zerodayinitiative.com/blog/2022/3/16/abusing-arbitrary-file-deletes-to-escalate-privilege-and-other-great-tricks)
Whos taking bets how long these bugs will remain as 0-days in Epic’s launcher?