What a one line change did to the Chrome sandbox
googleprojectzero.blogspot.com
googleprojectzero.blogspot.com
For anyone who is interested in the history, this type of Restricted Token & Job Object sandbox was, as far as I know, first used in MOICE (Microsoft Office Isolated Conversion Environment). This was created by Microsoft's Office Trustworthy Computing group to isolate the conversion of `.doc` to `.docx`. David LeBlanc blogged about it in 2007, with his "Practical Windows Sandboxing" series[0][1][2]. Of course a third party may have independently discovered the same techniques but kept it to themselves.
The state of the art has improved since then but the general principles are the same.
[0]: https://docs.microsoft.com/en-us/archive/blogs/david_leblanc...
[1]: https://docs.microsoft.com/en-us/archive/blogs/david_leblanc...
[2]: https://docs.microsoft.com/en-us/archive/blogs/david_leblanc...
This type of stuff is of course in browsers, and they are doing great work in this area, it is just a shame it is hard for the rest of us to use.
Things like video encoders and decoders are much slower in webassembly.
Of course though, you're right that it'll still incur a performance penalty.
That way, the developer can tweak the input to the compiler to get exactly the sequence of instructions they wanted.
They can also hand write the output assembly, and put a patch in to the compiler saying "this generated assembly is faster that what you generated, so please generate this in the next version".
It does not stop all kinds of issues, so it is not secure on its own either.
A seccomp-like mechanism on top of restricted tokens could be quite strong. The GPU process could be denied the ability to query or modify processes entirely. Similarly, it could be denied the ability to call CreateProcessAsUser at all.
Or, you can slap a Service Control Policy on the whole account and then boom, nobody can do Whichever Bad Thing that you're worried about Today.
The former approach requires me to reload the entire graph of dependencies and assumptions into my head whenever I want to make a change or ask my mental model of it a question. The latter approach allows nearly-reflexive answers.
Thx
Bear in mind, browser security comes from many levels. A sandbox escape first requires that someone has gotten malicious code to execute in your browser. And the first line of defense is blocking a lot of extraneous and harmful code from running in the first place.
https://securelist.com/chrome-0-day-exploit-cve-2019-13720-u...
But the takeaway from this post is more that perfect safety is difficult / impossible to achieve.
(Disclosure: I work for Mozilla, but not on this)
That said, safety is about much more than just sandboxing.
I really enjoyed reading this - thank you.
There are these security token objects that are used to keep track of what a process can and can't do. (Think of them as collections of capabilities.)
The design of the system is that you can create a less powerful child copy of your security token (dropping capabilities), and assign this token to a child process when you create that child. A process is free to change its security token to be any child of its current token or any sibling of its current token (plus a few other restrictions).
Someone screwed up a change to the Windows 10 kernel such that when the browser creates a restricted child of its token, the less powerful token is actually marked as a sibling of the browser's token, which is itself a sibling of many other tokens in the system. This means that the token the browser uses to create its child sandbox process has many unrestricted sibling tokens.
The rest of the exploit involves figuring out how to get a handle to a security tokens that a few other processes make publicly available (sounds very strange to me) and which aren't as restrictive as the security token used to create the sandbox process.
If the sandbox's token were (correctly) a child of the main browser process's token, then these other tokens found wouldn't be siblings of the sandbox's token, and the sandbox process couldn't switch to using these security tokens. However, because of the screwed up family tree of these tokens, the sandbox is free to switch to these other security tokens.
It is so complicated that even the people maintaining it don’t understand it, and they accidentally added a privilege escalation path.
The author uses that to use a Chrome sandbox bug to escape from the sandbox.
The real WTF is the complexity and obscurity of the security primitives being exported from the kernel. Arguably, all major operating systems have the same issue, and are getting worse over time — I doubt anyone understands all of the layers of privilege checking mechanisms that have been bolted on to Linux, Windows or Mac OS over the years.
Then it's a long detailed post about how you can exploit the bug, while missing some critical parts so you actually can't exploit it for real.
About the critical missing part, I was thinking about this :
> Let’s focus on escaping the GPU process sandbox. As I don’t have a GPU RCE to hand I’ll just inject a DLL into the process to run the escape.
From what I understand, a GPU RCE would allow escaping the sandbox from remote while injecting the DLL requires a good control on the machine. But your post was not about a GPU RCE so it totally makes sense to not do it. I may be very wrong because I am not a security expert, I only read MISC (a French magazine about security) on the beach.
I was originally going to write about using the same bug in Firefox. The default content sandbox in FF is basically the same as Chrome GPU, so any untrusted HTML/JS coming from the web could exploit RCE to get into a sandboxed process where this bug could be used. I decided considering they're using the Chromium sandbox code it really should be about Chrome.
That said, this sandbox escape isn't being presented for practical reasons. It'd be incredibly noisy to do and potentially unreliable due to the various mitigations you have to circumvent. Any "real" attacker would likely use an exploit in the kernel's WIN32K component which is accessible from GPU.
The problem with dealing with Windows and by extension Microsoft is there's no way of inspecting what they've changed from version to version other than by RE or having test cases. However, we try and avoid writing unit tests for behaviors Microsoft's responsible for, but of course in many cases MS don't have those tests either so these things fall through the cracks.
When you say "unit tests", this makes sense. But wouldn't it be wise to have integration tests in place that would guard against such regressions, either in your code or Microsoft's?
I can't speak to what MS do testing wise, considering the age of some of this code it seems likely there's no test for this specific functionality otherwise you'd assume it would have been noticed. Testing for security defects is inherently difficult anyway, especially logical flaws where you don't get a nice crash. This case is different but in general you usually need some specific setup process to get the system into a vulnerable state which is hard to achieve without knowing ahead of time the bug you were trying to detect.
I think it’s a great model, but it breaks down when the new version is a feature/usability regression vs the old version.
Once that started happening more often than not, the “aas” models came out, where the vendors started force upgrading users instead of trying to compete with version N-1.
This is worse for the users, but better for deadline-focused middle management, so it’s become incredibly popular.
Important customers could get a hotfix. For anyone else reporting bugs was pointless.
I'd also add that Microsoft used to be notoriously bad at security, such that even Mac owners would make fun of them. We're still dealing with the design decisions made during that era. It's only since XP SP1 that security was taken more seriously and it wasn't until Vista that they truly started to grapple with the whole mess from the ground up.
Although, in reality, Mac owners really only were secure by way of being too few and far between to bother writing malware for.
Just this past year, Apple essentially implemented UAC into OS X.