Boot2root
Sprundel, Ilja van
Tartaro, Joseph
The Achilles heel of [your secure device] is the secure boot chain. In this presentation we will show our results from auditing commonly used boot loaders and walk through the attack surface you open yourself up to. You would be surprised at how much attack surface exists when hardening and defense in depth is ignored. From remote attack surface via network protocol parsers to local filesystems and various BUS parsing, we will walk through the common mistakes we've seen by example and showcase how realistic it is for your product's secure boot chain to be compromised.
 Okay, please welcome our next speakers, Joseph and Ilja, who will be talking about how bootloaders are broken and how to look into them. Please give them a warm round of applause. Hello, does this sound okay? Cool. Yeah, so welcome to Boot to Root, auditing bootloaders by example. I'm Joseph Tartaro. I hack things for IO Active and this is my second time at Congress, so I'm really excited to be back here. Hi, I'm Ilja. This is my 18 or 19 time at Congress. Happy to be back here too. I've spoken here, I think, seven or eight times before and I'm very excited to speak here together with Joe. We've been working together on bootloaders last year in change and this is minus the NDA coverage stuff. This is some of the things we've observed and seen, so I'm very excited to do this. Yeah, so the expected audience for this talk would be embedded systems engineers, security people who are interested in embedded systems and just curious security people. Just a caveat. We're going to be quickly going through about like 70 slides or so and a lot of it's just like examples of C source code, so if you did not realize you were signing up for an hour of that, feel free to walk out. We're not going to be offended. And then another caveat would be this isn't really trying to flex and show look at all the bugs we found. The purpose of this was to kind of show people, hey, if you have not looked at bootloaders before, this is our recommended areas of attack surface that are interesting. This is probably where you should get started. And in some examples of nobody's really looking at them and they should start, so that's pretty much what's going to go on right now. So quickly, here's the agenda. We'll discuss why they're important. Some of the common ones we looked at, attack surface and our conclusions. So there's going to be a wide interpretation of bootloader. So basically what we mean by that is anything that's in your secure boot chain. And if you don't have experience with these or you haven't looked at them much, you can kind of think of it like from an operating standpoint of user land calling into kernel space, you'll have kind of normal world calling into secure world and stuff. And that's kind of what you're looking for is those pivots and when they're processing, you know, attacker user control data. So why? Because they're, you know, critical for security. It's a key component of your chain of trust and it's very obvious that a lot of device designers are poor at hardening and limiting attack surface. And what we mean by that is a lot of the devices we've looked at over the last year or so, you'll find devices that have like full network stacks even though they don't need a network stack. You'll have a bunch of code loaded up to handle file systems that are never expected. So it just, it doesn't really make sense why they're not limiting all that attack surface. There's also a huge under estimate of reverse engineering. People just kind of assuming that there's no bad actors and nobody's really going to look at this thing and it's this hidden black box that we should ignore. And a little story behind the presentation is we're actually on a train going to a baseball game. I was trying to introduce Ilya to the lovely game of baseball. And we were talking about U-Boot and I pulled out my phone and we went to the U-Boot GitHub and in about, I don't know, 10 minutes, 15 minutes, we ran into like 10 bugs and we went, yeah, we should probably audit some of this stuff. And kind of inspiration from a previous talk that Ilya has given at Congress where he audited a bunch of different BSDs. I said, why don't we look at a bunch of different boot loaders. And so just to give credit where credit's due, we are not the first to look at any of this stuff. So this is a list of people that kind of inspired us, have done really interesting work. And we recommend if you're interested in any of this and you enjoyed it, you should go check these people out and see things that they have released in papers and stuff like that. So where are they? Boot loaders are pretty much in everything. You have your workstations, game consoles, your TV, you know, everything. And generally the security basically depends on this. So it obviously really, really, really matters. And so with that said, we basically started looking at these common open source boot loaders. So U-Boot, Core Boot, Grub, TBIOS, CAFE, which is Broadcom, Ipixie and Tionocore. And we're just looking at what's on GitHub, what we downloaded. Obviously in your real world scenarios, the devices that you have at home or go buy and start looking at, they're going to be heavily modified. They're going to have weird custom drivers that aren't available, things like that. So, you know, we're not here to argue the likelihood of some of the bugs we found. We're not going to argue exploitability. Half of them, we don't know if they're exploitable. We don't know. We will for one. Yeah, we will for one. We don't really like, that's not really the point of it. The point is to kind of show people, show designers what they should be concerned with and show interesting, or researchers that might be interested what they should look at. So U-Boot is extremely common. It's in a ton of devices. There's a huge, very customizable config for all different sorts of boards and stuff. There's concerns for environment variable stuff. There's a super powerful shell. So you'll sometimes see even shell injection concerns based on environment variables. It's pretty funky. And there's lots of drivers for tons of devices. So it's kind of a great first step of looking at something that kind of covers a huge breadth of things. And so features of U-Boot that are interesting would be, you know, network stack for different protocol parsing, file systems. And they also will load their next stage images from like all sorts of weird, like, archaic things that nobody uses anymore. And it's just used by tons of devices. And then Core Boot. And I apologize. This is a little dry right now. We'll eventually get to this stuff. But Core Boot, you know, it's more targeted towards modern operating systems. There aren't like legacy bio support. It actually, they took a methodology that other projects don't, which is they're not going to implement features that they don't want to. So if you're trying to do network booting or something, you use Core Boot to boot into like Ipixie or something. They're not going to implement that feature. These are used in Chromebooks. And obviously some of the interesting parts come from Google. And one main interesting area is SMM. And then Grub. Obviously you guys are all familiar with this. The primary concern here is a multi-boot spec. And they support just a ton of file systems. So that's obviously the attack surface you'd be concerned with. But the interesting part here is that there are U-Fee signed versions of Grub. So that's kind of like your secure boot break right there. If you find a vulnerability that's an assigned version, you can now load that into your U-Fee and exploit that vulnerability and you're good to go. And then CBIOS is the default BIOS for KEMU KVM. This supports legacy BIOS stuff. So you'll see that this gets booted into from things like Core Boot. This supports TPM communication. So that's kind of interesting. And it's the compatibility support module for U-Fee and OVMF. And then Broadcom Cafe. So this is used in a ton of different network devices and TVs and stuff like that. And the obvious attack surface there would be network protocols, the network stack. That's what you'd want to look at. Ipixie. This would be more network-based stuff. Various parsing and similar to Grub. There's U-Fee signed versions. So it's a great potential pivot for secure boot stuff. And then finally, Tionakor. There's really no introduction needed here. There's been a ton of great presentations over the last 15 years. People just doing everything to this thing. And due to that, since it's pretty much the most scrutinized one out there, it's really mature compared to everything else. So when you bash Tionakor, realize that it's way better than everything else. So there's a lot of implementations built on top of it, like platform-specific stuff, Qualcomm, ABL and XBL, things like that. So you'll have all these. You have the base Tionakor EDK2 and then you have all the custom stuff built on top. And then related to bootloaders, you have things like TrustZone. And that's kind of where I mentioned. You have like normal world and secure world. You'll have these interesting pieces of code that are running into those secure areas that you're going to want to look for. You know, pivots into there so you can gain access to secrets. And then obviously from the host operating system, the attack surface there would be you can modify things like NVRAM. So you can set variables that when the next time you reboot, the boot loader is going to process as variables. And this slide's more for reference. Later you can get the slides or take a picture or something. These are just links to some instructions for building and whatnot. So if you wanted to start looking at these, you can quickly build a little environment and poke around. So just really quickly to go through the concept of secure boot, you kind of have your chain of trust. You'll have the boot ROM that will then verify and load various other loaders that then verify and load the next thing. And you'll sometimes have a TPM involvement. You'll have some TrustZone involvement and then OS interaction stuff like the OS basically setting things like NVRAM which will set boot configuration stuff and whatnot. So the boot ROM itself is something you've probably seen the talk by Cordy Oryoop, I think earlier. It's really important because it can't be patched. It's a hardware revision would be required if vulnerability is found. And it's so early in the stage and you would basically compromise everything after it that is where you'd want to go. It's extremely bare minimum. It does some initialization of hardware and memory stuff. And then you'll find things like maybe implementations of fast boots. You have a USB stack. So that's an obvious attack surface you'd be interested in. And then it will verify the signature of the next stage and then boot that. And then you move on to the next stages. And this is where they start initializing the rest of what's necessary, network stacks, SMM handlers and whatnot. And they'll basically just keep handing off. And then you'll run into things like trusted boot and measure boot which is, you know, verification and then measuring which is kind of more for logging and whatnot doesn't actually mitigate anything. It just kind of alerts you of stuff. So some hardware environments are a little different. Like the secure world stuff, you'll have ARM or trust zone. Windows has VTL 0, VTL 1, hypervisor stuff. And then, yeah, I'm basically repeating myself. And then eventually the operating system, that's going to get the kernels going to be loaded, it's going to be verified. And then eventually start running and then you can have fun. So early observations is everything we pretty much looked at that's open source, there's no privilege separation. So if you were to compromise a piece of component, you pretty much rule everything. And what's interesting is there are some proprietary boot loaders that you're starting to see, like Apple, for example, they're doing some aspect of privilege separation. So if you were to exploit a portion, you didn't necessarily control the world. And so right now, at least all the stuff we looked at did not have anything like that. But maybe in the future, we'll see that. So this is the list of the attack surface that we think people should be interested in and focusing on. You have NVRAM, file systems and files, all network stack protocol stuff, all various buses, you know, SMM, DMA and hardware stuff. The interesting thing about buses that we've noticed is that embedded designers seem to inherently trust anything that end users should never interact with. So they go, okay, an end user uses USB, so we should verify some of that, but they do a bad job. But an end user doesn't play with the spy flash, so just inherently trust it. Or an end user isn't to the TPM. So just if the TPM says something, run with it and they mess it up a lot. So NVRAM, these are the various environment variables that can be configured, you know, for the next boot cycle. And like I said, it's basically processing of user controlled data. So if you start looking at some of these boot loaders, here's the interesting functions you'd want to look at. For example, in Uboot, you just kind of call for environment get and grab through and you see them grabbing the environment variable and see what they do with it. If they're not doing any sort of validation, you're going to hit a book. And so an example of that would be right here, you see there's an environment get for boot P VCI. It checks if it existed. It will then do a stir length and then just mem copy it directly into a buffer without validating that it can fit the buffer. And this is actually kind of funny earlier today. We were like, ah, we should try to exploit one of these just to show it. So we toyed with this one and, you know, just do a bunch of bytes and it starts just kind of sending these weird packets over the wire and a bunch of boot P stuff. You'll see later on you just have full raw packets of whatever payload we send. But it wasn't very realistic. It kind of went, started getting into like the key move like network implementation stuff. So we kind of avoided and moved on to a different bug. But as you can see, it's very easy for you to start looking at the stuff and being interested in it and quickly set up an environment and mess with exploitation and we'll get into it but there's no mitigations. So as you see, there's a bit of a pattern here. Environment get host name, mem copy with stir length. No checks. 128 byte buffer, environment get boot dev, stir copy. It just keeps happening. This is kind of what we were talking about. Just the quality code is not very great. This is, what's funny is when we were messing with that boot P VCI stuff earlier this morning, we went, oh, this is going to be more involved. So it was like, well, let me just go find a different bug. You know, 10 minutes later, it's like, oh, I found a different stack smash. Okay, let's work on that one. It's just like, this is a perfect example. The environment get the variable and then they'll grab the very first element of that variable as a length and then use that as a length. And it keeps happening. So just a quick example. See this. So the attack scenario of this would be, you have a device, you have NV RAM that you can physically modify as you have physical access. And this is kind of an example of the default NV RAM. So we just threw an environment variable with 600 bytes and you'll see towards the bottom there's four bytes where we threw a function in there and that's the address. So just this had to do with the GFFS to file system loading. So you just do FS load. And that's it. That's shellcode being executed. So this is... Sorry, I can't see. So obviously, if you've never looked at this stuff, it's kind of fun to play around with and you should start poking at it because why not? And screenshot. Cool. So that was the NV RAM attack surface which is usually the most fun to play with. Programming to spy flash sometimes may take a little bit of fiddling but in terms of attack surface and fun things to play with, it's, you know, as Joe said, often overlooked and so it's easy to toy with. And so you saw all this Esperant Devs and MIM copies and string copies. So there's a lot of fun there. But obviously there's not just NV RAM. There's more attack surface to sort of a trusted boot environment. And obviously one of them is the file system right because this thing needs to boot and it needs to find images and they're stored somewhere and your file system sort of brings order to that chaos. So basically you need to mount your file system and often file systems are not signed or are technically checked or not all of it is because before you can do that, you need to be able to read something, and so obviously an example of a common file system would be the file system. If your boot environment supports loading your USB drive and for storage, it's probably going to be fat. Depending on, and the flash itself may have its own proprietary format or it may use X2 or something else. But clearly the file system parsers, I mean that's prime attack surface. A closely related is obviously the files inside of your file system, right? Now depending on what your boot environment looks like, some of these files are going to be integrity checked but some of them might not be, right? And so those file parsers are interesting attack surface. And if you're either looking for bugs or you're building a product, we would highly recommend fuzzing these. And it's like starting with AFL is probably a good starting point. But we'll show some examples of some bugs we saw in certain, in a number of boot loaders. So we'll cover X2, we'll cover a bitmap splash parsing one. And then the other ones are sort of examples of where there could be bugs but those two we'll cover. So this is grub, and this is grub X2, and grub X2, you know, this is the sim link code so it looks to file system and it goes, oh, okay, this is the sim link, how do I parse the sim link? And so the sim link says, hi, I'm a sim link, I'm this big. And what grub does is, oh, great, I'll allocate that much size but I'll do one more for an old byte. And of course that is a classic in Azure overflow. And the grub memory allocator actually returns a valid pointer for a zero size. So this is a perfect primitive so you get a pointer to something that is zero size and then it actually reads the sim link content from the file system into a zero size buffer and obviously that's going to cause memory corruption. And a primitive, you can't see it here but a primitive is really nice because that particular read function actually, if there's no much more on disk, it stops reading. So even though you can save, read four gigs, you can make the layout so it only reads, let's say, a thousand bytes or a hundred bytes. And so you have this near perfect primitive to cause memory corruption. This was in Tiana Core, for example, this was the bitmap splash screen parser and I don't know anything about bitmap internals. It's a very simple format but basically you can have a four-bit bitmap and that gives you a pallet of four by four which is 16 bytes. And so the idea is if you have a four-bit bitmap, then it has a 16 byte pallet and so it goes and reads that 16 byte pallet except you tell it how big the pallet is and you can say, okay, I know you're expecting a 16 byte pallet but I'm giving you a 256 byte pallet and it will read it into a 16 byte buffer. So that was broken and then for the 8-bit bitmaps, similarly it was broken the same way. And these are just a tip of the iceberg. There are many, many, many more. This did not take long to find. But let's move on. Obviously now that we've looked at some local stuff and some physical stuff, what about remote? What is there? Obviously if you're talking remote in the modern world, you're talking TCP IP. So you need a TCP IP stack and you need to have some services that you either expose or that you have client code for that you go talk to. And that's bootp and DHCP and DNS and iSCUSY and NFS. And if you're in a corporate, if you're a corporate net, you probably want to have IPsec and then HTP and HTTPS and TFTP. And sure enough, most bootloaders have code for this and then you start asking, okay, what's the attack surface? For TCP IP, if you implement your own stack, well, good luck because you're going to screw it up. But secondly, it's like, okay, well, if you look at these things, you take a step back and say, okay, well, really this is all mostly TLV parsing. And so you go and look into what are the things that can go wrong if you do TLV parsing and they'll be out of bound reads pretty much everywhere and you'll see in those loops and lots of places and things like that. If you look at the protocol at the top of that, like DHCP and DNS, you have your standard network attacks where you'll see lease stealing or cash poisoning or things like that if you don't protect your ID. So if you have a static ID or you don't validate your IDs or you generate predictable IDs, you can have these kind of poisoning, stealing, man-to-middle attacks. And then thirdly, obviously, the thing we really like to see is memory corruption bugs. At the end of the day, you take network data and you parse it and if you do it wrong, you may cause memory corruption bugs. Another sometimes overlooked interesting bug I think when you're doing network parsing is when you have information leaks. So this often manifests itself, I mean, hard bleed, of course, was one example. It was a perfect primitive. But generally, it will be this thing where you end up generating some kind of pack as a response to something and you'll have done the memory allocation but for some reason not initialize something and so you end up sending initialized data over the network. So this is sort of the common things you see network stacks in general. So if you are looking for these kind of bugs in a boot environment or if you are building a product that does this, I would highly recommend fuzzing them. There are numerous interesting network fuzzers. If you're looking for network stack fuzzing, I would recommend ISIC. It's pretty old but it's still incredibly, incredibly effective. It tends to break most network stacks. So with that said, let's show some examples. I was, so UBoot, for example, this is the UBoot DNS code and if you see that, the TID, that's the DNS ID and it's basically, they give it a, they use the static DNS ID of one for all DNS packets that they send out. So doing DNS man in the middle on a UBoot environment is extremely trivial. You guess the DNS ID by saying that it's one and you are correct 100% of the time. So this is Broadcom's coffee and this is the DHP parser and it basically has this sort of junk stack buffer where it just needs to read something out of a buffer and it goes and says, okay, well, get me the length of that thing and it's a UIN date. So that means it can represent 0 up to 255 and then it reads 0 up to 255 into that junk buffer. So that's a stack corruption right there. If you then look at the coffee at the DHP parser, it's very similar where in this case it has a 512 byte buffer and then it basically copies the entire RX buffer into it and this is Ethernet so up to 1500 bytes gets copied into this 512 byte buffer again causing memory corruption. Obviously we're not done with coffee yet because it has such beautiful code. So this is the coffee ICFP ping handler and this has this really cute sort of use after free bug or double free where it basically sends out a ping and then it sits there receiving the, you see the while loop there and it basically sits there receiving packets until it finds the right one but it also, because it doesn't want to have it on its loop, it has a timeout and there's this interesting condition where if the last thing it looked was the packet you were looking for but it also timed out at the exact same time it freeze that packet twice which obviously can lead to memory corruption. Again we're not done with coffee yet. Oh right there we go. Not done with coffee yet so this is the IP handling coffee and if anybody has ever looked at an IP header which I would assume most of you have, you'll know it has an IP header length and a total length and of course coffee needs to know this because it needs to know where stuff is but coffee validates neither the IP header length or the total length so once you start messing with those coffee blows up really fast. So that was sort of a quick overview of all the trivial TCP and TCP related bugs that show up in your after boot loader. So but let's say you got that covered and let's say, you know, okay what's the next thing? What more sort of network stuff can we do? And then of course what comes to mind is Wi-Fi, you know, 8 or 2.11. And a surprising number of boot loaders don't have 8 or 2.11 so I don't know if that's sort of a sort of on purpose or just sort of we didn't get to having this feature yet but we will at some point and obviously it'll have bugs when we implement it. But we did find one that has it and I'll get to that in a second. One thing I did want to mention is that if you look at 8 or 2.11 like frame parsing, depending on which device you have and particularly which radio your device is using, you'll have radios that do a lot of parsing on the radio in which case the stack is kind of covered because it's, at least you hope it is where the radio does a bunch of validation. But then there's a whole bunch of radios that sort of, you know, they take package from the wire and they just don't do anything and just pass it on to the OS. That's the stuff that's interesting from a, from a tax service point of view if you look into attack the boot loader and not the firmware. So yeah, we looked at Pixi and of course, you know, anytime you do any kind of Wi-Fi stuff the first thing you do is you're looking for an SSID, right? This is what this thing does and, you know, it sort of has this SSID buffer which an SSID can be up to 32 bytes so that is 32, well, it's 33 bytes because it's 32 plus 1 and it has this loop where it sort of goes over IE's that it gets and then when it finds the right, the IE for an SSID it says okay, we'll take this IE and we'll do IE length and IE length is a U and 8 so it can be up to 255 and it copies the SSID IE into the SSID buffer which is only 32 bytes causing memory corruption. So that's iPixie for you. Okay, so the next one if you're thinking networking would be Bluetooth and Joe and I have actually we've looked at proprietary bootloaders that have Bluetooth support. Unfortunately, we can't talk about those bugs because they're covered by non-scope agreements and we tried really, really hard to find a similar equivalent in any kind of open source bootloader and we couldn't find one. So unfortunately, we can't give examples of sort of Bluetooth bugs in open source bootloaders but I do kind of want to in general terms talk about what we have seen and where we suspect the bugs are going to be if somebody does do this in an open source bootloader or something that's a new bootloader. So and also like if you're going to do Bluetooth in a bootloader it's usually for you know HID device right this is for keyboard mouse this usually ends up being for consumer devices. But in general if you look at Bluetooth stack and you're looking for any kind of you know parsing bugs there's three sort of recurring teams. There's three sort of recurring teams that we saw when we looked at the Bluetooth stacks that we have and this is if you look at the lower layers like L2P cap and things like that and this is usually related to sort of frames and frame lengths so very, very large frames. So a frame can be up to about 65,000 bytes because the length is a UN16 and so if you create really large frames like right up to the edge that tends to blow up Bluetooth stacks. The other one is if you create very, very, very short frames you know less than what something is expecting that tends to blow up your Bluetooth stack. And then lastly because L2CAP can have fragmentation so you can have individual fragments that you will add together and every fragment can be X amount of bytes but the whole thing can be up to 65,000 bytes a byte, 65,000 number of bytes. So if you start playing around with the fragmentation we've numerous Bluetooth stacks have blown up. Again, I wish I could have shown an actual bug here but I wasn't able to find any in the open source boot loaders. So moving on to USB, this is a primate attack surface in boot loaders obviously. If you haven't followed the news in the last couple of weeks and months this has shown up in a number of devices. This is at least up till recently I think was sort of under reported or sort of people didn't quite care about it. But to me the USB stack is like that's the if I, any time I look at a USB loader at a boot loader my first thought is you know NV RAM and number two is USB. And USB is interesting because obviously a lot of boot loaders support USB because they'll use it either for storage or you know things like Internet dongles but often for storage where you know either you expose certain files or you try to do some kind of recovery boot from USB or something like that. And so basically if you start looking at how USB works at a slightly lower level it's not quite like it's not like PCI it's more packet based and so what happens when a device talks to a host the device is asked for quote unquote descriptors. And these descriptors say certain things about your device and based upon the number of descriptors that the host asks from you and all the answers you give them in the script responses the host can then figure out what kind of device you are and what class you are and what functionality you expose and all these kind of things. And so a lot of these descriptors end up you know being parsed and being parsed wrong. And so generally we often see either straight up overflows or double fetches because the way descriptors work is they're variable length content but the headers are predefined and the way it works is you first ask for the header and then based on the length of the header you ask for the thing again except the USB protocol doesn't allow you to just get the payload you have to reread the whole thing so you have to reread the header that you already had. And so in most implementation what happens is you go get the header you allocate a buffer and then you go get the header and payload again and you override the original header. Which means is you get to override the original header length and so you can have a talktow where your device gives you a header with a good length and then the second time it gives you a descriptor with a bad length and if your host doesn't validate that both lengths are the same bad things happen. And yeah, straight up overflows happen too because nobody ever expects the USB device. There's an example in Grubb for example where it goes and gets a descriptor and the descriptor says oh here's my config account I have this number of configurations go and fetch those in descriptors as well. And there is a predefined array of number of configurations that Grubb has and it doesn't correlate that with the config count. It just always assumes the config count is less or equal to the array. And so if you have a malicious device and you say hey I know your array is 32 bytes, 32 elements but I'm going to give you 64 configurations. It'll happily write 64 configurations in a place that can only hold 32 of them. And exactly the same thing for number of interfaces. Tiana core had similar bugs where this was Tiana core where they go and get a descriptor and the descriptor length says okay now go fetch me the whole thing and use that descriptor length except the original hub descriptor was a very small struct and the descriptor length is a U and 8 so you can set up to 255 bytes and so that would have smashed memory and caused a stack corruption. And so as you can see here the fix here wasn't actually at a bound check but just to make the buffer bigger because you know the length is U and 8 so if you just make the buffer 256 then any length you give it will fit within the buffer. Yeah this is an example in C BIOS where this is the classic double fetch where it goes and gets the header, does an alloc based on the header and then gets the header again with the content and it doesn't verify that config W total length is the same thing as CFG to W total length and because that verification isn't there whoever calls this thing can no longer trust W total length because it could be invalid. And so as I said USB to me is one of the prime attack services to secure boot and so I want to sort of very very briefly mention two recent real world cases where devices got broken into because of USB parsing in the boot loader. So this was this is a case of the Nintendo switch the Tegra this was done by the failover flow people about a year or so ago that basically you know you give it a length that's not validated and then a mem copy and that causes memory corruption and then the recent iPhone checkmate this is slightly more complicated because it wasn't a straight memory corruption but it was you know if you fiddle around enough with the state it sort of gets out of sync and it has all these pointers that it's still considered to be alive but the memory has been freed and so you end up this ends up what you use after free but it is because of a sequence of USB packets that are being sent. Right so that's it for USB obviously bunch of the buses or almost any bus on your device if your boot chain uses it is interesting attack surface and this is spy I mean spy flash and be trusted, SDIO, I2C, LPC even your TPM right even your TPM response you get back from TPM can't be trusted because somebody could desolder your TPM and pretend to be your TPM and if you don't now validate the data you get from TPM you end up with memory corruption. So this is for example what happened in CBIOS. CBIOS has this talk show TPM and it goes and gets this structure and you can send it less than what it expects and then basically they subtract some size of a struct minus less what they expect and so that causes integer underflow which ends up with a really big size and then that size is given to malloc and malloc internally has an end overflow so that really big size then becomes a very small size and then they copy into it and that causes memory corruption and so this is a combination of two bugs right one is where the sizes are wrong and then secondly is where the malloc has an internal integer overflow and this is the malloc internals of CBIOS which I don't want to dive into now because it's pretty convoluted and complex I'll leave this as an exercise to the audience to figure out where the int overflow is and technically it's not an overflow because it's a bunch of shifting being done but it essentially comes down to an int overflow. Yeah, there we go. Yep, there we go. Okay. So another service attack service that is interesting but often overlooked on devices except for Ufie is system management mode and I mean there have been over the last decade and a half numerous presentations about SMM attack service and break SMM handlers for Ufie because it's an x86 thing and you see this in Ufie stacks and it was a cat and mouse game where for years somebody breaks something and then Ufie fixes it and then somebody breaks it again and Ufie fixes it again and somebody makes it again and Ufie goes okay let's do mitigation for this and this has gone on for like 15, 16 years and occasionally people still find bugs but by and large Ufie does fairly well now with regards to SMM handling. There's some third party stuff that still breaks occasionally but in general they got a handle on this. Now what if you're using x86 but you re-implement your own boot loader and you don't use Ufie, right? Well that means you're going to run into all the same problems Ufie had and you're going to screw it up in all the same ways and it'll take you another 15 years to get it right. But I guess if you were to try it the first time this is what Corboot does and to their credit they say oh we get input we should range check it and their range check says to do. Okay so now I talked about a bunch of buses. The thing to me that sort of separates that from other things is when you do DMA. Generally for as long as DMA has been around DMA is game over. If you get DMA then that's that there's no trust boundary. Obviously that's no longer true. We have IOMM use and if you use them and if you have a device that has this available then old-sodd DMA can be stopped, it can be contained, it can be regulated and so it's no longer a sort of game over and you can implement a trust boundary. A few things there. A if you are an embedded device and you're using IOMM use you are way ahead of the curve because not that many people are doing this right. You should but it takes some effort. There's obviously many different IOMM use it depends on your architecture and sort of the board you have and all sorts of things. So Intel's VDD, ARM is SMMU, AMD has like the device exclusion and it's got a few other ones as well. But basically if you use one of these you can sort of DMA is no longer the game over. Now that doesn't mean that you're in the clear. Once you define DMA as an attack surface you have to defend it and that's where you get some difficulty because you'll end up using drivers that have been written before it was a trust boundary and I mean no one has ever written a DMA handler with a trust boundary in mind because you assume there's no trust boundary. So now if you start using the IOMM you have to go back and look at where am I doing DMA and now I can no longer trust what's in when I get back from DMA and you have to go validate all this stuff. But even if you do all of that right which by the way is very hard and you probably won't do it right but let's say you do. Secondly because DMA is now a trust boundary any time you open up a memory window for a device you can't just open it up you have to clear the memory first because otherwise now you're leaking memory to a device right. So all these sort of new things sort of show up if you take DMA as a trust boundary. And let's say you do that right well now you still have a dependency on the IOMM you because you are assuming the IOMM you's perfect when it probably isn't right. I haven't really gotten to this part yet but one of my plans for the future is to go look at IOMM you and see if I can attack IOMM you and then find bugs there. I strongly suspect there will be side channels and logic bugs and maybe maybe even some heart room implementation bugs. So bug-wise this is where it sort of gets design-y right. So this is what this is Ufie today, it's EDK2 platform code where it has support for IOMM you and they're ahead of the curve. But if you look at the spec there's no good handover protocol from Ufie to the next stage. And so Ufie basically boots up and very early configures the IOMM you and make sure that devices can't peek or poke arbitrary physical memory and then it does all of its stages and then it's about to hand off and it goes well I don't know if the next guy supports IOMM you so it undoes all the IOMM program it does, turns the thing off, opens up everything and then hands it over to the next guy. So you did all this work for nothing. And this is a spec bug and it's being worked on, people are very much aware of this. People at Apple have fixed this for their devices. This is going to get fixed in the future but given that this has to be done by spec it takes a while because you have to get people to agree to it and then have numerous different implementations implement this. And this is where I hand it back over to Joe. Yeah, so hardware it's pretty much out of scope for the presentation. We did not look at any of this but we thought it would be naive to not at least mention it to people. And what we mean by that are like glitching, side channel, silicon stuff. And so with glitching you have like fault injections and a lot of times people go after things like the signature verification stuff so they'll basically glitch that part and then they'll start running on sign code. And a recent example of some glitching was done by fell overflow for the PS4 SISCON. And I forget the specifics, it's been a while. Really, really good blog post you should check out. But I think it went to like an infinite loop like go to debug mode or something and would say that's not enabled, infinite loop and then there's glitch out of it and initializes debug mode. And so stuff like that obviously should be concerned with then clearly side channel with timing discrepancies, power discrepancies, things like spec or muck down, speculative execution in general. These are where people are leaking secrets for going after keys so they can start signing their own code, stuff like that. And then chip suck. And this is somewhat interesting because it's obviously only relevant for a very sophisticated attacker. It's going to be somebody who has very expensive equipment. They do things like decapping, they use fibs and Sims. They can do things like optical ROM extraction and get the boot ROM and then start auditing that and then, you know, find a bug and exploit it. And obviously totally out of scope for the presentation. But one thing that's interesting about this is kind of presently it's still, you know, not a lot of people have this expensive equipment. But I think very soon you have people like John McMaster and stuff who have like a SEM in their garage, right? And so you're going to eventually start getting these regular hackers in their garage that will eventually get this equipment as the older equipment becomes more affordable and maybe that opens us up to more realistic instead of people just kind of ignoring it and they go, eh, I'm not worried about somebody with, you know, a quarter of a million dollars worth of equipment. Now it's turning into somebody who dropped 10K or 15K. And then, you know, a quick note on code integrity. It's something that people mess up a lot. It's kind of hard to do, right? You have people that do weak or crypto, you have blacklist problems and an example that is, you know, there's finite space for their blacklist. It will eventually get exhausted. So when you have stuff like where I mentioned that you have a signed grub, there's a known bug in a signed grub binary that was really Speckers-Bursky. And if that's not on the blacklist of your Ufi platform at home, you can just load that up and then exploit it and you just broke Secure Boot. And it's not going to get fixed until that platform has an up-to-date blacklist. And eventually, if all this crap gets blacklisted, eventually that list will be full and then they can't blacklist anymore. So it's a concern there. And then you'll have issues where they'll only sign certain portions, not the full blob, so you can, you know, still modify certain parts or sometimes you'll see they'll just check for signature existing, but they don't validate it. You know, really, really dumb stuff. So conclusions. Obviously this is the tip of the iceberg. There's a lot of stuff we didn't look at. And if it wasn't clear, we did not really audit these things. We literally would like chat with each other every day and be like, hey, we need a C by us bug. Okay, give me an hour. Okay, I got one. Okay, check the box and then let's move on to the next one. Our goal was to have an example of a bug for each list of the attack surface, an example of a bug for each list of the thing we looked at. And that was it. So, you know, once we found one, we stopped. So you guys should, you know, go hunting and have fun. But if it wasn't obvious, there's a surprising amount of low quality code. It's kind of crazy. And it's pretty clear that not a lot of people are looking at this stuff. And one thing that kind of sucks is you get to NDA hell really, really, really quick if you want to look at any of this proprietary stuff. So if you're interested in Qualcomm stuff, for example, and you want to get some documentation or look at it, you pretty much have to sacrifice a first born to get access to that stuff. Like it's just not going to happen. And it's kind of silly. So, you know, kind of like our advice and call to action is, you know, people should be minimizing their image, their boot environments, their host environments. You know, turn off features you don't need. If you don't need a network stack, why have it? If you don't need USB, why have it? All you're doing is enabling a attack surface for somebody to leverage. And something that we see a lot, which is insane, is like these little embedded devices that are running Linux and they have literally more drivers than our desktop at home. And it's just like, what is going on here? It doesn't make sense. You should really, really, really work on limiting the attack surface. And really quick mitigations. There aren't any in most environments. Yeah, they just aren't any. As you can see from the example from before, that was, you know, just from this morning, just really quick, you know, smash and, you know, over at the stored PC. And that's it. Like, there's no ASLR. There's no anything like that, code flow integrity, whatnot. But there's a link to a GitHub and that is an Intel employee that has gone and implemented a lot of these mitigations that are moving into Tiana core. So they are way, way, way ahead of the game of everyone else because they're actually getting a lot of these mitigations, which is quite impressive. And you should check it out because it's interesting code. So kind of a call to action. We really hope that this was inspirational to a few of you. If you've never looked at this stuff and it was always this black box that you weren't sure about, you should just start poking around. Go find the slide where we showed where the, you know, build instructions, where and go build some of these things and mess around. And you're going to have fun. And like we said, with no mitigations, you can work on some easier exploit dev stuff and it's cool. But it's clear that a lot of people need to be reviewing this because it's clearly not happening. People should start fuzzing interfaces. Everything we kind of showed should have been found with basic fuzzing. We're kind of at a point where I just said I'm just going to take like a teensy or something and have it just, you know, do that classic descriptor double fetch because I think we've seen that in like every USB stack. Like it just make a device and just start plugging it into stuff and just watch it break. And then obviously periodic reviews and whatnot. But yeah, that's pretty much it. So yeah. Well, thank you. Now we have about 10 minutes for Q and a and we will start immediately with the Internet. Thank you. Has the grab issue been fixed yet? And was the code unique to grab or borrowed from, you know, elsewhere? I don't think it's been fixed yet. And this was the this was from whatever the official group repository was. All right. If you have a question in the room, please line up at the microphone so I can see you. And now microphone number two. So let's say you want to make a more secure laptop. So you came to take poor boot, take a static kernel so that everything is in compiled in no normal no modules. But what about the text text services that such a somebody tries to interrupt the line of why why did this booting for example, that you may be some somehow get into make a maybe DMA access because you you somehow interfere with a let's say Broadcom network device that has some special firmware to optimize the traffic or something and that that this thing gets above over floated above over flow and make some problems on the on the bus or something. Are you talking about attack surface from devices? Yes, it's like that. Yes, I tell you you want to make a good system. So I think the best you can do if you have a laptop that you take a core boot and you take a Linux that you completely compile without module support everything you want to have is in the static kernel and that just boots and the kernel is in the core boot and so it's in the flesh. But you can get a problems by by by let's say some devices that just spit into your memory because they can do a DMA master. Yeah, that's that's that's definitely concern. And that's one of the things we were like, okay, well, if if you do use DMA as it has been forever, then that then it's game over. Luckily, nowadays we have IOMUs. So you depending if which situation you are in and what hardware you have, you can configure your device to use the IOMU. And if you're doing that, then even if a certain hardware device is compromised, you can still try to protect you know your CPU and your host from the device by having the IOMU. That I think I hope it answers your question, but it's about as good an answer as I can come up with. So so that's a bit so this is the maximum you can do against some attacks. I mean from a device, I want to make an extreme hard laptop that you use an extreme hostile environment. So again, you want to make a hard laptop that you use in a hostile environment, right? I mean, I think that's the best you can do right. I mean, you can go and look at your host West and look at how it parses the stuff that comes from the bus because there'll be there'll be bugs there too. But I think that's the best I can come up with. Yeah, I mean, you minimized the attack surface as much as you can, right? And then once once you have it as minimized as possible, then you just kind of hope hope there's nothing there. But you don't then you don't need to code signing because you have everything in your flesh or you still need some stumps. Oh, you mean the stuff that runs on the host? Yeah, I mean, obviously, let's say you have your corporate on the Linux in the flesh. And so everything is that we have that same. And you maybe take this discussion after the talk because we have more questions. Thanks. And signal angel please. What is your favorite disassembly that you use by reverse engineering the bootloaders? We didn't really we just looked at source code. We need to meet a few places. I mean, for this particular particular in this particular case, most of it was white box. So we didn't have much except for the exploit. We didn't have much need for the for this assembler. I guess a little bit of GDP in general when we do do reverse engineering. I mean, I does my go to I've been playing around with Gidra a little bit. It looks promising. Has on do which is nice. But those are usually and then you know for doing Linux have stuff GDP is nice when you're doing debugging. But generally IDA. Microphone number one place. I have two questions. What's your opinion on the arm trusted from architecture? I'm I have to work with this and I'm a little bit shocked. It's a little bit over complicated. And the second question is, should we also question the boot ROMs? Because what I've seen the special project, it leads me to believe that the boot ROM is also very broken. And then is the question if it's really necessary to harden the other stuff. Right. Yep. Those are those are really good questions. By the way, it sounds like you're working on this. So what your first question was what again? What do you think about the arm trust? Right. Yes. I like you. I've touched upon it in a few engagements. Unfortunately, any of the concrete stuff I can't really talk about because it was covered by non. Yeah, I see you where this is this problem. But I just I share your opinion that there are some things in there that are troubling. With regards to the boot ROMs, your spot answer, I mean, we try to bring this up in the one of the slides is if there's a buck there, you can't fix it. Hardware revision is the only way to fix it. So you kind of screwed. There are some designs you can do to try to minimize it. So you could say, okay, well, you can in your boot ROM, you could have a feature that allows for a quote unquote, patching the boot ROM where you can have a piece of something on storage that could overwrite what the boot ROM supposed to do. Obviously, up until that point, whatever's in the boot ROM, still, you can't fix that. But you can you can minimize the amount of stuff in the boot ROM that's not patchable. But you can minimize all of it. I mean, there's going to be some of it that is locked, burned in hardware and can never be fixed for that device. I'd love to hear of a better solution. I don't know of any. No, I was just going to say this kind of touches on when we said people underestimating reverse engineering, they kind of just keep it super, super block box. And it's the secret thing. And then, you know, when somebody finds a way to dump a boot ROM, they start looking at it, then they just see, you know, a bug in a USB USB stack. And then the switch goes down and or the iPhone or whatever else, right? So so yeah, it's from my perspective, that I would say it would make more sense to do more open, open auditing and let more eyes see it instead of hiding it in the corner and in pretending like, well, it's okay because nobody's looking. That's that's at least my perspective on it. I know why why people are super secretive about it. But you need more eyeballs. So maybe if you've got the right context, as my wish would be to get blank chips, so I could flash them with my own boot ROM. So I have a method to prove things and keep the text surface minimum. Yeah. And then there's going to be two other arm dies on there that are circumventing everything that you just did. Do we have more internet questions? Yes. Are you aware of any good and maybe even free bootloader fuzzle? Not in its whole. I mentioned a few places. So if you're doing any kind of file based stuff and you can isolate it, AFL is you know, that's the go to these days for network stuff. There's a couple of interesting ones like is sick and there's some Wi Fi fuzzles and and I think there's you know, some DNS fuzzles or things like that. So that works. I would say the best way in my opinion would be to pull out the interesting components that are doing the parsing and the stuff you're concerned about and write a harness for that. So you don't really need to try to write a fuzzle for that environment. You just pull that feature out and harness it up and then let it you know, run on a bunch of cores. Yes. I think live fuzzle might be very helpful there. All right. Number two, please. Hi. We have producing the occurrence of such errors by using another programming language like that would feature more secure things that compile time or during runtime like maybe Rust. Will it happen? If yes, are there alternative projects that use other languages other than see? I'm not aware. So I think you're right. I think we can reduce the amount of especially the memory corruption stuff. I mean, if you switch to something like Rust, even though I think on occasion there's some Rust corner case that shows up where something doesn't get caught by the verifier, those are weird corner cases. In general, yes. I think you're right. If we switch languages, a lot of memory corruption stuff goes away, but not everything goes away. All the design stuff is still there, right? I'm currently doing that though. Well, so there was actually there was a talk by Andrea Barisani yesterday or day before where he's doing a go runtime for an as a as a base for an ARM device. So this is an avenue that is currently in the beginning of being researched and being worked on. I think it's interesting. I think it's a direction one that we could go into. I think there's something there. At the present time, it still seems a bit too early. And the other thing is that while it does reduce the number of bugs that are going to be there in particular memory corruption stuff, it doesn't like there will still be, you know, your logic bugs and your hardware bugs and things like that. So it's not a silver bullet, but it could definitely help. Okay. And we are out of time. Please thank our speakers again.
 Okay, please welcome our next speakers, Joseph and Ilja, who will be talking about how bootloaders  are broken and how to look into them. Please give them a warm round of applause.  Hello, does this sound okay? Cool. Yeah, so welcome to Boot to Root, auditing bootloaders  by example. I'm Joseph Tartaro. I hack things for IO Active and this is my second time at  Congress, so I'm really excited to be back here. Hi, I'm Ilja. This is my 18 or 19 time  at Congress. Happy to be back here too. I've spoken here, I think, seven or eight times  before and I'm very excited to speak here together with Joe. We've been working together  on bootloaders last year in change and this is minus the NDA coverage stuff. This is some  of the things we've observed and seen, so I'm very excited to do this.  Yeah, so the expected audience for this talk would be embedded systems engineers, security  people who are interested in embedded systems and just curious security people. Just a caveat.  We're going to be quickly going through about like 70 slides or so and a lot of it's just  like examples of C source code, so if you did not realize you were signing up for an  hour of that, feel free to walk out. We're not going to be offended. And then another  caveat would be this isn't really trying to flex and show look at all the bugs we found.  The purpose of this was to kind of show people, hey, if you have not looked at bootloaders  before, this is our recommended areas of attack surface that are interesting. This is probably  where you should get started. And in some examples of nobody's really looking at them  and they should start, so that's pretty much what's going to go on right now. So quickly,  here's the agenda. We'll discuss why they're important. Some of the common ones we looked  at, attack surface and our conclusions. So there's going to be a wide interpretation  of bootloader. So basically what we mean by that is anything that's in your secure boot  chain. And if you don't have experience with these or you haven't looked at them much,  you can kind of think of it like from an operating standpoint of user land calling into kernel  space, you'll have kind of normal world calling into secure world and stuff. And that's kind  of what you're looking for is those pivots and when they're processing, you know, attacker  user control data. So why? Because they're, you know, critical for security. It's a key  component of your chain of trust and it's very obvious that a lot of device designers  are poor at hardening and limiting attack surface. And what we mean by that is a lot  of the devices we've looked at over the last year or so, you'll find devices that have  like full network stacks even though they don't need a network stack. You'll have a  bunch of code loaded up to handle file systems that are never expected. So it just, it doesn't  really make sense why they're not limiting all that attack surface. There's also a huge  under estimate of reverse engineering. People just kind of assuming that there's no bad  actors and nobody's really going to look at this thing and it's this hidden black box  that we should ignore. And a little story behind the presentation is we're actually  on a train going to a baseball game. I was trying to introduce Ilya to the lovely game  of baseball. And we were talking about U-Boot and I pulled out my phone and we went to the  U-Boot GitHub and in about, I don't know, 10 minutes, 15 minutes, we ran into like 10  bugs and we went, yeah, we should probably audit some of this stuff. And kind of inspiration  from a previous talk that Ilya has given at Congress where he audited a bunch of different  BSDs. I said, why don't we look at a bunch of different boot loaders. And so just to  give credit where credit's due, we are not the first to look at any of this stuff. So  this is a list of people that kind of inspired us, have done really interesting work. And  we recommend if you're interested in any of this and you enjoyed it, you should go check  these people out and see things that they have released in papers and stuff like that.  So where are they? Boot loaders are pretty much in everything. You have your workstations,  game consoles, your TV, you know, everything. And generally the security basically depends  on this. So it obviously really, really, really matters. And so with that said, we basically  started looking at these common open source boot loaders. So U-Boot, Core Boot, Grub,  TBIOS, CAFE, which is Broadcom, Ipixie and Tionocore. And we're just looking at what's  on GitHub, what we downloaded. Obviously in your real world scenarios, the devices that  you have at home or go buy and start looking at, they're going to be heavily modified. They're  going to have weird custom drivers that aren't available, things like that. So, you know,  we're not here to argue the likelihood of some of the bugs we found. We're not going  to argue exploitability. Half of them, we don't know if they're exploitable. We don't  know. We will for one. Yeah, we will for one. We don't really like, that's not really the  point of it. The point is to kind of show people, show designers what they should be  concerned with and show interesting, or researchers that might be interested what they should look  at. So U-Boot is extremely common. It's in a ton of devices. There's a huge, very customizable  config for all different sorts of boards and stuff. There's concerns for environment variable  stuff. There's a super powerful shell. So you'll sometimes see even shell injection concerns  based on environment variables. It's pretty funky. And there's lots of drivers for tons  of devices. So it's kind of a great first step of looking at something that kind of  covers a huge breadth of things. And so features of U-Boot that are interesting would be, you  know, network stack for different protocol parsing, file systems. And they also will  load their next stage images from like all sorts of weird, like, archaic things that  nobody uses anymore. And it's just used by tons of devices. And then Core Boot. And I  apologize. This is a little dry right now. We'll eventually get to this stuff. But Core  Boot, you know, it's more targeted towards modern operating systems. There aren't like  legacy bio support. It actually, they took a methodology that other projects don't, which  is they're not going to implement features that they don't want to. So if you're trying  to do network booting or something, you use Core Boot to boot into like Ipixie or something.  They're not going to implement that feature. These are used in Chromebooks. And obviously  some of the interesting parts come from Google. And one main interesting area is SMM. And  then Grub. Obviously you guys are all familiar with this. The primary concern here is a  multi-boot spec. And they support just a ton of file systems. So that's obviously the attack  surface you'd be concerned with. But the interesting part here is that there are U-Fee signed  versions of Grub. So that's kind of like your secure boot break right there. If you find  a vulnerability that's an assigned version, you can now load that into your U-Fee and  exploit that vulnerability and you're good to go. And then CBIOS is the default BIOS for  KEMU KVM. This supports legacy BIOS stuff. So you'll see that this gets booted into from  things like Core Boot. This supports TPM communication. So that's kind of interesting. And it's the  compatibility support module for U-Fee and OVMF. And then Broadcom Cafe. So this is used in a  ton of different network devices and TVs and stuff like that. And the obvious attack surface  there would be network protocols, the network stack. That's what you'd want to look at.  Ipixie. This would be more network-based stuff. Various parsing and similar to Grub. There's  U-Fee signed versions. So it's a great potential pivot for secure boot stuff. And then finally,  Tionakor. There's really no introduction needed here. There's been a ton of great presentations  over the last 15 years. People just doing everything to this thing. And due to that,  since it's pretty much the most scrutinized one out there, it's really mature compared  to everything else. So when you bash Tionakor, realize that it's way better than everything  else. So there's a lot of implementations built on top of it, like platform-specific  stuff, Qualcomm, ABL and XBL, things like that. So you'll have all these. You have the  base Tionakor EDK2 and then you have all the custom stuff built on top. And then related  to bootloaders, you have things like TrustZone. And that's kind of where I mentioned. You  have like normal world and secure world. You'll have these interesting pieces of code that  are running into those secure areas that you're going to want to look for. You know, pivots  into there so you can gain access to secrets. And then obviously from the host operating  system, the attack surface there would be you can modify things like NVRAM. So you can set  variables that when the next time you reboot, the boot loader is going to process as variables.  And this slide's more for reference. Later you can get the slides or take a picture or  something. These are just links to some instructions for building and whatnot. So if you wanted  to start looking at these, you can quickly build a little environment and poke around.  So just really quickly to go through the concept of secure boot, you kind of have your chain  of trust. You'll have the boot ROM that will then verify and load various other loaders  that then verify and load the next thing. And you'll sometimes have a TPM involvement.  You'll have some TrustZone involvement and then OS interaction stuff like the OS basically  setting things like NVRAM which will set boot configuration stuff and whatnot. So the boot  ROM itself is something you've probably seen the talk by Cordy Oryoop, I think earlier.  It's really important because it can't be patched. It's a hardware revision would be  required if vulnerability is found. And it's so early in the stage and you would basically  compromise everything after it that is where you'd want to go. It's extremely bare minimum.  It does some initialization of hardware and memory stuff. And then you'll find things  like maybe implementations of fast boots. You have a USB stack. So that's an obvious  attack surface you'd be interested in. And then it will verify the signature of the next  stage and then boot that. And then you move on to the next stages. And this is where they  start initializing the rest of what's necessary, network stacks, SMM handlers and whatnot. And  they'll basically just keep handing off. And then you'll run into things like trusted boot  and measure boot which is, you know, verification and then measuring which is kind of more for  logging and whatnot doesn't actually mitigate anything. It just kind of alerts you of stuff.  So some hardware environments are a little different. Like the secure world stuff, you'll  have ARM or trust zone. Windows has VTL 0, VTL 1, hypervisor stuff. And then, yeah, I'm basically  repeating myself. And then eventually the operating system, that's going to get the  kernels going to be loaded, it's going to be verified. And then eventually start running  and then you can have fun. So early observations is everything we pretty much looked at that's  open source, there's no privilege separation. So if you were to compromise a piece of component,  you pretty much rule everything. And what's interesting is there are some proprietary  boot loaders that you're starting to see, like Apple, for example, they're doing some  aspect of privilege separation. So if you were to exploit a portion, you didn't necessarily  control the world. And so right now, at least all the stuff we looked at did not have anything  like that. But maybe in the future, we'll see that. So this is the list of the attack  surface that we think people should be interested in and focusing on. You have NVRAM, file systems  and files, all network stack protocol stuff, all various buses, you know, SMM, DMA and  hardware stuff. The interesting thing about buses that we've noticed is that embedded  designers seem to inherently trust anything that end users should never interact with.  So they go, okay, an end user uses USB, so we should verify some of that, but they do  a bad job. But an end user doesn't play with the spy flash, so just inherently trust it.  Or an end user isn't to the TPM. So just if the TPM says something, run with it and they  mess it up a lot. So NVRAM, these are the various environment variables that can be  configured, you know, for the next boot cycle. And like I said, it's basically processing  of user controlled data. So if you start looking at some of these boot loaders, here's the  interesting functions you'd want to look at. For example, in Uboot, you just kind of call  for environment get and grab through and you see them grabbing the environment variable  and see what they do with it. If they're not doing any sort of validation, you're going  to hit a book. And so an example of that would be right here, you see there's an environment  get for boot P VCI. It checks if it existed. It will then do a stir length and then just  mem copy it directly into a buffer without validating that it can fit the buffer. And  this is actually kind of funny earlier today. We were like, ah, we should try to exploit  one of these just to show it. So we toyed with this one and, you know, just do a bunch  of bytes and it starts just kind of sending these weird packets over the wire and a bunch  of boot P stuff. You'll see later on you just have full raw packets of whatever payload  we send. But it wasn't very realistic. It kind of went, started getting into like the  key move like network implementation stuff. So we kind of avoided and moved on to a different  bug. But as you can see, it's very easy for you to start looking at the stuff and being  interested in it and quickly set up an environment and mess with exploitation and we'll get into  it but there's no mitigations. So as you see, there's a bit of a pattern here. Environment  get host name, mem copy with stir length. No checks. 128 byte buffer, environment get  boot dev, stir copy. It just keeps happening. This is kind of what we were talking about.  Just the quality code is not very great. This is, what's funny is when we were messing with  that boot P VCI stuff earlier this morning, we went, oh, this is going to be more involved.  So it was like, well, let me just go find a different bug. You know, 10 minutes later,  it's like, oh, I found a different stack smash. Okay, let's work on that one. It's just like,  this is a perfect example. The environment get the variable and then they'll grab the  very first element of that variable as a length and then use that as a length. And it keeps  happening. So just a quick example. See this. So the attack scenario of this would be, you  have a device, you have NV RAM that you can physically modify as you have physical access.  And this is kind of an example of the default NV RAM. So we just threw an environment variable  with 600 bytes and you'll see towards the bottom there's four bytes where we threw a function  in there and that's the address. So just this had to do with the GFFS to file system loading.  So you just do FS load. And that's it.  That's shellcode being executed.  So this is...  Sorry, I can't see. So obviously, if you've never looked at this stuff, it's kind of fun  to play around with and you should start poking at it because why not? And screenshot.  Cool.  So that was the NV RAM attack surface which is usually the most fun to play with. Programming  to spy flash sometimes may take a little bit of fiddling but in terms of attack surface  and fun things to play with, it's, you know, as Joe said, often overlooked and so it's  easy to toy with. And so you saw all this Esperant Devs and MIM copies and string copies.  So there's a lot of fun there. But obviously there's not just NV RAM. There's more attack  surface to sort of a trusted boot environment. And obviously one of them is the file system  right because this thing needs to boot and it needs to find images and they're stored  somewhere and your file system sort of brings order to that chaos. So basically you need  to mount your file system and often file systems are not signed or are technically checked  or not all of it is because before you can do that, you need to be able to read something,  and so obviously an example of a common file system would be the file system. If your boot  environment supports loading your USB drive and for storage, it's probably going to be  fat. Depending on, and the flash itself may have its own proprietary format or it may  use X2 or something else. But clearly the file system parsers, I mean that's prime attack  surface. A closely related is obviously the files inside of your file system, right? Now  depending on what your boot environment looks like, some of these files are going to be  integrity checked but some of them might not be, right? And so those file parsers are interesting  attack surface. And if you're either looking for bugs or you're building a product, we  would highly recommend fuzzing these. And it's like starting with AFL is probably a  good starting point. But we'll show some examples of some bugs we saw in certain, in a number  of boot loaders. So we'll cover X2, we'll cover a bitmap splash parsing one. And then  the other ones are sort of examples of where there could be bugs but those two we'll cover.  So this is grub, and this is grub X2, and grub X2, you know, this is the sim link code  so it looks to file system and it goes, oh, okay, this is the sim link, how do I parse  the sim link? And so the sim link says, hi, I'm a sim link, I'm this big. And what grub  does is, oh, great, I'll allocate that much size but I'll do one more for an old byte.  And of course that is a classic in Azure overflow. And the grub memory allocator actually returns  a valid pointer for a zero size. So this is a perfect primitive so you get a pointer to  something that is zero size and then it actually reads the sim link content from the file system  into a zero size buffer and obviously that's going to cause memory corruption. And a primitive,  you can't see it here but a primitive is really nice because that particular read function  actually, if there's no much more on disk, it stops reading. So even though you can  save, read four gigs, you can make the layout so it only reads, let's say, a thousand bytes  or a hundred bytes. And so you have this near perfect primitive to cause memory corruption.  This was in Tiana Core, for example, this was the bitmap splash screen parser and I  don't know anything about bitmap internals. It's a very simple format but basically you  can have a four-bit bitmap and that gives you a pallet of four by four which is 16 bytes.  And so the idea is if you have a four-bit bitmap, then it has a 16 byte pallet and so it goes  and reads that 16 byte pallet except you tell it how big the pallet is and you can say,  okay, I know you're expecting a 16 byte pallet but I'm giving you a 256 byte pallet and it  will read it into a 16 byte buffer. So that was broken and then for the 8-bit bitmaps,  similarly it was broken the same way. And these are just a tip of the iceberg. There  are many, many, many more. This did not take long to find. But let's move on. Obviously  now that we've looked at some local stuff and some physical stuff, what about remote?  What is there? Obviously if you're talking remote in the modern world, you're talking  TCP IP. So you need a TCP IP stack and you need to have some services that you either  expose or that you have client code for that you go talk to. And that's bootp and DHCP  and DNS and iSCUSY and NFS. And if you're in a corporate, if you're a corporate net,  you probably want to have IPsec and then HTP and HTTPS and TFTP. And sure enough, most  bootloaders have code for this and then you start asking, okay, what's the attack surface?  For TCP IP, if you implement your own stack, well, good luck because you're going to screw  it up. But secondly, it's like, okay, well, if you look at these things, you take a step  back and say, okay, well, really this is all mostly TLV parsing. And so you go and look  into what are the things that can go wrong if you do TLV parsing and they'll be out of  bound reads pretty much everywhere and you'll see in those loops and lots of places and  things like that. If you look at the protocol at the top of that, like DHCP and DNS, you  have your standard network attacks where you'll see lease stealing or cash poisoning or things  like that if you don't protect your ID. So if you have a static ID or you don't validate  your IDs or you generate predictable IDs, you can have these kind of poisoning, stealing,  man-to-middle attacks. And then thirdly, obviously, the thing we really like to see is memory  corruption bugs. At the end of the day, you take network data and you parse it and if  you do it wrong, you may cause memory corruption bugs. Another sometimes overlooked interesting  bug I think when you're doing network parsing is when you have information leaks. So this  often manifests itself, I mean, hard bleed, of course, was one example. It was a perfect  primitive. But generally, it will be this thing where you end up generating some kind  of pack as a response to something and you'll have done the memory allocation but for some  reason not initialize something and so you end up sending initialized data over the network.  So this is sort of the common things you see network stacks in general. So if you are looking  for these kind of bugs in a boot environment or if you are building a product that does  this, I would highly recommend fuzzing them. There are numerous interesting network fuzzers.  If you're looking for network stack fuzzing, I would recommend ISIC. It's pretty old but  it's still incredibly, incredibly effective. It tends to break most network stacks.  So with that said, let's show some examples. I was, so UBoot, for example, this is the  UBoot DNS code and if you see that, the TID, that's the DNS ID and it's basically, they  give it a, they use the static DNS ID of one for all DNS packets that they send out. So  doing DNS man in the middle on a UBoot environment is extremely trivial. You guess the DNS ID  by saying that it's one and you are correct 100% of the time. So this is Broadcom's coffee  and this is the DHP parser and it basically has this sort of junk stack buffer where it  just needs to read something out of a buffer and it goes and says, okay, well, get me the  length of that thing and it's a UIN date. So that means it can represent 0 up to 255  and then it reads 0 up to 255 into that junk buffer. So that's a stack corruption right  there. If you then look at the coffee at the DHP parser, it's very similar where in this  case it has a 512 byte buffer and then it basically copies the entire RX buffer into  it and this is Ethernet so up to 1500 bytes gets copied into this 512 byte buffer again  causing memory corruption. Obviously we're not done with coffee yet because it has such  beautiful code. So this is the coffee ICFP ping handler and this has this really cute  sort of use after free bug or double free where it basically sends out a ping and then  it sits there receiving the, you see the while loop there and it basically sits there receiving  packets until it finds the right one but it also, because it doesn't want to have it  on its loop, it has a timeout and there's this interesting condition where if the last  thing it looked was the packet you were looking for but it also timed out at the exact same  time it freeze that packet twice which obviously can lead to memory corruption. Again we're  not done with coffee yet. Oh right there we go. Not done with coffee yet so this is the  IP handling coffee and if anybody has ever looked at an IP header which I would assume  most of you have, you'll know it has an IP header length and a total length and of course  coffee needs to know this because it needs to know where stuff is but coffee validates  neither the IP header length or the total length so once you start messing with those  coffee blows up really fast. So that was sort of a quick overview of all the trivial TCP  and TCP related bugs that show up in your after boot loader. So but let's say you got  that covered and let's say, you know, okay what's the next thing? What more sort of network  stuff can we do? And then of course what comes to mind is Wi-Fi, you know, 8 or 2.11. And  a surprising number of boot loaders don't have 8 or 2.11 so I don't know if that's sort  of a sort of on purpose or just sort of we didn't get to having this feature yet but  we will at some point and obviously it'll have bugs when we implement it. But we did  find one that has it and I'll get to that in a second. One thing I did want to mention  is that if you look at 8 or 2.11 like frame parsing, depending on which device you have  and particularly which radio your device is using, you'll have radios that do a lot of  parsing on the radio in which case the stack is kind of covered because it's, at least  you hope it is where the radio does a bunch of validation. But then there's a whole bunch  of radios that sort of, you know, they take package from the wire and they just don't  do anything and just pass it on to the OS. That's the stuff that's interesting from  a, from a tax service point of view if you look into attack the boot loader and not the  firmware. So yeah, we looked at Pixi and of course, you know, anytime you do any kind  of Wi-Fi stuff the first thing you do is you're looking for an SSID, right? This is what this  thing does and, you know, it sort of has this SSID buffer which an SSID can be up to 32 bytes  so that is 32, well, it's 33 bytes because it's 32 plus 1 and it has this loop where  it sort of goes over IE's that it gets and then when it finds the right, the IE for an  SSID it says okay, we'll take this IE and we'll do IE length and IE length is a U and 8 so  it can be up to 255 and it copies the SSID IE into the SSID buffer which is only 32 bytes  causing memory corruption. So that's iPixie for you. Okay, so the next one if you're thinking  networking would be Bluetooth and Joe and I have actually we've looked at proprietary  bootloaders that have Bluetooth support. Unfortunately, we can't talk about those bugs because they're  covered by non-scope agreements and we tried really, really hard to find a similar equivalent  in any kind of open source bootloader and we couldn't find one. So unfortunately, we  can't give examples of sort of Bluetooth bugs in open source bootloaders but I do kind of  want to in general terms talk about what we have seen and where we suspect the bugs are  going to be if somebody does do this in an open source bootloader or something that's  a new bootloader. So and also like if you're going to do Bluetooth in a bootloader it's  usually for you know HID device right this is for keyboard mouse this usually ends up  being for consumer devices. But in general if you look at Bluetooth stack and you're  looking for any kind of you know parsing bugs there's three sort of recurring teams. There's  three sort of recurring teams that we saw when we looked at the Bluetooth stacks that  we have and this is if you look at the lower layers like L2P cap and things like that and  this is usually related to sort of frames and frame lengths so very, very large frames.  So a frame can be up to about 65,000 bytes because the length is a UN16 and so if you  create really large frames like right up to the edge that tends to blow up Bluetooth  stacks. The other one is if you create very, very, very short frames you know less than  what something is expecting that tends to blow up your Bluetooth stack. And then lastly  because L2CAP can have fragmentation so you can have individual fragments that you will  add together and every fragment can be X amount of bytes but the whole thing can be up to  65,000 bytes a byte, 65,000 number of bytes. So if you start playing around with the fragmentation  we've numerous Bluetooth stacks have blown up. Again, I wish I could have shown an actual  bug here but I wasn't able to find any in the open source boot loaders. So moving on  to USB, this is a primate attack surface in boot loaders obviously. If you haven't followed  the news in the last couple of weeks and months this has shown up in a number of devices.  This is at least up till recently I think was sort of under reported or sort of people  didn't quite care about it. But to me the USB stack is like that's the if I, any time  I look at a USB loader at a boot loader my first thought is you know NV RAM and number  two is USB. And USB is interesting because obviously a lot of boot loaders support USB  because they'll use it either for storage or you know things like Internet dongles but  often for storage where you know either you expose certain files or you try to do some  kind of recovery boot from USB or something like that. And so basically if you start looking  at how USB works at a slightly lower level it's not quite like it's not like PCI it's  more packet based and so what happens when a device talks to a host the device is asked  for quote unquote descriptors. And these descriptors say certain things about your device and based  upon the number of descriptors that the host asks from you and all the answers you give  them in the script responses the host can then figure out what kind of device you are  and what class you are and what functionality you expose and all these kind of things. And  so a lot of these descriptors end up you know being parsed and being parsed wrong. And so  generally we often see either straight up overflows or double fetches because the way  descriptors work is they're variable length content but the headers are predefined and  the way it works is you first ask for the header and then based on the length of the  header you ask for the thing again except the USB protocol doesn't allow you to just  get the payload you have to reread the whole thing so you have to reread the header that  you already had. And so in most implementation what happens is you go get the header you  allocate a buffer and then you go get the header and payload again and you override  the original header. Which means is you get to override the original header length and  so you can have a talktow where your device gives you a header with a good length and  then the second time it gives you a descriptor with a bad length and if your host doesn't  validate that both lengths are the same bad things happen. And yeah, straight up overflows  happen too because nobody ever expects the USB device. There's an example in Grubb for  example where it goes and gets a descriptor and the descriptor says oh here's my config  account I have this number of configurations go and fetch those in descriptors as well.  And there is a predefined array of number of configurations that Grubb has and it doesn't  correlate that with the config count. It just always assumes the config count is less or  equal to the array. And so if you have a malicious device and you say hey I know your array is  32 bytes, 32 elements but I'm going to give you 64 configurations. It'll happily write  64 configurations in a place that can only hold 32 of them. And exactly the same thing  for number of interfaces. Tiana core had similar bugs where this was Tiana core where  they go and get a descriptor and the descriptor length says okay now go fetch me the whole  thing and use that descriptor length except the original hub descriptor was a very small  struct and the descriptor length is a U and 8 so you can set up to 255 bytes and so that  would have smashed memory and caused a stack corruption. And so as you can see here the  fix here wasn't actually at a bound check but just to make the buffer bigger because  you know the length is U and 8 so if you just make the buffer 256 then any length you give  it will fit within the buffer. Yeah this is an example in C BIOS where this is the classic  double fetch where it goes and gets the header, does an alloc based on the header and then  gets the header again with the content and it doesn't verify that config W total length  is the same thing as CFG to W total length and because that verification isn't there  whoever calls this thing can no longer trust W total length because it could be invalid.  And so as I said USB to me is one of the prime attack services to secure boot and so I want  to sort of very very briefly mention two recent real world cases where devices got broken  into because of USB parsing in the boot loader. So this was this is a case of the Nintendo  switch the Tegra this was done by the failover flow people about a year or so ago that basically  you know you give it a length that's not validated and then a mem copy and that causes memory  corruption and then the recent iPhone checkmate this is slightly more complicated because  it wasn't a straight memory corruption but it was you know if you fiddle around enough  with the state it sort of gets out of sync and it has all these pointers that it's still  considered to be alive but the memory has been freed and so you end up this ends up  what you use after free but it is because of a sequence of USB packets that are being  sent. Right so that's it for USB obviously bunch of the buses or almost any bus on your  device if your boot chain uses it is interesting attack surface and this is spy I mean spy  flash and be trusted, SDIO, I2C, LPC even your TPM right even your TPM response you  get back from TPM can't be trusted because somebody could desolder your TPM and pretend  to be your TPM and if you don't now validate the data you get from TPM you end up with  memory corruption. So this is for example what happened in CBIOS. CBIOS has this talk  show TPM and it goes and gets this structure and you can send it less than what it expects  and then basically they subtract some size of a struct minus less what they expect and  so that causes integer underflow which ends up with a really big size and then that size  is given to malloc and malloc internally has an end overflow so that really big size then  becomes a very small size and then they copy into it and that causes memory corruption  and so this is a combination of two bugs right one is where the sizes are wrong and  then secondly is where the malloc has an internal integer overflow and this is the malloc internals  of CBIOS which I don't want to dive into now because it's pretty convoluted and complex  I'll leave this as an exercise to the audience to figure out where the int overflow is and  technically it's not an overflow because it's a bunch of shifting being done but it essentially  comes down to an int overflow. Yeah, there we go. Yep, there we go. Okay. So another  service attack service that is interesting but often overlooked on devices except for  Ufie is system management mode and I mean there have been over the last decade and a  half numerous presentations about SMM attack service and break SMM handlers for Ufie because  it's an x86 thing and you see this in Ufie stacks and it was a cat and mouse game where  for years somebody breaks something and then Ufie fixes it and then somebody breaks it  again and Ufie fixes it again and somebody makes it again and Ufie goes okay let's do  mitigation for this and this has gone on for like 15, 16 years and occasionally people  still find bugs but by and large Ufie does fairly well now with regards to SMM handling.  There's some third party stuff that still breaks occasionally but in general they got a handle  on this. Now what if you're using x86 but you re-implement your own boot loader and  you don't use Ufie, right? Well that means you're going to run into all the same problems  Ufie had and you're going to screw it up in all the same ways and it'll take you another  15 years to get it right. But I guess if you were to try it the first time this is what  Corboot does and to their credit they say oh we get input we should range check it and  their range check says to do. Okay so now I talked about a bunch of buses. The thing  to me that sort of separates that from other things is when you do DMA. Generally for as  long as DMA has been around DMA is game over. If you get DMA then that's that there's no  trust boundary. Obviously that's no longer true. We have IOMM use and if you use them  and if you have a device that has this available then old-sodd DMA can be stopped, it can be  contained, it can be regulated and so it's no longer a sort of game over and you can  implement a trust boundary. A few things there. A if you are an embedded device and you're  using IOMM use you are way ahead of the curve because not that many people are doing this  right. You should but it takes some effort. There's obviously many different IOMM use  it depends on your architecture and sort of the board you have and all sorts of things.  So Intel's VDD, ARM is SMMU, AMD has like the device exclusion and it's got a few other  ones as well. But basically if you use one of these you can sort of DMA is no longer  the game over. Now that doesn't mean that you're in the clear. Once you define DMA as  an attack surface you have to defend it and that's where you get some difficulty because  you'll end up using drivers that have been written before it was a trust boundary and  I mean no one has ever written a DMA handler with a trust boundary in mind because you  assume there's no trust boundary. So now if you start using the IOMM you have to go back  and look at where am I doing DMA and now I can no longer trust what's in when I get  back from DMA and you have to go validate all this stuff. But even if you do all of  that right which by the way is very hard and you probably won't do it right but let's say  you do. Secondly because DMA is now a trust boundary any time you open up a memory window  for a device you can't just open it up you have to clear the memory first because otherwise  now you're leaking memory to a device right. So all these sort of new things sort of show  up if you take DMA as a trust boundary. And let's say you do that right well now you still  have a dependency on the IOMM you because you are assuming the IOMM you's perfect when  it probably isn't right. I haven't really gotten to this part yet but one of my plans  for the future is to go look at IOMM you and see if I can attack IOMM you and then find  bugs there. I strongly suspect there will be side channels and logic bugs and maybe  maybe even some heart room implementation bugs. So bug-wise this is where it sort of  gets design-y right. So this is what this is Ufie today, it's EDK2 platform code where  it has support for IOMM you and they're ahead of the curve. But if you look at the spec  there's no good handover protocol from Ufie to the next stage. And so Ufie basically boots  up and very early configures the IOMM you and make sure that devices can't peek or poke  arbitrary physical memory and then it does all of its stages and then it's about to hand  off and it goes well I don't know if the next guy supports IOMM you so it undoes all the  IOMM program it does, turns the thing off, opens up everything and then hands it over  to the next guy. So you did all this work for nothing. And this is a spec bug and it's  being worked on, people are very much aware of this. People at Apple have fixed this for  their devices. This is going to get fixed in the future but given that this has to be  done by spec it takes a while because you have to get people to agree to it and then  have numerous different implementations implement this. And this is where I hand it back over  to Joe.  Yeah, so hardware it's pretty much out of scope for the presentation. We did not look  at any of this but we thought it would be naive to not at least mention it to people.  And what we mean by that are like glitching, side channel, silicon stuff. And so with glitching  you have like fault injections and a lot of times people go after things like the signature  verification stuff so they'll basically glitch that part and then they'll start running on  sign code. And a recent example of some glitching was done by fell overflow for the PS4 SISCON.  And I forget the specifics, it's been a while. Really, really good blog post you should check  out. But I think it went to like an infinite loop like go to debug mode or something and  would say that's not enabled, infinite loop and then there's glitch out of it and initializes  debug mode. And so stuff like that obviously should be concerned with then clearly side  channel with timing discrepancies, power discrepancies, things like spec or muck down, speculative  execution in general. These are where people are leaking secrets for going after keys so  they can start signing their own code, stuff like that. And then chip suck. And this is  somewhat interesting because it's obviously only relevant for a very sophisticated attacker.  It's going to be somebody who has very expensive equipment. They do things like decapping, they  use fibs and Sims. They can do things like optical ROM extraction and get the boot ROM  and then start auditing that and then, you know, find a bug and exploit it. And obviously  totally out of scope for the presentation. But one thing that's interesting about this  is kind of presently it's still, you know, not a lot of people have this expensive equipment.  But I think very soon you have people like John McMaster and stuff who have like a SEM  in their garage, right? And so you're going to eventually start getting these regular  hackers in their garage that will eventually get this equipment as the older equipment  becomes more affordable and maybe that opens us up to more realistic instead of people just  kind of ignoring it and they go, eh, I'm not worried about somebody with, you know, a quarter  of a million dollars worth of equipment. Now it's turning into somebody who dropped 10K  or 15K. And then, you know, a quick note on code integrity. It's something that people  mess up a lot. It's kind of hard to do, right? You have people that do weak or crypto, you  have blacklist problems and an example that is, you know, there's finite space for their  blacklist. It will eventually get exhausted. So when you have stuff like where I mentioned  that you have a signed grub, there's a known bug in a signed grub binary that was really  Speckers-Bursky. And if that's not on the blacklist of your Ufi platform at home, you  can just load that up and then exploit it and you just broke Secure Boot. And it's not  going to get fixed until that platform has an up-to-date blacklist. And eventually, if  all this crap gets blacklisted, eventually that list will be full and then they can't  blacklist anymore. So it's a concern there. And then you'll have issues where they'll  only sign certain portions, not the full blob, so you can, you know, still modify certain  parts or sometimes you'll see they'll just check for signature existing, but they don't  validate it. You know, really, really dumb stuff. So conclusions. Obviously this is the  tip of the iceberg. There's a lot of stuff we didn't look at. And if it wasn't clear,  we did not really audit these things. We literally would like chat with each other every day  and be like, hey, we need a C by us bug. Okay, give me an hour. Okay, I got one. Okay, check  the box and then let's move on to the next one. Our goal was to have an example of a  bug for each list of the attack surface, an example of a bug for each list of the thing  we looked at. And that was it. So, you know, once we found one, we stopped. So you guys  should, you know, go hunting and have fun. But if it wasn't obvious, there's a surprising  amount of low quality code. It's kind of crazy. And it's pretty clear that not a lot of people  are looking at this stuff. And one thing that kind of sucks is you get to NDA hell really,  really, really quick if you want to look at any of this proprietary stuff. So if you're  interested in Qualcomm stuff, for example, and you want to get some documentation or  look at it, you pretty much have to sacrifice a first born to get access to that stuff.  Like it's just not going to happen. And it's kind of silly. So, you know, kind of like  our advice and call to action is, you know, people should be minimizing their image, their  boot environments, their host environments. You know, turn off features you don't need.  If you don't need a network stack, why have it? If you don't need USB, why have it? All  you're doing is enabling a attack surface for somebody to leverage. And something that  we see a lot, which is insane, is like these little embedded devices that are running Linux  and they have literally more drivers than our desktop at home. And it's just like, what  is going on here? It doesn't make sense. You should really, really, really work on limiting  the attack surface. And really quick mitigations.  There aren't any in most environments.  Yeah, they just aren't any. As you can see from the example from before, that was, you  know, just from this morning, just really quick, you know, smash and, you know, over  at the stored PC. And that's it. Like, there's no ASLR. There's no anything like that, code  flow integrity, whatnot. But there's a link to a GitHub and that is an Intel employee  that has gone and implemented a lot of these mitigations that are moving into Tiana core.  So they are way, way, way ahead of the game of everyone else because they're actually  getting a lot of these mitigations, which is quite impressive. And you should check  it out because it's interesting code.  So kind of a call to action. We really hope that this was inspirational to a few of you.  If you've never looked at this stuff and it was always this black box that you weren't  sure about, you should just start poking around. Go find the slide where we showed where the,  you know, build instructions, where and go build some of these things and mess around.  And you're going to have fun. And like we said, with no mitigations, you can work on  some easier exploit dev stuff and it's cool. But it's clear that a lot of people need to  be reviewing this because it's clearly not happening. People should start fuzzing interfaces.  Everything we kind of showed should have been found with basic fuzzing. We're kind of at  a point where I just said I'm just going to take like a teensy or something and have  it just, you know, do that classic descriptor double fetch because I think we've seen that  in like every USB stack. Like it just make a device and just start plugging it into stuff  and just watch it break. And then obviously periodic reviews and whatnot. But yeah, that's  pretty much it. So yeah.  Well, thank you. Now we have about 10 minutes for Q and a and we will start immediately with  the Internet. Thank you. Has the grab issue been fixed yet? And was the code unique to  grab or borrowed from, you know, elsewhere? I don't think it's been fixed yet. And this  was the this was from whatever the official group repository was.  All right. If you have a question in the room, please line up at the microphone so I can  see you. And now microphone number two. So let's say you want to make a more secure laptop.  So you came to take poor boot, take a static kernel so that everything is in compiled in  no normal no modules. But what about the text text services that such a somebody tries to  interrupt the line of why why did this booting for example, that you may be some somehow get  into make a maybe DMA access because you you somehow interfere with a let's say Broadcom  network device that has some special firmware to optimize the traffic or something and that  that this thing gets above over floated above over flow and make some problems on the on  the bus or something. Are you talking about attack surface from devices? Yes, it's like  that. Yes, I tell you you want to make a good system. So I think the best you can do if  you have a laptop that you take a core boot and you take a Linux that you completely compile  without module support everything you want to have is in the static kernel and that just  boots and the kernel is in the core boot and so it's in the flesh. But you can get a problems  by by by let's say some devices that just spit into your memory because they can do a DMA  master. Yeah, that's that's that's definitely concern. And that's one of the things we were  like, okay, well, if if you do use DMA as it has been forever, then that then it's game  over. Luckily, nowadays we have IOMUs. So you depending if which situation you are in and  what hardware you have, you can configure your device to use the IOMU. And if you're doing  that, then even if a certain hardware device is compromised, you can still try to protect  you know your CPU and your host from the device by having the IOMU. That I think I hope it  answers your question, but it's about as good an answer as I can come up with. So so that's  a bit so this is the maximum you can do against some attacks. I mean from a device, I want  to make an extreme hard laptop that you use an extreme hostile environment. So again, you  want to make a hard laptop that you use in a hostile environment, right? I mean, I think  that's the best you can do right. I mean, you can go and look at your host West and  look at how it parses the stuff that comes from the bus because there'll be there'll  be bugs there too. But I think that's the best I can come up with. Yeah, I mean, you minimized  the attack surface as much as you can, right? And then once once you have it as minimized  as possible, then you just kind of hope hope there's nothing there. But you don't then  you don't need to code signing because you have everything in your flesh or you still  need some stumps. Oh, you mean the stuff that runs on the host? Yeah, I mean, obviously,  let's say you have your corporate on the Linux in the flesh. And so everything is that we  have that same. And you maybe take this discussion after the talk because we have more questions.  Thanks. And signal angel please. What is your favorite disassembly that you use by reverse  engineering the bootloaders? We didn't really we just looked at source code. We need to  meet a few places. I mean, for this particular particular in this particular case, most of  it was white box. So we didn't have much except for the exploit. We didn't have much need for  the for this assembler. I guess a little bit of GDP in general when we do do reverse engineering.  I mean, I does my go to I've been playing around with Gidra a little bit. It looks promising.  Has on do which is nice. But those are usually and then you know for doing Linux have stuff  GDP is nice when you're doing debugging. But generally IDA. Microphone number one place.  I have two questions. What's your opinion on the arm trusted from architecture? I'm  I have to work with this and I'm a little bit shocked. It's a little bit over complicated.  And the second question is, should we also question the boot ROMs? Because what I've  seen the special project, it leads me to believe that the boot ROM is also very broken. And  then is the question if it's really necessary to harden the other stuff. Right. Yep. Those  are those are really good questions. By the way, it sounds like you're working on this.  So what your first question was what again? What do you think about the arm trust? Right.  Yes. I like you. I've touched upon it in a few engagements. Unfortunately, any of the  concrete stuff I can't really talk about because it was covered by non. Yeah, I see you where  this is this problem. But I just I share your opinion that there are some things in there  that are troubling. With regards to the boot ROMs, your spot answer, I mean, we try to  bring this up in the one of the slides is if there's a buck there, you can't fix it.  Hardware revision is the only way to fix it. So you kind of screwed. There are some designs  you can do to try to minimize it. So you could say, okay, well, you can in your boot  ROM, you could have a feature that allows for a quote unquote, patching the boot ROM  where you can have a piece of something on storage that could overwrite what the boot  ROM supposed to do. Obviously, up until that point, whatever's in the boot ROM, still,  you can't fix that. But you can you can minimize the amount of stuff in the boot ROM that's  not patchable. But you can minimize all of it. I mean, there's going to be some of it  that is locked, burned in hardware and can never be fixed for that device. I'd love  to hear of a better solution. I don't know of any.  No, I was just going to say this kind of touches on when we said people underestimating reverse  engineering, they kind of just keep it super, super block box. And it's the secret thing.  And then, you know, when somebody finds a way to dump a boot ROM, they start looking  at it, then they just see, you know, a bug in a USB USB stack. And then the switch goes  down and or the iPhone or whatever else, right? So so yeah, it's from my perspective,  that I would say it would make more sense to do more open, open auditing and let more  eyes see it instead of hiding it in the corner and in pretending like, well, it's okay because  nobody's looking. That's that's at least my perspective on it. I know why why people are  super secretive about it. But you need more eyeballs.  So maybe if you've got the right context, as my wish would be to get blank chips, so  I could flash them with my own boot ROM. So I have a method to prove things and keep the  text surface minimum.  Yeah. And then there's going to be two other arm dies on there that are circumventing everything  that you just did.  Do we have more internet questions?  Yes. Are you aware of any good and maybe even free bootloader fuzzle?  Not in its whole. I mentioned a few places. So if you're doing any kind of file based  stuff and you can isolate it, AFL is you know, that's the go to these days for network stuff.  There's a couple of interesting ones like is sick and there's some Wi Fi fuzzles and  and I think there's you know, some DNS fuzzles or things like that. So that works.  I would say the best way in my opinion would be to pull out the interesting components that  are doing the parsing and the stuff you're concerned about and write a harness for that.  So you don't really need to try to write a fuzzle for that environment. You just pull  that feature out and harness it up and then let it you know, run on a bunch of cores.  Yes. I think live fuzzle might be very helpful there.  All right. Number two, please.  Hi. We have producing the occurrence of such errors by using another programming language  like that would feature more secure things that compile time or during runtime like maybe  Rust. Will it happen? If yes, are there alternative projects that use other languages other than  see? I'm not aware.  So I think you're right. I think we can reduce the amount of especially the memory corruption  stuff. I mean, if you switch to something like Rust, even though I think on occasion  there's some Rust corner case that shows up where something doesn't get caught by the  verifier, those are weird corner cases. In general, yes. I think you're right. If we  switch languages, a lot of memory corruption stuff goes away, but not everything goes away.  All the design stuff is still there, right?  I'm currently doing that though.  Well, so there was actually there was a talk by Andrea Barisani yesterday or day before  where he's doing a go runtime for an as a as a base for an ARM device. So this is an  avenue that is currently in the beginning of being researched and being worked on. I  think it's interesting. I think it's a direction one that we could go into. I think there's  something there. At the present time, it still seems a bit too early. And the other thing  is that while it does reduce the number of bugs that are going to be there in particular  memory corruption stuff, it doesn't like there will still be, you know, your logic bugs and  your hardware bugs and things like that. So it's not a silver bullet, but it could definitely  help.  Okay. And we are out of time. Please thank our speakers again.
36c3-10706-eng-deu-rus-Boot2root_hd_0_59.png 36c3-10706-eng-deu-rus-Boot2root_hd_60_107.png 36c3-10706-eng-deu-rus-Boot2root_hd_108_251.png 36c3-10706-eng-deu-rus-Boot2root_hd_252_779.png 36c3-10706-eng-deu-rus-Boot2root_hd_780_1079.png 36c3-10706-eng-deu-rus-Boot2root_hd_1080_1127.png 36c3-10706-eng-deu-rus-Boot2root_hd_1128_1715.png 36c3-10706-eng-deu-rus-Boot2root_hd_1716_2231.png 36c3-10706-eng-deu-rus-Boot2root_hd_2232_2771.png 36c3-10706-eng-deu-rus-Boot2root_hd_2772_4535.png 36c3-10706-eng-deu-rus-Boot2root_hd_4536_6755.png 36c3-10706-eng-deu-rus-Boot2root_hd_6756_6875.png 36c3-10706-eng-deu-rus-Boot2root_hd_6876_9383.png 36c3-10706-eng-deu-rus-Boot2root_hd_9384_12455.png 36c3-10706-eng-deu-rus-Boot2root_hd_12456_12563.png 36c3-10706-eng-deu-rus-Boot2root_hd_12564_13163.png 36c3-10706-eng-deu-rus-Boot2root_hd_13164_13775.png 36c3-10706-eng-deu-rus-Boot2root_hd_13776_14711.png 36c3-10706-eng-deu-rus-Boot2root_hd_14712_14891.png 36c3-10706-eng-deu-rus-Boot2root_hd_14892_15743.png 36c3-10706-eng-deu-rus-Boot2root_hd_15744_16031.png 36c3-10706-eng-deu-rus-Boot2root_hd_16032_16199.png 36c3-10706-eng-deu-rus-Boot2root_hd_16200_21071.png 36c3-10706-eng-deu-rus-Boot2root_hd_21072_22115.png 36c3-10706-eng-deu-rus-Boot2root_hd_22116_22559.png 36c3-10706-eng-deu-rus-Boot2root_hd_22560_24347.png 36c3-10706-eng-deu-rus-Boot2root_hd_24348_24455.png 36c3-10706-eng-deu-rus-Boot2root_hd_24456_25679.png 36c3-10706-eng-deu-rus-Boot2root_hd_25680_25763.png 36c3-10706-eng-deu-rus-Boot2root_hd_25764_26963.png 36c3-10706-eng-deu-rus-Boot2root_hd_26964_27035.png 36c3-10706-eng-deu-rus-Boot2root_hd_27036_27227.png 36c3-10706-eng-deu-rus-Boot2root_hd_27228_27311.png 36c3-10706-eng-deu-rus-Boot2root_hd_27312_28679.png 36c3-10706-eng-deu-rus-Boot2root_hd_28680_29387.png 36c3-10706-eng-deu-rus-Boot2root_hd_29388_30659.png 36c3-10706-eng-deu-rus-Boot2root_hd_30660_30887.png 36c3-10706-eng-deu-rus-Boot2root_hd_30888_32867.png 36c3-10706-eng-deu-rus-Boot2root_hd_32868_33251.png 36c3-10706-eng-deu-rus-Boot2root_hd_33252_33599.png 36c3-10706-eng-deu-rus-Boot2root_hd_33600_34307.png 36c3-10706-eng-deu-rus-Boot2root_hd_34308_34883.png 36c3-10706-eng-deu-rus-Boot2root_hd_34884_40679.png 36c3-10706-eng-deu-rus-Boot2root_hd_40680_42059.png 36c3-10706-eng-deu-rus-Boot2root_hd_42060_43547.png 36c3-10706-eng-deu-rus-Boot2root_hd_43548_44255.png 36c3-10706-eng-deu-rus-Boot2root_hd_44256_44855.png 36c3-10706-eng-deu-rus-Boot2root_hd_44856_47531.png 36c3-10706-eng-deu-rus-Boot2root_hd_47532_50615.png 36c3-10706-eng-deu-rus-Boot2root_hd_50616_52607.png 36c3-10706-eng-deu-rus-Boot2root_hd_52608_53207.png 36c3-10706-eng-deu-rus-Boot2root_hd_53208_53723.png 36c3-10706-eng-deu-rus-Boot2root_hd_53724_53771.png 36c3-10706-eng-deu-rus-Boot2root_hd_53772_53819.png 36c3-10706-eng-deu-rus-Boot2root_hd_53820_56183.png 36c3-10706-eng-deu-rus-Boot2root_hd_56184_56759.png 36c3-10706-eng-deu-rus-Boot2root_hd_56760_58199.png 36c3-10706-eng-deu-rus-Boot2root_hd_58200_59243.png 36c3-10706-eng-deu-rus-Boot2root_hd_59244_60971.png 36c3-10706-eng-deu-rus-Boot2root_hd_60972_62723.png 36c3-10706-eng-deu-rus-Boot2root_hd_62724_62831.png 36c3-10706-eng-deu-rus-Boot2root_hd_62832_64379.png 36c3-10706-eng-deu-rus-Boot2root_hd_64380_64535.png 36c3-10706-eng-deu-rus-Boot2root_hd_64536_64787.png 36c3-10706-eng-deu-rus-Boot2root_hd_64788_66431.png 36c3-10706-eng-deu-rus-Boot2root_hd_66432_67691.png 36c3-10706-eng-deu-rus-Boot2root_hd_67692_68315.png 36c3-10706-eng-deu-rus-Boot2root_hd_68316_70043.png 36c3-10706-eng-deu-rus-Boot2root_hd_70044_71963.png 36c3-10706-eng-deu-rus-Boot2root_hd_71964_73799.png 36c3-10706-eng-deu-rus-Boot2root_hd_73800_77459.png 36c3-10706-eng-deu-rus-Boot2root_hd_77460_78467.png 36c3-10706-eng-deu-rus-Boot2root_hd_78468_79703.png 36c3-10706-eng-deu-rus-Boot2root_hd_79704_82607.png 36c3-10706-eng-deu-rus-Boot2root_hd_82608_82931.png 36c3-10706-eng-deu-rus-Boot2root_hd_82932_84047.png 36c3-10706-eng-deu-rus-Boot2root_hd_84048_84863.png 36c3-10706-eng-deu-rus-Boot2root_hd_84864_86927.png 36c3-10706-eng-deu-rus-Boot2root_hd_86928_88667.png 36c3-10706-eng-deu-rus-Boot2root_hd_88668_90071.png 36c3-10706-eng-deu-rus-Boot2root_hd_90072_92543.png 36c3-10706-eng-deu-rus-Boot2root_hd_92544_92747.png 36c3-10706-eng-deu-rus-Boot2root_hd_92748_92795.png 36c3-10706-eng-deu-rus-Boot2root_hd_92796_93324.png
Okay, please welcome our next speakers, Joseph and Ilja, who will be talking about how bootloaders are broken and how to look into them. Please give them a warm round of applause. Hello, does this sound okay? Cool. Yeah, so welcome to Boot to Root, auditing bootloaders by example. I'm Joseph Tartaro. I hack things for IO Active and this is my second time at Congress, so I'm really excited to be back here. Hi, I'm Ilja. This is my 18 or 19 time at Congress. Happy to be back here too. I've spoken here, I think, seven or eight times before and I'm very excited to speak here together with Joe. We've been working together on bootloaders last year in change and this is minus the NDA coverage stuff. This is some of the things we've observed and seen, so I'm very excited to do this. Yeah, so the expected audience for this talk would be embedded systems engineers, security people who are interested in embedded systems and just curious security people. Just a caveat. We're going to be quickly going through about like 70 slides or so and a lot of it's just like examples of C source code, so if you did not realize you were signing up for an hour of that, feel free to walk out. We're not going to be offended. And then another caveat would be this isn't really trying to flex and show look at all the bugs we found. The purpose of this was to kind of show people, hey, if you have not looked at bootloaders before, this is our recommended areas of attack surface that are interesting. This is probably where you should get started. And in some examples of nobody's really looking at them and they should start, so that's pretty much what's going to go on right now. So quickly, here's the agenda. We'll discuss why they're important. Some of the common ones we looked at, attack surface and our conclusions. So there's going to be a wide interpretation of bootloader. So basically what we mean by that is anything that's in your secure boot chain. And if you don't have experience with these or you haven't looked at them much, you can kind of think of it like from an operating standpoint of user land calling into kernel space, you'll have kind of normal world calling into secure world and stuff. And that's kind of what you're looking for is those pivots and when they're processing, you know, attacker user control data. So why? Because they're, you know, critical for security. It's a key component of your chain of trust and it's very obvious that a lot of device designers are poor at hardening and limiting attack surface. And what we mean by that is a lot of the devices we've looked at over the last year or so, you'll find devices that have like full network stacks even though they don't need a network stack. You'll have a bunch of code loaded up to handle file systems that are never expected. So it just, it doesn't really make sense why they're not limiting all that attack surface. There's also a huge under estimate of reverse engineering. People just kind of assuming that there's no bad actors and nobody's really going to look at this thing and it's this hidden black box that we should ignore. And a little story behind the presentation is we're actually on a train going to a baseball game. I was trying to introduce Ilya to the lovely game of baseball. And we were talking about U-Boot and I pulled out my phone and we went to the U-Boot GitHub and in about, I don't know, 10 minutes, 15 minutes, we ran into like 10 bugs and we went, yeah, we should probably audit some of this stuff. And kind of inspiration from a previous talk that Ilya has given at Congress where he audited a bunch of different BSDs. I said, why don't we look at a bunch of different boot loaders. And so just to give credit where credit's due, we are not the first to look at any of this stuff. So this is a list of people that kind of inspired us, have done really interesting work. And we recommend if you're interested in any of this and you enjoyed it, you should go check these people out and see things that they have released in papers and stuff like that. So where are they? Boot loaders are pretty much in everything. You have your workstations, game consoles, your TV, you know, everything. And generally the security basically depends on this. So it obviously really, really, really matters. And so with that said, we basically started looking at these common open source boot loaders. So U-Boot, Core Boot, Grub, TBIOS, CAFE, which is Broadcom, Ipixie and Tionocore. And we're just looking at what's on GitHub, what we downloaded. Obviously in your real world scenarios, the devices that you have at home or go buy and start looking at, they're going to be heavily modified. They're going to have weird custom drivers that aren't available, things like that. So, you know, we're not here to argue the likelihood of some of the bugs we found. We're not going to argue exploitability. Half of them, we don't know if they're exploitable. We don't know. We will for one. Yeah, we will for one. We don't really like, that's not really the point of it. The point is to kind of show people, show designers what they should be concerned with and show interesting, or researchers that might be interested what they should look at. So U-Boot is extremely common. It's in a ton of devices. There's a huge, very customizable config for all different sorts of boards and stuff. There's concerns for environment variable stuff. There's a super powerful shell. So you'll sometimes see even shell injection concerns based on environment variables. It's pretty funky. And there's lots of drivers for tons of devices. So it's kind of a great first step of looking at something that kind of covers a huge breadth of things. And so features of U-Boot that are interesting would be, you know, network stack for different protocol parsing, file systems. And they also will load their next stage images from like all sorts of weird, like, archaic things that nobody uses anymore. And it's just used by tons of devices. And then Core Boot. And I apologize. This is a little dry right now. We'll eventually get to this stuff. But Core Boot, you know, it's more targeted towards modern operating systems. There aren't like legacy bio support. It actually, they took a methodology that other projects don't, which is they're not going to implement features that they don't want to. So if you're trying to do network booting or something, you use Core Boot to boot into like Ipixie or something. They're not going to implement that feature. These are used in Chromebooks. And obviously some of the interesting parts come from Google. And one main interesting area is SMM. And then Grub. Obviously you guys are all familiar with this. The primary concern here is a multi-boot spec. And they support just a ton of file systems. So that's obviously the attack surface you'd be concerned with. But the interesting part here is that there are U-Fee signed versions of Grub. So that's kind of like your secure boot break right there. If you find a vulnerability that's an assigned version, you can now load that into your U-Fee and exploit that vulnerability and you're good to go. And then CBIOS is the default BIOS for KEMU KVM. This supports legacy BIOS stuff. So you'll see that this gets booted into from things like Core Boot. This supports TPM communication. So that's kind of interesting. And it's the compatibility support module for U-Fee and OVMF. And then Broadcom Cafe. So this is used in a ton of different network devices and TVs and stuff like that. And the obvious attack surface there would be network protocols, the network stack. That's what you'd want to look at. Ipixie. This would be more network-based stuff. Various parsing and similar to Grub. There's U-Fee signed versions. So it's a great potential pivot for secure boot stuff. And then finally, Tionakor. There's really no introduction needed here. There's been a ton of great presentations over the last 15 years. People just doing everything to this thing. And due to that, since it's pretty much the most scrutinized one out there, it's really mature compared to everything else. So when you bash Tionakor, realize that it's way better than everything else. So there's a lot of implementations built on top of it, like platform-specific stuff, Qualcomm, ABL and XBL, things like that. So you'll have all these. You have the base Tionakor EDK2 and then you have all the custom stuff built on top. And then related to bootloaders, you have things like TrustZone. And that's kind of where I mentioned. You have like normal world and secure world. You'll have these interesting pieces of code that are running into those secure areas that you're going to want to look for. You know, pivots into there so you can gain access to secrets. And then obviously from the host operating system, the attack surface there would be you can modify things like NVRAM. So you can set variables that when the next time you reboot, the boot loader is going to process as variables. And this slide's more for reference. Later you can get the slides or take a picture or something. These are just links to some instructions for building and whatnot. So if you wanted to start looking at these, you can quickly build a little environment and poke around. So just really quickly to go through the concept of secure boot, you kind of have your chain of trust. You'll have the boot ROM that will then verify and load various other loaders that then verify and load the next thing. And you'll sometimes have a TPM involvement. You'll have some TrustZone involvement and then OS interaction stuff like the OS basically setting things like NVRAM which will set boot configuration stuff and whatnot. So the boot ROM itself is something you've probably seen the talk by Cordy Oryoop, I think earlier. It's really important because it can't be patched. It's a hardware revision would be required if vulnerability is found. And it's so early in the stage and you would basically compromise everything after it that is where you'd want to go. It's extremely bare minimum. It does some initialization of hardware and memory stuff. And then you'll find things like maybe implementations of fast boots. You have a USB stack. So that's an obvious attack surface you'd be interested in. And then it will verify the signature of the next stage and then boot that. And then you move on to the next stages. And this is where they start initializing the rest of what's necessary, network stacks, SMM handlers and whatnot. And they'll basically just keep handing off. And then you'll run into things like trusted boot and measure boot which is, you know, verification and then measuring which is kind of more for logging and whatnot doesn't actually mitigate anything. It just kind of alerts you of stuff. So some hardware environments are a little different. Like the secure world stuff, you'll have ARM or trust zone. Windows has VTL 0, VTL 1, hypervisor stuff. And then, yeah, I'm basically repeating myself. And then eventually the operating system, that's going to get the kernels going to be loaded, it's going to be verified. And then eventually start running and then you can have fun. So early observations is everything we pretty much looked at that's open source, there's no privilege separation. So if you were to compromise a piece of component, you pretty much rule everything. And what's interesting is there are some proprietary boot loaders that you're starting to see, like Apple, for example, they're doing some aspect of privilege separation. So if you were to exploit a portion, you didn't necessarily control the world. And so right now, at least all the stuff we looked at did not have anything like that. But maybe in the future, we'll see that. So this is the list of the attack surface that we think people should be interested in and focusing on. You have NVRAM, file systems and files, all network stack protocol stuff, all various buses, you know, SMM, DMA and hardware stuff. The interesting thing about buses that we've noticed is that embedded designers seem to inherently trust anything that end users should never interact with. So they go, okay, an end user uses USB, so we should verify some of that, but they do a bad job. But an end user doesn't play with the spy flash, so just inherently trust it. Or an end user isn't to the TPM. So just if the TPM says something, run with it and they mess it up a lot. So NVRAM, these are the various environment variables that can be configured, you know, for the next boot cycle. And like I said, it's basically processing of user controlled data. So if you start looking at some of these boot loaders, here's the interesting functions you'd want to look at. For example, in Uboot, you just kind of call for environment get and grab through and you see them grabbing the environment variable and see what they do with it. If they're not doing any sort of validation, you're going to hit a book. And so an example of that would be right here, you see there's an environment get for boot P VCI. It checks if it existed. It will then do a stir length and then just mem copy it directly into a buffer without validating that it can fit the buffer. And this is actually kind of funny earlier today. We were like, ah, we should try to exploit one of these just to show it. So we toyed with this one and, you know, just do a bunch of bytes and it starts just kind of sending these weird packets over the wire and a bunch of boot P stuff. You'll see later on you just have full raw packets of whatever payload we send. But it wasn't very realistic. It kind of went, started getting into like the key move like network implementation stuff. So we kind of avoided and moved on to a different bug. But as you can see, it's very easy for you to start looking at the stuff and being interested in it and quickly set up an environment and mess with exploitation and we'll get into it but there's no mitigations. So as you see, there's a bit of a pattern here. Environment get host name, mem copy with stir length. No checks. 128 byte buffer, environment get boot dev, stir copy. It just keeps happening. This is kind of what we were talking about. Just the quality code is not very great. This is, what's funny is when we were messing with that boot P VCI stuff earlier this morning, we went, oh, this is going to be more involved. So it was like, well, let me just go find a different bug. You know, 10 minutes later, it's like, oh, I found a different stack smash. Okay, let's work on that one. It's just like, this is a perfect example. The environment get the variable and then they'll grab the very first element of that variable as a length and then use that as a length. And it keeps happening. So just a quick example. See this. So the attack scenario of this would be, you have a device, you have NV RAM that you can physically modify as you have physical access. And this is kind of an example of the default NV RAM. So we just threw an environment variable with 600 bytes and you'll see towards the bottom there's four bytes where we threw a function in there and that's the address. So just this had to do with the GFFS to file system loading. So you just do FS load. And that's it. That's shellcode being executed. So this is... Sorry, I can't see. So obviously, if you've never looked at this stuff, it's kind of fun to play around with and you should start poking at it because why not? And screenshot. Cool. So that was the NV RAM attack surface which is usually the most fun to play with. Programming to spy flash sometimes may take a little bit of fiddling but in terms of attack surface and fun things to play with, it's, you know, as Joe said, often overlooked and so it's easy to toy with. And so you saw all this Esperant Devs and MIM copies and string copies. So there's a lot of fun there. But obviously there's not just NV RAM. There's more attack surface to sort of a trusted boot environment. And obviously one of them is the file system right because this thing needs to boot and it needs to find images and they're stored somewhere and your file system sort of brings order to that chaos. So basically you need to mount your file system and often file systems are not signed or are technically checked or not all of it is because before you can do that, you need to be able to read something, and so obviously an example of a common file system would be the file system. If your boot environment supports loading your USB drive and for storage, it's probably going to be fat. Depending on, and the flash itself may have its own proprietary format or it may use X2 or something else. But clearly the file system parsers, I mean that's prime attack surface. A closely related is obviously the files inside of your file system, right? Now depending on what your boot environment looks like, some of these files are going to be integrity checked but some of them might not be, right? And so those file parsers are interesting attack surface. And if you're either looking for bugs or you're building a product, we would highly recommend fuzzing these. And it's like starting with AFL is probably a good starting point. But we'll show some examples of some bugs we saw in certain, in a number of boot loaders. So we'll cover X2, we'll cover a bitmap splash parsing one. And then the other ones are sort of examples of where there could be bugs but those two we'll cover. So this is grub, and this is grub X2, and grub X2, you know, this is the sim link code so it looks to file system and it goes, oh, okay, this is the sim link, how do I parse the sim link? And so the sim link says, hi, I'm a sim link, I'm this big. And what grub does is, oh, great, I'll allocate that much size but I'll do one more for an old byte. And of course that is a classic in Azure overflow. And the grub memory allocator actually returns a valid pointer for a zero size. So this is a perfect primitive so you get a pointer to something that is zero size and then it actually reads the sim link content from the file system into a zero size buffer and obviously that's going to cause memory corruption. And a primitive, you can't see it here but a primitive is really nice because that particular read function actually, if there's no much more on disk, it stops reading. So even though you can save, read four gigs, you can make the layout so it only reads, let's say, a thousand bytes or a hundred bytes. And so you have this near perfect primitive to cause memory corruption. This was in Tiana Core, for example, this was the bitmap splash screen parser and I don't know anything about bitmap internals. It's a very simple format but basically you can have a four-bit bitmap and that gives you a pallet of four by four which is 16 bytes. And so the idea is if you have a four-bit bitmap, then it has a 16 byte pallet and so it goes and reads that 16 byte pallet except you tell it how big the pallet is and you can say, okay, I know you're expecting a 16 byte pallet but I'm giving you a 256 byte pallet and it will read it into a 16 byte buffer. So that was broken and then for the 8-bit bitmaps, similarly it was broken the same way. And these are just a tip of the iceberg. There are many, many, many more. This did not take long to find. But let's move on. Obviously now that we've looked at some local stuff and some physical stuff, what about remote? What is there? Obviously if you're talking remote in the modern world, you're talking TCP IP. So you need a TCP IP stack and you need to have some services that you either expose or that you have client code for that you go talk to. And that's bootp and DHCP and DNS and iSCUSY and NFS. And if you're in a corporate, if you're a corporate net, you probably want to have IPsec and then HTP and HTTPS and TFTP. And sure enough, most bootloaders have code for this and then you start asking, okay, what's the attack surface? For TCP IP, if you implement your own stack, well, good luck because you're going to screw it up. But secondly, it's like, okay, well, if you look at these things, you take a step back and say, okay, well, really this is all mostly TLV parsing. And so you go and look into what are the things that can go wrong if you do TLV parsing and they'll be out of bound reads pretty much everywhere and you'll see in those loops and lots of places and things like that. If you look at the protocol at the top of that, like DHCP and DNS, you have your standard network attacks where you'll see lease stealing or cash poisoning or things like that if you don't protect your ID. So if you have a static ID or you don't validate your IDs or you generate predictable IDs, you can have these kind of poisoning, stealing, man-to-middle attacks. And then thirdly, obviously, the thing we really like to see is memory corruption bugs. At the end of the day, you take network data and you parse it and if you do it wrong, you may cause memory corruption bugs. Another sometimes overlooked interesting bug I think when you're doing network parsing is when you have information leaks. So this often manifests itself, I mean, hard bleed, of course, was one example. It was a perfect primitive. But generally, it will be this thing where you end up generating some kind of pack as a response to something and you'll have done the memory allocation but for some reason not initialize something and so you end up sending initialized data over the network. So this is sort of the common things you see network stacks in general. So if you are looking for these kind of bugs in a boot environment or if you are building a product that does this, I would highly recommend fuzzing them. There are numerous interesting network fuzzers. If you're looking for network stack fuzzing, I would recommend ISIC. It's pretty old but it's still incredibly, incredibly effective. It tends to break most network stacks. So with that said, let's show some examples. I was, so UBoot, for example, this is the UBoot DNS code and if you see that, the TID, that's the DNS ID and it's basically, they give it a, they use the static DNS ID of one for all DNS packets that they send out. So doing DNS man in the middle on a UBoot environment is extremely trivial. You guess the DNS ID by saying that it's one and you are correct 100% of the time. So this is Broadcom's coffee and this is the DHP parser and it basically has this sort of junk stack buffer where it just needs to read something out of a buffer and it goes and says, okay, well, get me the length of that thing and it's a UIN date. So that means it can represent 0 up to 255 and then it reads 0 up to 255 into that junk buffer. So that's a stack corruption right there. If you then look at the coffee at the DHP parser, it's very similar where in this case it has a 512 byte buffer and then it basically copies the entire RX buffer into it and this is Ethernet so up to 1500 bytes gets copied into this 512 byte buffer again causing memory corruption. Obviously we're not done with coffee yet because it has such beautiful code. So this is the coffee ICFP ping handler and this has this really cute sort of use after free bug or double free where it basically sends out a ping and then it sits there receiving the, you see the while loop there and it basically sits there receiving packets until it finds the right one but it also, because it doesn't want to have it on its loop, it has a timeout and there's this interesting condition where if the last thing it looked was the packet you were looking for but it also timed out at the exact same time it freeze that packet twice which obviously can lead to memory corruption. Again we're not done with coffee yet. Oh right there we go. Not done with coffee yet so this is the IP handling coffee and if anybody has ever looked at an IP header which I would assume most of you have, you'll know it has an IP header length and a total length and of course coffee needs to know this because it needs to know where stuff is but coffee validates neither the IP header length or the total length so once you start messing with those coffee blows up really fast. So that was sort of a quick overview of all the trivial TCP and TCP related bugs that show up in your after boot loader. So but let's say you got that covered and let's say, you know, okay what's the next thing? What more sort of network stuff can we do? And then of course what comes to mind is Wi-Fi, you know, 8 or 2.11. And a surprising number of boot loaders don't have 8 or 2.11 so I don't know if that's sort of a sort of on purpose or just sort of we didn't get to having this feature yet but we will at some point and obviously it'll have bugs when we implement it. But we did find one that has it and I'll get to that in a second. One thing I did want to mention is that if you look at 8 or 2.11 like frame parsing, depending on which device you have and particularly which radio your device is using, you'll have radios that do a lot of parsing on the radio in which case the stack is kind of covered because it's, at least you hope it is where the radio does a bunch of validation. But then there's a whole bunch of radios that sort of, you know, they take package from the wire and they just don't do anything and just pass it on to the OS. That's the stuff that's interesting from a, from a tax service point of view if you look into attack the boot loader and not the firmware. So yeah, we looked at Pixi and of course, you know, anytime you do any kind of Wi-Fi stuff the first thing you do is you're looking for an SSID, right? This is what this thing does and, you know, it sort of has this SSID buffer which an SSID can be up to 32 bytes so that is 32, well, it's 33 bytes because it's 32 plus 1 and it has this loop where it sort of goes over IE's that it gets and then when it finds the right, the IE for an SSID it says okay, we'll take this IE and we'll do IE length and IE length is a U and 8 so it can be up to 255 and it copies the SSID IE into the SSID buffer which is only 32 bytes causing memory corruption. So that's iPixie for you. Okay, so the next one if you're thinking networking would be Bluetooth and Joe and I have actually we've looked at proprietary bootloaders that have Bluetooth support. Unfortunately, we can't talk about those bugs because they're covered by non-scope agreements and we tried really, really hard to find a similar equivalent in any kind of open source bootloader and we couldn't find one. So unfortunately, we can't give examples of sort of Bluetooth bugs in open source bootloaders but I do kind of want to in general terms talk about what we have seen and where we suspect the bugs are going to be if somebody does do this in an open source bootloader or something that's a new bootloader. So and also like if you're going to do Bluetooth in a bootloader it's usually for you know HID device right this is for keyboard mouse this usually ends up being for consumer devices. But in general if you look at Bluetooth stack and you're looking for any kind of you know parsing bugs there's three sort of recurring teams. There's three sort of recurring teams that we saw when we looked at the Bluetooth stacks that we have and this is if you look at the lower layers like L2P cap and things like that and this is usually related to sort of frames and frame lengths so very, very large frames. So a frame can be up to about 65,000 bytes because the length is a UN16 and so if you create really large frames like right up to the edge that tends to blow up Bluetooth stacks. The other one is if you create very, very, very short frames you know less than what something is expecting that tends to blow up your Bluetooth stack. And then lastly because L2CAP can have fragmentation so you can have individual fragments that you will add together and every fragment can be X amount of bytes but the whole thing can be up to 65,000 bytes a byte, 65,000 number of bytes. So if you start playing around with the fragmentation we've numerous Bluetooth stacks have blown up. Again, I wish I could have shown an actual bug here but I wasn't able to find any in the open source boot loaders. So moving on to USB, this is a primate attack surface in boot loaders obviously. If you haven't followed the news in the last couple of weeks and months this has shown up in a number of devices. This is at least up till recently I think was sort of under reported or sort of people didn't quite care about it. But to me the USB stack is like that's the if I, any time I look at a USB loader at a boot loader my first thought is you know NV RAM and number two is USB. And USB is interesting because obviously a lot of boot loaders support USB because they'll use it either for storage or you know things like Internet dongles but often for storage where you know either you expose certain files or you try to do some kind of recovery boot from USB or something like that. And so basically if you start looking at how USB works at a slightly lower level it's not quite like it's not like PCI it's more packet based and so what happens when a device talks to a host the device is asked for quote unquote descriptors. And these descriptors say certain things about your device and based upon the number of descriptors that the host asks from you and all the answers you give them in the script responses the host can then figure out what kind of device you are and what class you are and what functionality you expose and all these kind of things. And so a lot of these descriptors end up you know being parsed and being parsed wrong. And so generally we often see either straight up overflows or double fetches because the way descriptors work is they're variable length content but the headers are predefined and the way it works is you first ask for the header and then based on the length of the header you ask for the thing again except the USB protocol doesn't allow you to just get the payload you have to reread the whole thing so you have to reread the header that you already had. And so in most implementation what happens is you go get the header you allocate a buffer and then you go get the header and payload again and you override the original header. Which means is you get to override the original header length and so you can have a talktow where your device gives you a header with a good length and then the second time it gives you a descriptor with a bad length and if your host doesn't validate that both lengths are the same bad things happen. And yeah, straight up overflows happen too because nobody ever expects the USB device. There's an example in Grubb for example where it goes and gets a descriptor and the descriptor says oh here's my config account I have this number of configurations go and fetch those in descriptors as well. And there is a predefined array of number of configurations that Grubb has and it doesn't correlate that with the config count. It just always assumes the config count is less or equal to the array. And so if you have a malicious device and you say hey I know your array is 32 bytes, 32 elements but I'm going to give you 64 configurations. It'll happily write 64 configurations in a place that can only hold 32 of them. And exactly the same thing for number of interfaces. Tiana core had similar bugs where this was Tiana core where they go and get a descriptor and the descriptor length says okay now go fetch me the whole thing and use that descriptor length except the original hub descriptor was a very small struct and the descriptor length is a U and 8 so you can set up to 255 bytes and so that would have smashed memory and caused a stack corruption. And so as you can see here the fix here wasn't actually at a bound check but just to make the buffer bigger because you know the length is U and 8 so if you just make the buffer 256 then any length you give it will fit within the buffer. Yeah this is an example in C BIOS where this is the classic double fetch where it goes and gets the header, does an alloc based on the header and then gets the header again with the content and it doesn't verify that config W total length is the same thing as CFG to W total length and because that verification isn't there whoever calls this thing can no longer trust W total length because it could be invalid. And so as I said USB to me is one of the prime attack services to secure boot and so I want to sort of very very briefly mention two recent real world cases where devices got broken into because of USB parsing in the boot loader. So this was this is a case of the Nintendo switch the Tegra this was done by the failover flow people about a year or so ago that basically you know you give it a length that's not validated and then a mem copy and that causes memory corruption and then the recent iPhone checkmate this is slightly more complicated because it wasn't a straight memory corruption but it was you know if you fiddle around enough with the state it sort of gets out of sync and it has all these pointers that it's still considered to be alive but the memory has been freed and so you end up this ends up what you use after free but it is because of a sequence of USB packets that are being sent. Right so that's it for USB obviously bunch of the buses or almost any bus on your device if your boot chain uses it is interesting attack surface and this is spy I mean spy flash and be trusted, SDIO, I2C, LPC even your TPM right even your TPM response you get back from TPM can't be trusted because somebody could desolder your TPM and pretend to be your TPM and if you don't now validate the data you get from TPM you end up with memory corruption. So this is for example what happened in CBIOS. CBIOS has this talk show TPM and it goes and gets this structure and you can send it less than what it expects and then basically they subtract some size of a struct minus less what they expect and so that causes integer underflow which ends up with a really big size and then that size is given to malloc and malloc internally has an end overflow so that really big size then becomes a very small size and then they copy into it and that causes memory corruption and so this is a combination of two bugs right one is where the sizes are wrong and then secondly is where the malloc has an internal integer overflow and this is the malloc internals of CBIOS which I don't want to dive into now because it's pretty convoluted and complex I'll leave this as an exercise to the audience to figure out where the int overflow is and technically it's not an overflow because it's a bunch of shifting being done but it essentially comes down to an int overflow. Yeah, there we go. Yep, there we go. Okay. So another service attack service that is interesting but often overlooked on devices except for Ufie is system management mode and I mean there have been over the last decade and a half numerous presentations about SMM attack service and break SMM handlers for Ufie because it's an x86 thing and you see this in Ufie stacks and it was a cat and mouse game where for years somebody breaks something and then Ufie fixes it and then somebody breaks it again and Ufie fixes it again and somebody makes it again and Ufie goes okay let's do mitigation for this and this has gone on for like 15, 16 years and occasionally people still find bugs but by and large Ufie does fairly well now with regards to SMM handling. There's some third party stuff that still breaks occasionally but in general they got a handle on this. Now what if you're using x86 but you re-implement your own boot loader and you don't use Ufie, right? Well that means you're going to run into all the same problems Ufie had and you're going to screw it up in all the same ways and it'll take you another 15 years to get it right. But I guess if you were to try it the first time this is what Corboot does and to their credit they say oh we get input we should range check it and their range check says to do. Okay so now I talked about a bunch of buses. The thing to me that sort of separates that from other things is when you do DMA. Generally for as long as DMA has been around DMA is game over. If you get DMA then that's that there's no trust boundary. Obviously that's no longer true. We have IOMM use and if you use them and if you have a device that has this available then old-sodd DMA can be stopped, it can be contained, it can be regulated and so it's no longer a sort of game over and you can implement a trust boundary. A few things there. A if you are an embedded device and you're using IOMM use you are way ahead of the curve because not that many people are doing this right. You should but it takes some effort. There's obviously many different IOMM use it depends on your architecture and sort of the board you have and all sorts of things. So Intel's VDD, ARM is SMMU, AMD has like the device exclusion and it's got a few other ones as well. But basically if you use one of these you can sort of DMA is no longer the game over. Now that doesn't mean that you're in the clear. Once you define DMA as an attack surface you have to defend it and that's where you get some difficulty because you'll end up using drivers that have been written before it was a trust boundary and I mean no one has ever written a DMA handler with a trust boundary in mind because you assume there's no trust boundary. So now if you start using the IOMM you have to go back and look at where am I doing DMA and now I can no longer trust what's in when I get back from DMA and you have to go validate all this stuff. But even if you do all of that right which by the way is very hard and you probably won't do it right but let's say you do. Secondly because DMA is now a trust boundary any time you open up a memory window for a device you can't just open it up you have to clear the memory first because otherwise now you're leaking memory to a device right. So all these sort of new things sort of show up if you take DMA as a trust boundary. And let's say you do that right well now you still have a dependency on the IOMM you because you are assuming the IOMM you's perfect when it probably isn't right. I haven't really gotten to this part yet but one of my plans for the future is to go look at IOMM you and see if I can attack IOMM you and then find bugs there. I strongly suspect there will be side channels and logic bugs and maybe maybe even some heart room implementation bugs. So bug-wise this is where it sort of gets design-y right. So this is what this is Ufie today, it's EDK2 platform code where it has support for IOMM you and they're ahead of the curve. But if you look at the spec there's no good handover protocol from Ufie to the next stage. And so Ufie basically boots up and very early configures the IOMM you and make sure that devices can't peek or poke arbitrary physical memory and then it does all of its stages and then it's about to hand off and it goes well I don't know if the next guy supports IOMM you so it undoes all the IOMM program it does, turns the thing off, opens up everything and then hands it over to the next guy. So you did all this work for nothing. And this is a spec bug and it's being worked on, people are very much aware of this. People at Apple have fixed this for their devices. This is going to get fixed in the future but given that this has to be done by spec it takes a while because you have to get people to agree to it and then have numerous different implementations implement this. And this is where I hand it back over to Joe. Yeah, so hardware it's pretty much out of scope for the presentation. We did not look at any of this but we thought it would be naive to not at least mention it to people. And what we mean by that are like glitching, side channel, silicon stuff. And so with glitching you have like fault injections and a lot of times people go after things like the signature verification stuff so they'll basically glitch that part and then they'll start running on sign code. And a recent example of some glitching was done by fell overflow for the PS4 SISCON. And I forget the specifics, it's been a while. Really, really good blog post you should check out. But I think it went to like an infinite loop like go to debug mode or something and would say that's not enabled, infinite loop and then there's glitch out of it and initializes debug mode. And so stuff like that obviously should be concerned with then clearly side channel with timing discrepancies, power discrepancies, things like spec or muck down, speculative execution in general. These are where people are leaking secrets for going after keys so they can start signing their own code, stuff like that. And then chip suck. And this is somewhat interesting because it's obviously only relevant for a very sophisticated attacker. It's going to be somebody who has very expensive equipment. They do things like decapping, they use fibs and Sims. They can do things like optical ROM extraction and get the boot ROM and then start auditing that and then, you know, find a bug and exploit it. And obviously totally out of scope for the presentation. But one thing that's interesting about this is kind of presently it's still, you know, not a lot of people have this expensive equipment. But I think very soon you have people like John McMaster and stuff who have like a SEM in their garage, right? And so you're going to eventually start getting these regular hackers in their garage that will eventually get this equipment as the older equipment becomes more affordable and maybe that opens us up to more realistic instead of people just kind of ignoring it and they go, eh, I'm not worried about somebody with, you know, a quarter of a million dollars worth of equipment. Now it's turning into somebody who dropped 10K or 15K. And then, you know, a quick note on code integrity. It's something that people mess up a lot. It's kind of hard to do, right? You have people that do weak or crypto, you have blacklist problems and an example that is, you know, there's finite space for their blacklist. It will eventually get exhausted. So when you have stuff like where I mentioned that you have a signed grub, there's a known bug in a signed grub binary that was really Speckers-Bursky. And if that's not on the blacklist of your Ufi platform at home, you can just load that up and then exploit it and you just broke Secure Boot. And it's not going to get fixed until that platform has an up-to-date blacklist. And eventually, if all this crap gets blacklisted, eventually that list will be full and then they can't blacklist anymore. So it's a concern there. And then you'll have issues where they'll only sign certain portions, not the full blob, so you can, you know, still modify certain parts or sometimes you'll see they'll just check for signature existing, but they don't validate it. You know, really, really dumb stuff. So conclusions. Obviously this is the tip of the iceberg. There's a lot of stuff we didn't look at. And if it wasn't clear, we did not really audit these things. We literally would like chat with each other every day and be like, hey, we need a C by us bug. Okay, give me an hour. Okay, I got one. Okay, check the box and then let's move on to the next one. Our goal was to have an example of a bug for each list of the attack surface, an example of a bug for each list of the thing we looked at. And that was it. So, you know, once we found one, we stopped. So you guys should, you know, go hunting and have fun. But if it wasn't obvious, there's a surprising amount of low quality code. It's kind of crazy. And it's pretty clear that not a lot of people are looking at this stuff. And one thing that kind of sucks is you get to NDA hell really, really, really quick if you want to look at any of this proprietary stuff. So if you're interested in Qualcomm stuff, for example, and you want to get some documentation or look at it, you pretty much have to sacrifice a first born to get access to that stuff. Like it's just not going to happen. And it's kind of silly. So, you know, kind of like our advice and call to action is, you know, people should be minimizing their image, their boot environments, their host environments. You know, turn off features you don't need. If you don't need a network stack, why have it? If you don't need USB, why have it? All you're doing is enabling a attack surface for somebody to leverage. And something that we see a lot, which is insane, is like these little embedded devices that are running Linux and they have literally more drivers than our desktop at home. And it's just like, what is going on here? It doesn't make sense. You should really, really, really work on limiting the attack surface. And really quick mitigations. There aren't any in most environments. Yeah, they just aren't any. As you can see from the example from before, that was, you know, just from this morning, just really quick, you know, smash and, you know, over at the stored PC. And that's it. Like, there's no ASLR. There's no anything like that, code flow integrity, whatnot. But there's a link to a GitHub and that is an Intel employee that has gone and implemented a lot of these mitigations that are moving into Tiana core. So they are way, way, way ahead of the game of everyone else because they're actually getting a lot of these mitigations, which is quite impressive. And you should check it out because it's interesting code. So kind of a call to action. We really hope that this was inspirational to a few of you. If you've never looked at this stuff and it was always this black box that you weren't sure about, you should just start poking around. Go find the slide where we showed where the, you know, build instructions, where and go build some of these things and mess around. And you're going to have fun. And like we said, with no mitigations, you can work on some easier exploit dev stuff and it's cool. But it's clear that a lot of people need to be reviewing this because it's clearly not happening. People should start fuzzing interfaces. Everything we kind of showed should have been found with basic fuzzing. We're kind of at a point where I just said I'm just going to take like a teensy or something and have it just, you know, do that classic descriptor double fetch because I think we've seen that in like every USB stack. Like it just make a device and just start plugging it into stuff and just watch it break. And then obviously periodic reviews and whatnot. But yeah, that's pretty much it. So yeah. Well, thank you. Now we have about 10 minutes for Q and a and we will start immediately with the Internet. Thank you. Has the grab issue been fixed yet? And was the code unique to grab or borrowed from, you know, elsewhere? I don't think it's been fixed yet. And this was the this was from whatever the official group repository was. All right. If you have a question in the room, please line up at the microphone so I can see you. And now microphone number two. So let's say you want to make a more secure laptop. So you came to take poor boot, take a static kernel so that everything is in compiled in no normal no modules. But what about the text text services that such a somebody tries to interrupt the line of why why did this booting for example, that you may be some somehow get into make a maybe DMA access because you you somehow interfere with a let's say Broadcom network device that has some special firmware to optimize the traffic or something and that that this thing gets above over floated above over flow and make some problems on the on the bus or something. Are you talking about attack surface from devices? Yes, it's like that. Yes, I tell you you want to make a good system. So I think the best you can do if you have a laptop that you take a core boot and you take a Linux that you completely compile without module support everything you want to have is in the static kernel and that just boots and the kernel is in the core boot and so it's in the flesh. But you can get a problems by by by let's say some devices that just spit into your memory because they can do a DMA master. Yeah, that's that's that's definitely concern. And that's one of the things we were like, okay, well, if if you do use DMA as it has been forever, then that then it's game over. Luckily, nowadays we have IOMUs. So you depending if which situation you are in and what hardware you have, you can configure your device to use the IOMU. And if you're doing that, then even if a certain hardware device is compromised, you can still try to protect you know your CPU and your host from the device by having the IOMU. That I think I hope it answers your question, but it's about as good an answer as I can come up with. So so that's a bit so this is the maximum you can do against some attacks. I mean from a device, I want to make an extreme hard laptop that you use an extreme hostile environment. So again, you want to make a hard laptop that you use in a hostile environment, right? I mean, I think that's the best you can do right. I mean, you can go and look at your host West and look at how it parses the stuff that comes from the bus because there'll be there'll be bugs there too. But I think that's the best I can come up with. Yeah, I mean, you minimized the attack surface as much as you can, right? And then once once you have it as minimized as possible, then you just kind of hope hope there's nothing there. But you don't then you don't need to code signing because you have everything in your flesh or you still need some stumps. Oh, you mean the stuff that runs on the host? Yeah, I mean, obviously, let's say you have your corporate on the Linux in the flesh. And so everything is that we have that same. And you maybe take this discussion after the talk because we have more questions. Thanks. And signal angel please. What is your favorite disassembly that you use by reverse engineering the bootloaders? We didn't really we just looked at source code. We need to meet a few places. I mean, for this particular particular in this particular case, most of it was white box. So we didn't have much except for the exploit. We didn't have much need for the for this assembler. I guess a little bit of GDP in general when we do do reverse engineering. I mean, I does my go to I've been playing around with Gidra a little bit. It looks promising. Has on do which is nice. But those are usually and then you know for doing Linux have stuff GDP is nice when you're doing debugging. But generally IDA. Microphone number one place. I have two questions. What's your opinion on the arm trusted from architecture? I'm I have to work with this and I'm a little bit shocked. It's a little bit over complicated. And the second question is, should we also question the boot ROMs? Because what I've seen the special project, it leads me to believe that the boot ROM is also very broken. And then is the question if it's really necessary to harden the other stuff. Right. Yep. Those are those are really good questions. By the way, it sounds like you're working on this. So what your first question was what again? What do you think about the arm trust? Right. Yes. I like you. I've touched upon it in a few engagements. Unfortunately, any of the concrete stuff I can't really talk about because it was covered by non. Yeah, I see you where this is this problem. But I just I share your opinion that there are some things in there that are troubling. With regards to the boot ROMs, your spot answer, I mean, we try to bring this up in the one of the slides is if there's a buck there, you can't fix it. Hardware revision is the only way to fix it. So you kind of screwed. There are some designs you can do to try to minimize it. So you could say, okay, well, you can in your boot ROM, you could have a feature that allows for a quote unquote, patching the boot ROM where you can have a piece of something on storage that could overwrite what the boot ROM supposed to do. Obviously, up until that point, whatever's in the boot ROM, still, you can't fix that. But you can you can minimize the amount of stuff in the boot ROM that's not patchable. But you can minimize all of it. I mean, there's going to be some of it that is locked, burned in hardware and can never be fixed for that device. I'd love to hear of a better solution. I don't know of any. No, I was just going to say this kind of touches on when we said people underestimating reverse engineering, they kind of just keep it super, super block box. And it's the secret thing. And then, you know, when somebody finds a way to dump a boot ROM, they start looking at it, then they just see, you know, a bug in a USB USB stack. And then the switch goes down and or the iPhone or whatever else, right? So so yeah, it's from my perspective, that I would say it would make more sense to do more open, open auditing and let more eyes see it instead of hiding it in the corner and in pretending like, well, it's okay because nobody's looking. That's that's at least my perspective on it. I know why why people are super secretive about it. But you need more eyeballs. So maybe if you've got the right context, as my wish would be to get blank chips, so I could flash them with my own boot ROM. So I have a method to prove things and keep the text surface minimum. Yeah. And then there's going to be two other arm dies on there that are circumventing everything that you just did. Do we have more internet questions? Yes. Are you aware of any good and maybe even free bootloader fuzzle? Not in its whole. I mentioned a few places. So if you're doing any kind of file based stuff and you can isolate it, AFL is you know, that's the go to these days for network stuff. There's a couple of interesting ones like is sick and there's some Wi Fi fuzzles and and I think there's you know, some DNS fuzzles or things like that. So that works. I would say the best way in my opinion would be to pull out the interesting components that are doing the parsing and the stuff you're concerned about and write a harness for that. So you don't really need to try to write a fuzzle for that environment. You just pull that feature out and harness it up and then let it you know, run on a bunch of cores. Yes. I think live fuzzle might be very helpful there. All right. Number two, please. Hi. We have producing the occurrence of such errors by using another programming language like that would feature more secure things that compile time or during runtime like maybe Rust. Will it happen? If yes, are there alternative projects that use other languages other than see? I'm not aware. So I think you're right. I think we can reduce the amount of especially the memory corruption stuff. I mean, if you switch to something like Rust, even though I think on occasion there's some Rust corner case that shows up where something doesn't get caught by the verifier, those are weird corner cases. In general, yes. I think you're right. If we switch languages, a lot of memory corruption stuff goes away, but not everything goes away. All the design stuff is still there, right? I'm currently doing that though. Well, so there was actually there was a talk by Andrea Barisani yesterday or day before where he's doing a go runtime for an as a as a base for an ARM device. So this is an avenue that is currently in the beginning of being researched and being worked on. I think it's interesting. I think it's a direction one that we could go into. I think there's something there. At the present time, it still seems a bit too early. And the other thing is that while it does reduce the number of bugs that are going to be there in particular memory corruption stuff, it doesn't like there will still be, you know, your logic bugs and your hardware bugs and things like that. So it's not a silver bullet, but it could definitely help. Okay. And we are out of time. Please thank our speakers again.
and Ilja, who will be talking about how Boot to Root, auditing bootloaders by example. common ones we looked at, attack surface and our lot of device designers are poor at hardening and Boot loaders are pretty much in everything. You that's kind of like your secure boot break right would be network protocols, the network stack. from the host operating system, the attack your device if your boot chain uses it is boundary any time you open up a memory window for conclusions. Obviously this is the tip of the double fetch because I think we've seen that in