4 ms·
Can someone explain the RCE part? I understand the double free bug but not the exploit part.
by wil421 7y ago
Can someone explain the RCE part? I understand the double free bug but not the exploit part.
- codezero 7y agoBecause one can overwrite the struct with arbitrary content, and that after the function that corrupts the struct is called, it executed a function that lives inside that struct, so the attacker can redefine the function to call out to the system (after a few other tricks - I think)
- aloknnikhil 7y agoYea. They hand-waved over the key part of the RCE. I know they exploited the function call in the struct, but how exactly did they re-write the program counter to point to the address of the system call? They mention that's another vulnerability not part of this article. Also, in the demo, they read a WhatsApp DB file as if it was plain-text from the terminal. I thought WhatsApp DB files were encrypted? How was 'more' able to just read the file?
- icebraining 7y ago> how exactly did they re-write the program counter to point to the address of the system call My understanding is: with the double-free, they managed to overwrite "info", including the location of the function "rewindFunction". When the parsing process calls that function, it will therefore actually call whatever function the attacker has pointed "rewindFunction" to.
- aloknnikhil 7y agoI see now. That's really clever. The fact that there's a double free AND that the WhatsApp gallery parses a GIF twice for some reason is a great catch.
- l33tman 7y agoYes, it's not something you typically think about when writing code even if you're security-conscious. IMO it's not good that the double-free bug has these consequences.
- wyldfire 7y ago> We need to first let PC jumps to an intermediate gadget, IMO ROP gadgets are terribly clever. Since you can't just execute new malicious code but you do have control over which instruction to execute next, you have to scour the executable and its libraries for any content that would have the effects that you require. Take a look at the output from ROPGadget [1] (look at "ROP Chain Generation" screenshot) to see an example of how it works. [1] https://github.com/JonathanSalwan/ROPgadget https://github.com/JonathanSalwan/ROPgadget
- kardos 7y agoROP gadgets are indeed clever. Meanwhile there are efforts afoot [1,2] to mitigate this line of attack by removing all of the ROP gadgets, which is also rather clever. [1] https://www.openbsd.org/papers/asiabsdcon2019-rop-paper.pdf https://www.openbsd.org/papers/asiabsdcon2019-rop-paper.pdf [2] https://www.openbsd.org/papers/eurobsdcon2018-rop.pdf https://www.openbsd.org/papers/eurobsdcon2018-rop.pdf
- l33tman 7y agoThe double-free bug means that a double-free of a chunk of size X might lead to subsequent allocs of that size X to return the same pointer. The lib in question parses the GIF twice. In the first run, it allocs an internal info struct of size X, then you trigger the double-free so this info struct is freed twice. In the second run, it allocs the same internal info struct of size X and gets a ptr Y. Then, by crafting the GIF so one of the frames to be decoded is also of the size X, it will alloc intermediary space for this frame, but due to it being the same size, you'll get the same ptr Y returned, and the frame gets unpacked over the info structure... So, you get your user-provided frame data placed in the internal info struct. Luckily for the exploiter, there are function pointers inside the info struct which are called a bit later. So you can provide a memory address to jump to by putting it in the right place in the magic frame. You can't also put executable code in the magic frame due to restrictions, but you can place shell commands in the frame and shuffle registers by using already available executable chunks by selecting the right jump address (this is explained well in the post I think).
- lubesGordi 7y agoAwesome explanation! Thank you! Does this mean also that function pointers inherently weaken security (by providing a means of code execution given other faults)?
- l33tman 7y agoThey are a very common design-pattern in traditional C, as you kind of emulate object-oriented virtual function overloading by using them in structs. I don't think it's realistic to avoid them just by principle.. As in network server hardening, you can usually start by following where user-provided data goes, and harden its path. In this case however the first problem was a clandestine bug (the double free in some cases), probably induced by the programmer trying to be a bit too clever with the management of these structs (if you're not threaded you could simply have a single static declaration for this info struct and forget the malloc/freeing, or at least malloc it just once upon each thread init, haven't looked at this code..). Generally keeping track of all malloc/free pairs is tricky and you can go a long way by trying to simplify your logic, I mean even if you don't get exploited like this, you might simply crash sometime or leak memory or in general behave badly. There are good reasons why there exist all kinds of memory-managed languages :)