8 ms·
FORCEDENTRY: Sandbox Escape
- 0x0 5y agoScarily elegant.
- ssklash 5y agoThis. The "weird machine" they built in the original exploit is the single most impressive exploit I've ever seen.
- deleted 5y ago[deleted]
- RL_Quine 5y agoThe knowledge of even what the scope of the attack surface is is incredible, beyond any other exploits that have ever been made public.
- etaioinshrdlu 5y agoI heard that Apple had a very hard time even understanding the exploit when they rushed a bandaid-patch for it, leaving most of the holes unpatched for the time being.
- saagarjha 5y agoThis isn't the first weird machine exploit used in the wild, and the people who respond to these kinds of things are quite familiar with them.
- deleted 5y ago[deleted]
- Thaxll 5y agoThat's where I think Rust could be a game changer, if all those deserialization libraries used in phone would be written in safe Rust it woudn't be an issue.
- invokestatic 5y agoAs explained in the introduction, this escape used only logic bugs. So rust would still be affected
- ghayes 5y agoFrom the first paragraph: > By sending a .gif iMessage attachment (which was really a PDF) NSO were able to remotely trigger a heap buffer overflow in the ImageIO JBIG2 decoder.
- greiskul 5y agoYes, this attack had multiple stages. First stage is to get something running, and to do that they do use a memory bug that Rust would prevent. The second stage is the sandbox escape that the post describes which is done with only logic bugs, so that would still be vunerable if written in Rust. While rewritting the world is not possible, all these attacks show that definitely new systems should probably not be written in memory unsafe languages.
- O5vYtytb 5y agoThey're referring to a previously mentioned exploit: > Late last year we published a writeup of the initial remote code execution stage of FORCEDENTRY, the zero-click iMessage exploit attributed by Citizen Lab to NSO. The sandbox escape only uses logic bugs: > In this post we'll take a look at that sandbox escape. It's notable for using only logic bugs.
- ForgotIdAgain 5y agoIn the introduction "In this post we'll take a look at that sandbox escape. It's notable for using only logic bugs". My understanding was that Rust only cover memory corruption type of bug.
- silvestrov 5y ago> starting in OS X 10.5 (which would also be around the launch of iOS in 2007) NSFunctionExpressions were extended to allow arbitrary method invocations with the FUNCTION keyword: "FUNCTION('abc', 'stringByAppendingString', 'def')" => @"abcdef" This is always a bad idea. If you want a callback, register it manually so only registered functions are available. Java serialization and Log4J made same style of security bug.
- slaymaker1907 5y agoRacket allows for macro/exec, but it strictly controls the namespace for both of these things. The former mainly via hygienic macros and the latter via requiring exec to be given a namespace to execute in. I think allowing things like NSFunctionExpressions are ok, but you need to have an explicit namespace, and the default needs to be an empty namespace, not the current/full namespace. Having a default is a good idea because if you don't add one as an API designer, other people creating wrappers around your library will, so at least try to make the default safe. It sounds like that is somewhat similar to your idea of registering a function.
- saagarjha 5y agoIt's easy to just look at features and call them "obviously" bad but this feature provides an extensible interface that isn't much different from any other API in Objective-C that takes a selector, e.g. sortedArrayUsingSelector:. This is just how the language is. It is your job to restrict what can go into that function; in this case where the attacker controls the address space it doesn't matter anyways because an attacker will just create a calling primitive elsewhere. So this is really just a kneejerk reaction that doesn't meaningfully help security here, and removes a fairly useful API. Note that if you actually wanted to make the attack harder here I'd go after the NSPredicate evaluation instead, which you can see in the blog post is done without checking the sender, rather than going after what the predicate itself can do.
- deleted 5y ago[deleted]
- arcticbull 5y ago
- spansoa 5y agoWhat if we had multiple sandboxes instead? Then we could make the rogue malware 'think' it has escaped by using a decoy environment, and then it has to break another sandbox. Having just one sandbox is a SPOF and once that's breached, it's fair game. (Good) security has always been about /layers/ of security.
- klabb3 5y agoIs layering always more secure? Layering may create more complexity in the system overall (usually bad for security) and spreads efforts thinner if you are maintaining both sandboxes. What's the difference between good and bad layering?
- spansoa 5y ago> Layering may create more complexity in the system overall Have you ever heard of the `swiss cheese method of security`, where each slice of cheese has a hole in it? The idea being: each slice may have a hole, but when sandwiched together, the route of entry is blocked. I've heard the adage: 'complexity enlarges the attack surface' before, but not in all cases especially. Sometimes security 'maxims' get in the way of security.
- saagarjha 5y agoThis wouldn't help, because malware developers have access to iOS and can see the implementation of multiple sandboxes.
- d110af5ccf 5y agoAlso it's fencepost security. Doing the exact same thing because "more is better" without a concrete reason why the additional copies would change the outcome. If the outer sandbox is the same as the inner one, why wouldn't the malware break through immediately? If it's different in some way, why not apply those additional mitigations to the inner one?
- spansoa 5y ago
- mwcampbell 5y agoThe ostensibly domain-specific interpreter tucked away in NSFunctionExpression is interesting, and I think it would be reasonable for Apple to try to rid their platforms of all such interpreters (with the inevitable exception of JavaScriptCore exclusively for the web). But I think the most important part is this: > The expressive power of NSXPC just seems fundamentally ill-suited for use across sandbox boundaries, even though it was designed with exactly that in mind. It reminds me of the YAML deserialization vulnerabilities that plagued Rails. It's clearly necessary to ensure that any data received from an untrusted source is merely data, with no generic way of instantiating arbitrary classes.
- d4mi3n 5y agoAgreed. I worked in closure for a hot minute and learned of a pretty nice solution they had to this called EDN (pronounced "eden"): https://github.com/edn-format/edn https://github.com/edn-format/edn I suspect it was inspired by the whole "data is code" philosophy of lisp languages, but it seemed like a well thought out pattern for encoding and decoding data in relatively safe ways. It had a way of tagging fields to indicate that they required processing to derive the decoded value, e.g. #inst "1985-04-12T23:20:50.52Z" Would be interpreted as a Java DateTime object, but one could just as easily read the raw data without respecting those tags if one didn't trust the safety of the data being read. In effect the format split the work of parsing the data from decoding the data, which is a distinction I haven't seen in many other data encoding mechanisms.
- bumblebritches5 5y ago
- valleyer 5y agoIt's striking how often these PZ iOS exploits at some point come around to too-polymorphic use of object unarchiving. Other examples: https://googleprojectzero.blogspot.com/2020/01/remote-iphone-exploitation-part-1.html https://googleprojectzero.blogspot.com/2020/01/remote-iphone... https://googleprojectzero.blogspot.com/2019/08/the-many-possibilities-of-cve-2019-8646.html https://googleprojectzero.blogspot.com/2019/08/the-many-poss...
- londons_explore 5y agoIt would seem the solution is to require every 'unarchive' operation to provide a 'schema' which specifies exactly which classes will be used in the unarchive operation. That schema would be read-only and specific to the unarchive call site.
- valleyer 5y agoYou're sort of describing NSSecureCoding. Unfortunately, it's not used everywhere, and (because Cocoa relies heavily on internal class clusters) it still allows subclasses of the specified class.
- olliej 5y agoI also recall one exploit that happened despite using nssecurecoding because a special internal class was a subclass of a secure coding class
- blintz 5y agoVery cool that this is just from logic bugs! I wonder if we should as a rule assume that sandboxing that is not formally verified or battle tested over a really long time is unlikely to be free of bugs. What's the long-term solution for these kinds of problems? How can we get out of this tar pit? Of course in the short run we can be dilligent about updates and bug bounties etc, but how can we actually eliminate these kinds of errors in a 'complete' way?
- mwcampbell 5y agoNot just any logic bug. I think the most succinct identification so far of the specific type of logic bug is in this comment (not mine): https://news.ycombinator.com/item?id=30871034 https://news.ycombinator.com/item?id=30871034
- codeflo 5y agoIt’s funny that no amount of (Rust-like) compile time or (Java-like) runtime checks would have prevented this — every line of code is working as intended. The parallels to the recent Log4J vulnerability are evident. If you happen to think, as I do, that we need safe(r) languages to have any hope of creating secure systems, then problems like these are a striking reminder that memory safety alone isn’t sufficient to achieve security.
- olliej 5y agoThe problem is historical serialization APIs that date to before people really thought about deserialising as an attack vector. All the big/enterprises serialization APIs of the era made the same mistake (and later on added layers to allow the developer to limit the set of classes that could be instantiated) Modern serialization frameworks all seem to have moved to a no-polymorphic instantiations model. Eg when deserialising a field of type X, they will only deserialise into an X.