Home > Vulnerabilities > Steam UAC bypass via code execution

Steam UAC bypass via code execution

Like many other gamers, I love Steam. Not only is it ridiculously convenient, but it’s also become a pretty awesome platform for indie game developers to get their games out there. It provides a online store platform for 54 million users, and most of the time it does an excellent job. That’s partly the reason why I’m so frustrated with Valve right now.

I spent a good few hours playing with a bug I found in Steam, and then made an effort to provide Valve with a clear, concise, detailed security vulnerability notification. Their response has been one of pure opacity, with not a single ounce of professional courtesy.

On Tuesday 17th September 2013, I submitted a vulnerability report to Valve, the full text of which follows:

I have discovered a vulnerability within the Steam client application that allows for arbitrary memory copies to be initiated within the Steam process. These issues can be triggered at multiple crash sites, and range in severity from unexploitable crash (denial of service) to full compromise of the process.

Technical details:

The shared memory section GameOverlayRender_PIDStream_mem-IPCWrapper does not have an ACL applied to it, so any user may open a handle to it with all privileges. This is especially important in multi-user systems such as terminal services, or in situations where other potentially risky processes are sandboxed into other user accounts within the same session.

By opening a handle to the section and writing random garbage data, then signalling the Steam3Master_SharedMemLock wait handle (which also does not have an ACL) it is possible to cause the Steam client to crash. I have discovered multiple locations where the crash may occur, and many are within REP MOVS copy instructions. In some cases it is possible to control the destination address (EDI), the source address (ESI), and/or the memory at the target site of ESI. In some cases other general purpose registers were modified. By carefully crafting a payload, it would certainly be possible to cause code execution via heap corruption, e.g. by overwriting a callback pointer. Despite the use of ASLR and DEP on the process, certain modules (e.g. Steam.dll, steamclient.dll, CSERHelper.dll) are not marked as ASLR supporting. It is possible to use a technique called Return Orientated Programming (ROP) to bypass ASLR and DEP in cases such as this, where there are non-ASLR modules loaded into the process.

I have created a proof of concept application, which can be provided upon request, though it should be trivial for a developer to discover the source of the vulnerabilities.

Mitigation:

The fix I would propose is that an appropriate explicit ACL is set on the afforementioned objects, enforcing that only the user that created the Steam process can access the object. Additionally, I would recommend that proper bounds and sanity checking is enforced on the shared memory object. Furthermore, it would be prudent to ensure that memory copy operations (e.g. memcpy) are performed using SDL approved functions, such as memcpy_s.

Responsible disclosure policy:

This ticket serves as initial notification of a security issue. Please respond within 30 days, detailing your acceptance or rejection of the report, the proposed mitigation (if any), and patch timescale. If no satisfactory response is received within 30 days, it will be assumed that you do not consider the issues in this report to constitute a security issue, and they will be publicly disclosed. My normal public disclosure timescale is 90 days after initial notification, but this can be extended upon reasonable request. Most importantly, please remember that this is an invitation to work with me to help improve your product and increase the security posture of your customers. Should you require further information about the issue, or any other aspects of this notification, please contact me.

Thank you.

On Sunday 22nd of September 2013, after further pondering the issue, I provided this addendum to the report:

Impact update:

On further consideration, the impact of this issue is not exactly as described above. Due to the location of the shared memory section object within the object manager hierarchy, it is not accessible across sessions unless the reading process is running in an administrative context. This negates any cross-session privilege escalation, so one user session cannot directly attack another in this manner.

However, an additional impact has been discovered. If the attacking process runs in the same session as the user (e.g. malware) and waits for Steam to escalate its privileges to an administrative context via User Account Control (UAC), it may then exploit the vulnerability and gain UAC escalation. This completely bypasses the UAC process and could allow local malware to jump from a limited or guest user context to a full administrative context. Not only is this directly problematic for home users, but it becomes significantly important for domain environments where workstation security is enforced by group policy, which is bypassable via the administrative security context.

I feel that this new impact scenario is more significant, since it targets the most common configuration of Steam, i.e. a single-session machine.

As noted before, please feel free to contact me if you have any questions. For absolute clarity, the cut-off point for non-responsiveness is the 17th of October 2013, i.e. 30 days after initial notification. Please respond before then as per the responsible disclosure policy detailed above.

Thank you.

I recognise that this isn’t exactly an earth-shattering vulnerability, as UAC isn’t “officially” a privilege segregation. That said, it’s significant enough to warrant fixing, especially as it results in memory corruption. Furthermore, I’m sure someone could find a way to utilise the issue in a much more interesting way than I did.

A Valve employee under the name of “Support Tech Alex” responded the next day, apologising for the delay and informing me that the details would be forwarded to the appropriate department. Excellent, I thought. I thanked him, and waited. A week passed, then two. Still no response.

On Wednesday 9th October, I discovered that they had closed the ticket. I asked why, and their response was as follows:

Hello Graham,

Unfortunately, you will not receive a notification about any action taken as a result of this report.

If you have a business related inquiry, please visit http://www.valvesoftware.com/

If you have any further difficulty, please let us know.

This annoys me, and I think it demonstrates a fundamental lack of understanding of whitehats on Valve’s part. In my opinion and experience, what drives a whitehat isn’t a lust for rewards, or free swag, or even being thanked by the company (though that is nice). What drives a whitehat is the quest for technical knowledge, and the satisfaction of having helped fixed a security issue. When a vendor cuts a whitehat out of the loop, and leaves them hanging without even saying whether they’re going to look into it, it kills all motivation. Not only is it unprofessional, but it’s also downright rude to reward a person’s hard work with little more than contempt.

I didn’t go into this expecting Valve to pay me or even send me a T-shirt for finding the bug. I did, however, at least expect to get something along the lines of “thanks, we’ll fix that, should get pushed out in the couple of months”. Instead what I got was opacity and avoidance, and that’s not the way to deal with security notifications. Hopefully a public shaming will do you some good, Valve. Treat whitehats well, and you’ll do well. Treat whitehats badly, and you might find that they take their reports elsewhere.

Update: In my sleep-deprived state last night, I forgot to update this draft before publishing it. There’s actually a much bigger vulnerability here: Steam gives itself SeDebugPrivilege, which allows it to bypass ACLs on OpenProcess calls, meaning it can inject code into any other process on the system, including those running as SYSTEM. It’s a full privesc. I’ve written a follow-up post that explains this in more detail.

About these ads
Categories: Vulnerabilities
  1. Mr10001
    October 11, 2013 at 17:58

    Pretty sure they use some unsigned DLL’s too.

  2. ThePaSch
    October 11, 2013 at 23:25

    To be fair, you were kind of a dick. They have no obligations to tell you anything, and frankly, starting things off with a 30-day ultimatum is not the best way to approach anyone.

    “A Valve employee under the name of “Support Tech Alex” responded the next day, apologising for the delay and informing me that the details would be forwarded to the appropriate department”

    What more do you want? I get that you’d like some recognition for finding this issue, and I also get that it’s frustrating to be waved off like that; however, if you hadn’t outright threatened them in _the first report you sent them_, they might have been a little nicer.

    • October 12, 2013 at 11:20

      I’m going to guess that you haven’t written (or read) many vulnerability disclosures to companies. The timescale and release policy is standard procedure for security disclosures – it’s not a threat. Keeps us from getting screwed by certain unscrupulous companies if they don’t fix and we go public, because some of them try to crucify the whitehat as a PR move. If all companies were responsible in their handling of security issue reports, and didn’t act like douchenozzles to whitehats when we do full disclosure, then we wouldn’t need to state these policies. It’s yet another case of a few ruining it for the many.

      Another reason for stating that policy is that it’s professional courtesy to inform them of your intention – if you intend that the bug will be publicly disclosed as some point, then it’s worth telling them that. It’s not a threat, it’s just a notice so that they can plan accordingly. I’d feel douchey if I didn’t do it.

      They were given 30 days to respond, they didn’t do so adequately within the first 28, after which they’d closed my ticket and told me I wouldn’t get any feedback. There was no ticket status, nor any indication as to whether anyone would even look into it. I consider 30 days a pretty comfortable timescale to give me a response, and if after 28 they’ve made it clear that they’re not going to do that, then I don’t think it’s unfair to go for full disclosure.

  1. October 11, 2013 at 09:08

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 640 other followers

%d bloggers like this: