Chrome OS exploit: WebAsm, Site Isolation, crosh, crash reporter, cryptohomed
bugs.chromium.org
bugs.chromium.org
Getting access to the privileged 'crosh' extension in this exploit depends on getting code into its process, which depends on the odd choice to put unrelated extensions into a shared extension process when there's too many processes. Given the insecure nature of the Chrome App Store, this was questionable to begin with - should a potentially backdoored bookmarking extension really share a process with my password safe? - but once privileged Chrome OS code started running in extension processes this immediately became a huge security hole waiting to be exploited.
In this case they also don't even need a compromised extension, because they can (if I understand this right) impersonate an extension's frame and then send messages of their choice to the extension. The access control here is almost entirely done inside the content process, where potentially compromised content is running. It's hard to avoid this since most extension code runs inside content processes by design, but it's a weakness that is rarely (if ever) called out in the chrome extension documentation.
The webassembly exploit part of the chain bums me out (I was always afraid of stuff like this when I was working on the design for it) but it's pretty uninteresting, really. The simple sort of bug you get when you insist on writing stuff in C++.
The parts of the chain after getting access to crosh also seem like tough-to-avoid oversights. This set of attacks definitely make symlinks look like a problem child, given how useful they are for all sorts of naughty behavior the attack gets up to :)
I really hope people don't think webassembly is the fault for this, this vulnerability is no different from any other memory corruption vulnerability you would find in the js interpreter or the css parser or whatever.
As for the rest, well, it'd be nice if there was any sort of plan to make Blink safer. I know about oilpan but what Mozilla is doing with Rust is impressive. The JVM guys are working on rewriting the JVM in Java. What's Blink's plan to make its own code safer? Sandboxing alone?
The ones you call out in this post don’t have the same impact as native, even when it’s C or C++ compiled to wasm.
wasm program parses q
stack smash occurs
ROP chain is used to gain code execution
user cookie is stolen
attacker now controls your account
I don't know enough about wasm to know if it has some special mitigations for this but when I looked at it, wasm seemed closer to a CPU emulation than a high level language VM. Flat memory space, no GC, no pointer maps.
The attack surface of a gmail implemented in C++-compiled-to-wasm is almost certainly going to be larger than a gmail implemented in JS, because the runtime environment is vulnerable to double frees and heap corruption and other attacks, even if it won't escape the browser sandbox. My gmail tab basically has access to my entire life.
I can see some site DOSing though where you use the equivalent of a png-bomb to blow up CPU from the parser, but that is any not-meticulously written client-side parser of untrusted input.
So while you can toy with memory and maybe even affect the function pointer before a successive indirect call, it's not near as dangerous to the outside-of-wasm world as raw CPU instructions. I can see an issue where the caller that imports libpng and exports his memory to it might have something secret in that memory...hopefully multi-memory and GC-like-structs and what not can make passing and manipulating large blocks more like params than shared mem (and all of shared mem's faults).
The way function addresses are sequential in wasm tables (and deterministic) also means it is probably easier to get to the function you want once you get code execution.
In fact, it should be better, given the static declaration of external calls that can be inspected.
Ideally wasm libraries will always be narrowly scoped and good about what they import, but there will definitely be broadly scoped libraries that import a ton of dangerous stuff, and there will be some that import a function that is effectively eval because they don't want to declare a thousand imports by hand.
It's certainly possible for JS libraries to have these kinds of vulnerabilities, but it's hard for me to imagine how a JS PNG decoder would end up with the same sort of attack possible on it since it's parsing binary data into pixel buffers. At worst, you'd crash it.
Yeah, sorry about the duplication here, I'm extremely interested in this specific topic.
> Now someone finds a png decoder exploit that works against my build.
I think this is the part I don't get. Specifically, how would an exploit work within wasm? That is, in the wasm environment is different than in native; the memory is bounds checked, for example. Basically, I 100% agree that some security bugs are logic bugs, but take the above stack smash, for example: that can't happen, in my understanding. Again, modulo interpreter bugs, like any sandboxing technique.
> it's hard for me to imagine how a JS PNG decoder would end up with the same sort of attack possible on it since it's parsing binary data into pixel buffers. At worst, you'd crash it.
It's hard for me to imagine how wasm is any different than JS here.
Just in general if I have an arbitrary memory write primitive inside the wasm memory space, how much control over the program can I obtain?
The caveat is that not everything native apps put on the stack can currently be stored in wasm's safe stack, so applications often put a secondary stack inside their heap. This will also happen if you're - for example - passing large structs around as arguments. You can smash the heap stack if you manage to find an exploit, and if function pointers or other important data are stored there, you can turn that into an attack.
It's absolutely the case that a large subset of stack smashing attacks don't work on wasm, because of the safety properties. Some of them will still work though. The way function pointers work in wasm raises the risk profile a bit if you manage to get control over the value of a function pointer, since function pointer values are extremely easy to predict.
I am curious how JIT compilation policies will affect this. Wasm is a new bytecode form that has no mature JIT compilers. I wonder how many safety properties the compilers will assume. For instance if the wasm VM only really tries to stop wasm code escaping its own sandbox, then I guess compiling all stack ops down to a unified stack, C style, is a perfectly legitimate approach as long as the sandbox properties can be maintained. I don't think wasm is claiming it will make all C/C++ hackproof code.
https://www.infoq.com/articles/virtual-panel-dotnet-future
And the D guys have been rewriting dmd, the reference compiler, into D.
"Automated Testing of Graphics Shader Compilers"
Nah, I think it's pretty clear GP meant "when you insist on writing interpreters/compilers in C++" not that C++ was compiled into wasm.
Most (all?) browser wasm backends function by just generating the internal IR used by the existing JS runtime, so it's not especially necessary to write the loader/generator in C++. The generated native module(s) are often cached, also, which diminishes the importance of making the generator fast at the cost of safety.
I wrote all the original encoder and decoder prototypes in JS for this reason - you can make it fast enough, and the browser already has a high-performance environment in which you can run that decoder. When the result is already being cached I think writing this in C++ is a dangerous premature optimization.
Similarly it's common to write decoders as a bunch of switch statements and bitpacking, which creates a lot of duplication and space for bugs to hide. You can build these things generally out of a smaller set of robust primitives to limit attack surface, but that wasn't done here either, despite my best efforts.
If you look through the chromium issue tracker you can also find multiple bug reports where people were struggling to get their chromebooks to update to the latest release, because auto-update had broken. Some of those people were Google employees.
Chromebooks have two boot partitions. So one updates while you are using the other. You then just pick up the update all ready to go next time you boot. You have zero idea that your laptop even updated.
You can google for a solution, but that solution only works on last year's version, the professional edition, or similar.
I thought that was how it worked too having just switched back to having to use windows.
But you can pick a time of your choice and specify a day up to about 5 days in the future or something, so it's not as bad as I thought it was going to be.
Coming from Linux it still an annoying difference between the operating systems but not as bad as people tend to make out.
I don't know whether it was a bug or planned but it was very agressive.
Only if you catch it while it's prompting.
I've seen people set up for a meeting/presentation/etc, test everything's working and then walk away from their computer to grab a drink. In that time, Windows has popped up a "Hey, we're going to perform updates" dialog which if you don't catch it before it disappears, becomes uncancellable/undeferrable. Depending on the update (eg Creators Edition) it then spends the next 20-45 minutes with the entire machine being unusable.
I've seen many panicky tweets from people who're about to give a talk in an hour or two that they've just opened their laptop and it's resumed into the dreaded "Oh, we're just updating now!" screen.
OTOH, when you do that there is no confirmation button on the UI, and the button placed and styled the way users expect a confirmation button to be is a “do the upgrade right now instead of at the time I just selected” button, so all is not roses and sunshine.
When an audit violation is detected ChromeOS forces an update an reboot to the new version (which takes seconds and feels almost like you've been unexpectedly logged out). All without losing any data except for unsubmitted form contents. Even if an update isn't available, the writable part of the system (not user data) is completely wiped limiting the ability of malicious actors to persist anything.
It's not a panacea but it is way more aggressive and seamless than any of the major operating systems could possibly do.
That aside, I wonder how much effort it takes to produce a hardened Ubuntu that behaves somewhat like ChromeOS, but you get to use any browser you want instead of just Chrome. Then you just run it under a tiling window manager (or minimal WM) to force focus on the browser, or on app at a time, while still having access to development tools (I guess the security aspect falls short here?) and maybe some office software.
I will get on someone's Windows box that will have updates waiting and I am like what gives? They are like I do not want to deal with the hassle.
It is all about getting rid of as much friction as possible and people will actually do it.
BTW, have you ever used a Chromebook?
Chrome OS is web centric, the bulk of users are desktop centric so it cannot be compared to desktop usage patterns.
Some developers tend to be extremist about updates, but given bug less software or a seamless disruption free upgrade cannot be guaranteed it's remains a better option to educate users rather than try to dis-empower and take control.
It's great that large, corporate projects like Chrome OS are attracting the sustained attention necessary to find bugs such as this one. But I worry that projects without such deep pockets are crowded out, leaving bugs unreported. Are many people doing security audits of open source projects without bug bounties?
> We have a standing $100,000 reward for participants that can compromise a Chromebook or Chromebox with device persistence in guest mode
https://bugs.chromium.org/p/chromium/issues/detail?id=648971...
It was actually reported by the same guy!
Imagine reporting 6 small bugs individually that nets you 6 x 1000$ = 6k$. But if you save each one, it may chain together for a potential 100k$ bounty. Of course, any insight that reveals these underlying relations is most certainly worth 100k$.
this would be awesome
- Random bugs that someone reported leading to something bigger,
- You already know the software well enough to dive inside,
- Luck ¯\_(ツ)_/¯
Finding (1) (3) and (4) is old-school exploit development - a combination of looking at fuzzers, looking at code, looking at bug reports, and memory exploit development (which is a black art I'm not familiar with). So persistence and luck. Be lucky 3 times and you have 3 steps. If you were an organization I suppose you could have 3 separate groups or buy from 3 separate blackhats.
I'm less familiar with the "worker process to user process" part, which tends to rely on combining a few vulnerabilities (in this exploit, 2 + 1 broken hardening), but it's probably similar.