Third Steam Windows Client vulnerability, but not 0day
Previously on Privilege Escalation
Not long ago I posted about two vulnerabilities in Steam: CVE-2019-14743 and CVE-2019-15316. There was quite a story about how I tried to report them and didn’t succeed, how I’ve been banned, and how it took a public disclosure and community support to achieve results. Valve made it look like they’ve apologized and unbanned me at HackerOne, so I’ve decided to report another vulnerability with this service. On third time (
insert obvious Half-Life 3 joke here) it went rather well.
Vulnerability allows creating files with partially controlled content (or adding partially controlled content to files that already exist). Vulnerable service version is 188.8.131.52 (data from SteamService.exe file). First, I’ll describe how to use the vulnerability, then the possible impact.
Step 1. Environment
It’s necessary to close Steam application and stop “Steam Client Service”, if they’re launched. More often non-administrator users are not allowed to start and stop any service. But for this specific service Valve sets the rules, which allow every user to start and stop it.
Then create a directory in any user-controlled space (“C:\test”, for example). It’s needed to copy files Steam.exe and steamclient.dll from original Steam directory ("C:\Program Files (x86)\Steam" by default) to created directory. Create empty subdirectory “logs” (“C:\test\logs”).
Now edit the registry: in "HKLM\Software\wow6432node\valve\steam" branch change the value of “InstallPath” parameter to “C:\test\1\..”. Usually users without administrative privileges cannot write to HKLM branches, but not in this case. During installation Valve sets “Full Control” permissions for “Users” group on their registry branches, which allows any user perform any action with them.
Step 2. Little test
Let’s launch “Steam Client Service”. After it stops (it’ll happen automatically after a few seconds) check the contents of “C:\test\logs” directory – we will find there a file named “service_log.txt”. The content of the file will be something like this:
08/27/19 13:45:01 : ERROR: SteamService: Invalid file signature C:\test\1\..\bin\SteamService.dll
Note that path “C:\test\1\..” equals to “C:\test”, so Windows used second path for the job, but the first one was written to log. Let’s remove “service_log.txt” and move on.
Step 3. Adding more text
Interesting fact: when OS Windows interacts with paths which contain “\..”, it automatically simplifies such paths. Without any checks for in-between directories.
For example, path “C:\1\<test>\..” will be transformed to “C:\1” despite the fact that symbols “<” and “>” are not allowed in directory names.
At Step 1 we wrote a path to registry, now let’s add newline symbols to it. It could be done with writing a simple code, but it is also possible to do with regedit interface. You can open "HKLM\Software\wow6432node\valve\steam" registry branch and then select “Modify binary data..” in “InstallPath” parameter’s context menu. A hex-editor-like window will appear where you can make needed changes.
Let’s make another service test run and check the results of our actions.
Delete “service_log.txt” once again after test.
Step 4. Redirect created file
Users without administrative permissions cannot create symbolic links from one file to another. But there’s a trick – you can combine another types of links which are available for users without administrative privileges to achieve result close to file-to-file symlink.
First let’s create NTFS reparse point (sometimes called NTFS mount point) from “C:\test\logs” directory to “\RPC Control\”. “\RPC Control\” is not a regular directory, it can’t be viewed in explorer. It’s system object directory, which stores, for example, named mutexes, events and other similar objects. It’s not clear, why redirection with NTFS reparse point works with it, most likely because similar abstractions are used for directories in filesystem and object directories. It is possible to create symlink from object directory to file without administrative permissions. Let’s create symlink “\RPC Control\service_log.txt” <-> “C:\Path\to\file”.
As a result any call to "C:\test\logs\service_log.txt" will be redirected to file “C:\path\to\file”. To create such a redirect there are two requirements – directory, where reparse point is being created, should be empty and available for user to write into it. First requirement is the reason why we deleted “service_logs.txt” after each test. Second requirement is fulfilled with creation of initial folder in user-controlled space.
There is specific utility to create such a pairs of symlinks – CreateSymlink, which is available on GitHub (https://github.com/googleprojectzero/symboliclink-testing-tools/). Usage: CreateSymlink.exe <from> <to>.
In our case it is CreateSymlink.exe “C:\test\logs\service_log.txt” “C:\path\to\file”.
Putting it all together we get that at the start of “Steam Client Service” a file will be created at path, that was chosen at symlink creation. This file will contain input that we control (except first and last string). If we create symlink to existing file, content will be written to it’s end. All this action will be perfored by Steam Client Service as NT AUTHORITY\SYSTEM.
Now I shall tell about possible outcome in the order of its severity beginning with less important.
If symlink destination is "C:\Windows\System32\config\SAM" or "C:\Windows\System32\config\SECURITY", it’s unlikely that OS starts after next reboot.
2. Redirection of user in the internet
Let’s set symlink destination to "C:\Windows\system32\drivers\etc\hosts" and add there a string like "127.0.0.1 google.com".Result:
3. Horizontal EoP
Horizontal escalation of privilege is such an action that allows us to act not like a higher privileged user, but a same privileged user with access to different objects than us, for example, other user’s data.
Let’s set symlink destination to "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp\run.bat" and add there a string like "start C:\test\1.exe".
All files from "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp" directory are executed by users at their login. That way one user could force another to execute arbitrary code. Every string in .bat file will be executed line by line. The first and the last string will not do anything, but injected "start C:\test\1.exe" will be run.
There is a thing with injecting such command – symbols “\” will be revised during path normalization, so for it to work correctly it is needed to add a few “\..” to path in the “InstallPath”.
4. Vertical EoP
Vertical escalation of privilege is a common privilege escalation, for example from user without admin permissions to NT AUTHORITY\SYSTEM.
Quite often you can find software that executes text scripts with high privileges. We can add commands to such scripts and execute our code with higher privileges. I did not find such scripts in clean OS, so I cannot easily demonstrate an exploit like this. But I can point out .bat files that are created by NVIDIA and VmWare or logon-scripts for OS in domain.
In addition, creation of xml-files and ini-files with corrupted formats could be checked for privilege escalation. Sadly, there are too many options – creating tasks in TaskSheduler, working with .manifest, loading other libraries and many other. I think that what I’ve already described is enough to understand the possible impacts of the vulnerability.
For completion, I’ll give a boring timeline for this vulnerability.
Aug 26 – found vulnerability.
Aug 27 – unbanned at h1, published the report.
Sep 12 – fix released.
This is where I finish posts on Steam research – 3 vulnerabilities that were found during rather superficial analysis is already a big deal. To dig deeper I need more time and aspiration. Sadly, Valve’s attitude and HackerOne employees’ incompetence are very strong barriers.
Once more I want to thank all the readers, who helped make Steam more secure. I thank Valve for yet fixing the vulnerabilities and disproving my conspiracy theories. I thank HackerOne for providing the platform despite the fact that mostly they just interfered in delivering vulnerability information to Valve.
Vasily Kravets, Lead Expert