I walk through the process of developing the exploit and primitives, and was upfront that I ran into a mitigation which thwarted my exploit strategy. Similar to other exploit writeups I've done, I try to focus on the big picture and illustrate the idea (through writing and diagrams) while still being technically rigorous. Exploit development is much more reading code than it is writing it.
If you have any suggestions for improvement, or want to tell me which sections felt like handwaving to you, please let me know! Better yet, if you have an idea on how to defeat the mitigation so I can complete the exploit, I would love to discuss it.
BTW: Failing to produce an exploit for a very powerful bug like this, despite my best efforts, was considered a giant win for the security review of Firecracker.
Not GP, but I struggled to follow some parts due to passive voice.[0] There were a lot of sentences that omit the actor of the sentence, so I had a hard time understanding which component performed which action.
For example:
>If specified in flags, descriptors can be chained together with next containing the descriptor table index of the chained descriptor. virtio-vsock, buffers in a descriptor chain are used to construct a vsock packet. Something to note at this point: the buffer information in the descriptor comes from the guest, and it should be treated as untrusted.
So when I read that, I have to mentally walk back and figure out:
* can be chained together -> Who chains descriptors together?
* are used to construct a vsock packet -> Who constructs the packet?
* should be treated as untrusted -> Who should treat it as untrusted?
From context, I can figure these things out, but the Firecracker/kernel concepts you're explaining are occupying most of my mental bandwidth. Any bandwidth you can free up with simpler sentences makes it easier for me to focus on the main subject of the blog.
I've read over this paragraph a few times now and I'm really struggling to see how their protections don't defend against the described issues -
"There are two problems that could occur; the base and result address may belong to two different regions, and the base address may not even exist in a valid region."
"the base and result address may belong to two different regions"
if addr >= region.guest_base && addr < region_end(region)
Surely region_end(region) stops it belonging to two different regions, as you're using one region in the for loop? I'm probably being thick!
"the base address may not even exist in a valid region."
Again surely if the addr < region_end(region) this would ensure it's within a valid region?
Is there any other info you can provide so that my simple brain can understand?
It looks like the author wasn't able to pull all the gadgets together into a working exploit, after finally being stymied by the fact that Rust surrounds the stack with guard pages (which are intended to catch accidental stack overflow, but fortuitously appear to also provide some protection against deliberate exploits as well). But it could have easily gone the other way, and exploits there might be still be possible (though obviously the code in question is many years out of date by now). It still serves to demonstrate the importance of auditing your unsafe blocks, the value of unsafe blocks in the first place (which is, I suspect, how this exploit was discovered in the first place), the value of additional tools to verify unsafe code (e.g. Miri, Kani), and the reason why Rust still goes to all the trouble of implementing runtime mitigations despite its memory safety guarantees.
Well, we attacked Firecracker and this is what we got haha not every attack is going to lead to a full end to end, reliable exploit, although we've posted those in the past too.
The key here wasn't to produce an exploit. That would have been interesting, but ultimately not the entire goal. The key was to understand "how do we use Firecracker in the safest possible way for our use case?". To do that we picked one of the CVEs that looked like it could be exploitable and dug into it.
We learned a ton about Firecracker and KVM and walked away with some mitigations we can implement such that even if the bug had been exploitable the attacker would have more hurdles to jump through. Specifically, we'll be working to harden the guest operating system such that the untrusted code will have a difficult time escalating to root/kernel, which is a prerequisite for this sort of attack.
6 months, here's why:
They random forested height data, everyone random forests these days. It's quick and dirty and yields good accuracy. Not only that, everyone seems to support a built in Random Forest training model, programs from pandas/numpy/scikit to R has it built in. Height data seems the easiest to go by, to short and it has a kink that may cause cracking in the future as the metal oxidizes. What were their 3 models? Who knows? But their idea of combining 3 models, that 3 different teams have made is standard in all DataScience competitions. This is called ensembling. ArToolkit for Unreal Engine, someone else made that and they probably just connected a bunch of blocks together with Unreal's script engine. Honestly, 6 months max and you can do this in a day yourself.
Multiple years, here's why: you need to decide what will work and what will not, as you don't have time to go the wrong route. And that takes experience which it would be difficult to gain in 6 months.
We used two convolutional neural networks, one for each side of the weld. Features extracted by these nets are then concatenated, as well as the meta data. Two fully connected layers are then applied on this vector, giving the final prediction.
Everything was trained on the raw images resized to 20x150 pixels.
You can leave the country and not tell anyone the field you are in and inevitably the topic will come up.
Insufferable.