We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback
00:00

Formal Metadata

Title
Boot2root
Subtitle
Auditing Boot Loaders by Example
Title of Series
Number of Parts
254
Author
License
CC Attribution 4.0 International:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
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.
Keywords
47
72
Thumbnail
1:02:13
82
Thumbnail
1:02:15
99
144
157
162
175
179
187
246
253
Element (mathematics)Directory serviceRoundness (object)Online helpBootingWater vaporoutputMultiplication sign19 (number)Covering space2 (number)Computer animationJSONLecture/ConferenceMeeting/Interview
Physical systemSystem programmingInformation securityBootingSample (statistics)Information securityPhysical systemBootingSystems engineeringSlide ruleSource codeCodeOperating systemSoftware bugSurfaceArea1 (number)Water vaporInterpreter (computing)Meeting/InterviewComputer animation
Kernel (computing)Game controllerBootingChainCodeSystem callCoroutinePresentation of a groupSimilarity (geometry)Asynchronous Transfer ModePhysical systemData managementTime zoneInformation securityReverse engineeringData integritySurfaceIdeal (ethics)Independence (probability theory)Server (computing)Workstation <Musikinstrument>Embedded systemSoftwareFreewareSource codeContinued fractionDevice driverIntegrated development environmentBefehlsprozessorWhiteboardGastropod shellConfiguration spaceMeta elementAddress spaceDynamic Host Configuration ProtocolComputer networkDirect numerical simulationFile systemLevel (video gaming)Computer-generated imageryStructural loadSerial portNP-hardMiniDiscCompact spaceSCSIFlash memoryProcess capability indexGoogolRevision controlInstallable File SystemDensity of statesUser-defined functionPlastikkarteModule (mathematics)FirmwareEmulationOpen setInterface (computing)Virtual realityComputing platformRouter (computing)File Transfer ProtocolOpen sourceComputer configurationCommunications protocolImplementationLatent heatLengthImplementationPresentation of a groupPivot elementWhiteboardVector potentialSoftwareIntegrated development environmentOperating systemBootingCore dumpInformation securityModule (mathematics)Right angleQuicksortKernel (computing)Different (Kate Ryan album)Configuration spaceNormal (geometry)Computer fileBootingSurfaceStack (abstract data type)Product (business)Connectivity (graph theory)Operator (mathematics)Device driverMereologyAreaCommunications protocolDefault (computer science)Vulnerability (computing)Wave packetReverse engineeringControl flowRevision controlElectronic mailing listGame theoryPoint (geometry)Software bugLikelihood functionComa BerenicesBlack boxVariable (mathematics)ChainTopological vector spaceCodeFile systemGastropod shellOpen sourceInjektivitätBitSign (mathematics)Multiplication signUsabilityMultiplicationEstimatorBuildingGraphical user interfaceMusical ensembleComputing platformMedical imagingWorkstation <Musikinstrument>System callLatent heatParsingLevel (video gaming)Physical systemEndliche ModelltheorieTelecommunicationHeegaard splittingGame controllerComputer animation
Cloud computingInformation securityKernel (computing)Operations researchSystem programmingPresentation of a groupBootingTime zoneImplementationArmContinued fractionBuildingSample (statistics)Source codeIntegrated development environmentBootingInformation securityNormal (geometry)CodeAreaVariable (mathematics)Multiplication signBuildingPivot elementChainSurfacePhysical systemProcess (computing)WebsiteComputer animation
Time zoneBootingShooting methodLevel (video gaming)Read-only memoryRevision controlComputer hardwareFormal verificationElectronic signatureFlash memoryData storage devicePoint (geometry)Computer networkIntegrated development environmentVariable (mathematics)CodeArmStructural loadKernel (computing)Parameter (computer programming)Open sourceFlow separationChainNon-volatile memorySystem programmingComputer fileSurfaceInformation securityBootingStructural loadVotingFormal verificationStack (abstract data type)State observerKernel (computing)SurfaceWindowComputer hardwareSoftwareFile systemNon-volatile memoryLevel (video gaming)Flow separationBootingRevision controlElectronic mailing listVulnerability (computing)Configuration spaceInteractive televisionMeasurementChainOpen setSemiconductor memoryElectronic signatureIntegrated development environmentCommunications protocolOperating systemBus (computing)RoutingOrder (biology)Computer fileModal logicPhysical systemGame controllerOpen sourceMachine visionImplementationRule of inferenceConnectivity (graph theory)Process (computing)Meeting/InterviewComputer animation
Non-volatile memoryComputer hardwareSystem programmingComputer fileSurfaceBootingGame controllerStandard deviationVariable (mathematics)Integrated development environmentParsingIntegrated development environmentVariable (mathematics)Process (computing)Cycle (graph theory)Game controllerBitBootingSystem callFunctional (mathematics)QuicksortValidity (statistics)Computer animationMeeting/Interview
Continued fractionSurfaceNon-volatile memoryBootingFluid staticsComputer configurationData typeMessage passingDynamic Host Configuration ProtocolServer (computing)Address spaceClient (computing)Computer hardwareHTTP cookieFile Transfer ProtocolInformationSource codeFrame problemCommunications protocolBroadcasting (networking)String (computer science)LengthBuffer solutionChainImplementationPattern languageBitIntegrated development environmentExploit (computer security)Software bugSoftwareBootingComputer wormPrinciple of maximum entropyDifferent (Kate Ryan album)Computer animationXML
BuildingBootingDemo (music)BitPattern languageIntegrated development environmentLengthFunctional (mathematics)Variable (mathematics)Default (computer science)Element (mathematics)BootingStructural loadSoftware bugFile systemCodeNon-volatile memorySampling (statistics)Different (Kate Ryan album)Cycle (graph theory)WeightGreatest elementAreaBuffer solutionAddress spaceMeeting/InterviewComputer animation
Demo (music)Data integrityPrime idealSurfaceFile systemIntegrated development environmentSurfaceFile formatRight angleGoodness of fitQuicksortOrder (biology)BootingPhysical systemAddress spaceLetterpress printingFlash memoryFile systemData storage deviceTerm (mathematics)Prime idealArithmetic meanMedical imagingNon-volatile memoryBootingBitComputer fileString (computer science)Meeting/InterviewComputer animation
Computer filePhysical systemData integritySoftwareParsingSurfaceFuzzy logicDevice driverBinary filePartition (number theory)Table (information)Computer-generated imageryFile systemBootingSurfacePrime idealComputer fileQuicksortLevel (video gaming)NumberBitSoftware bugServer (computing)ChainSymbol tableCNNIntegrated development environmentSimulationParsing1 (number)Raster graphicsBootingCovering spaceCodeFile systemINTEGRALLecture/ConferenceMeeting/InterviewComputer animation
Block (periodic table)Asynchronous Transfer ModeGradientImplementationStack (abstract data type)Buffer overflowParsingLogicPointer (computer programming)IntegerMemory managementSemiconductor memoryRaster graphicsSimulationFunctional (mathematics)Buffer overflowCausalityBuffer solutionPrimitive (album)ParsingTouchscreenChainClassical physicsReading (process)Content (media)File systemText editorLevel (video gaming)BitFile formatPerfect groupMappingPoint (geometry)Turtle graphicsWebsiteRoboticsComputer animation
Computer networkService (economics)Dynamic Host Configuration ProtocolDirect numerical simulationFile Transfer ProtocolSurfaceiSCSIRead-only memoryInformationBuffer solutionClient (computing)iSCSICodeDirect numerical simulationStack (abstract data type)Service (economics)BlogWeightRight angleBootingGoodness of fitQuicksortSurfaceMeeting/InterviewComputer animation
Dynamic Host Configuration ProtocolDirect numerical simulationRead-only memoryComputer networkInformationSurfaceSoftware bugStack (abstract data type)BootingSemiconductor memoryCausalityQuicksortDependent and independent variablesSoftwareTLB <Informatik>Primitive (album)LeakCommunications protocolStandard deviationProgrammschleifeDirect numerical simulationNumeral (linguistics)Intrusion detection systemProduct (business)Cache (computing)ParsingIntegrated development environmentParticle systemGoodness of fitInformationBuildingFluid staticsCuboidRight angleComputer animation
EmailStandard deviationOvalTelephone number mappingDirect numerical simulationBootingContinued fractionFile Transfer ProtocolInformationLengthSurfaceParsingValidity (statistics)Condition numberLoop (music)CASE <Informatik>Right angleDirect numerical simulationQuicksortPresentation of a groupEntire functionBootingMultiplication signIntegrated development environmentFiber bundleBuffer solutionFluid staticsLengthSoftwareTotal S.A.Software bugStack (abstract data type)Email2 (number)NumberSemiconductor memoryServer (computing)Point (geometry)Frame problemCodeParsingGodPressureChainMetropolitan area networkSpeech synthesisVotingFreewareView (database)Computer animation
Integrated development environmentBootingParsingComputer networkCommunications protocolKeyboard shortcutCausalityFrame problemGame theorySurfaceLoop (music)BootingQuicksortSurgeryVideo gameMultiplication signSoftware1 (number)WordRight angleLengthFrame problemCASE <Informatik>Equivalence relationComputer configurationKeyboard shortcutSoftware bugTerm (mathematics)BlogBuffer solutionOpen sourceSpherical capSemiconductor memoryStack (abstract data type)Information extractionMeeting/InterviewComputer animation
ParsingData storage deviceSoftware protection dongleSurfaceOpen sourceNumberNumeral (linguistics)Stack (abstract data type)Spherical capPrime idealSoftware bugSurfaceBootingData recoveryEmailLengthCommunications protocolComputer fileTesselationSocial classMultiplication signVariable (mathematics)Validity (statistics)QuicksortFunctional (mathematics)BootingComputer wormData storage deviceBuffer overflowDoubling the cubeChainMereologyDependent and independent variablesLevel (video gaming)Quantum stateWebsiteRight angleConfiguration spaceContent (media)Scripting languageMusical ensembleTowerStructural loadHypermediaHecke operatorBuffer solutionMeeting/InterviewLecture/Conference
Total S.A.Configuration spaceData Encryption StandardFast Fourier transformSemiconductor memoryBuffer solutionNumberRevision controlLengthCountingArray data structureConfiguration spaceRule of inferenceChainContent (media)Scripting languageSoftware bugInterface (computing)EmailXML
Data bufferStack (abstract data type)Internet forumPrice indexComputer-generated imageryAsynchronous Transfer ModeBootingFreewareProcess (computing)Level (video gaming)Turing testAddress spaceIterationBlogSoftware developerSurfaceCASE <Informatik>EmailSequenceBootingBootingReal numberService (economics)Bus (computing)ChainParsingSemiconductor memoryConfiguration spaceDependent and independent variablesPrime idealLine (geometry)QuicksortPointer (computer programming)LengthFlash memoryRight angleData structureBoss CorporationSynchronizationSurfaceState of matterFreewareComputer animation
CountingRippingPhysical systemData managementAsynchronous Transfer ModeNP-hardInformation securityEntire functionMemory managementSurfaceCellular automatonParsingIntelBoundary value problemInformationRead-only memoryImplementationBoundary value problemService (economics)QuicksortDevice driverGame theoryArmRange (statistics)Arithmetic meanComputer-assisted translationBootingBuffer overflowException handlingWhiteboardSystem administratorControl flowFlow separationSemiconductor memoryIntegerComputer architectureCombinational logicNumeral (linguistics)Presentation of a groupRight angleCurveMaizeStack (abstract data type)SurfaceDataflowWeightCASE <Informatik>Turtle graphicsRule of inference1 (number)Exclusive orAsynchronous Transfer ModeCausalityoutputMultiplication signComputer animation
Computing platformRight angleGoodness of fitDisk read-and-write headDevice driverValidity (statistics)LogicObservational studyBoundary value problemSemiconductor memoryWebsitePlanningPoint (geometry)QuicksortWindowMultiplication signMaizeCommunications protocolLevel (video gaming)Software bugGoogolImplementationSide channel attackMeeting/Interview
MassControl flowBootingTuring testNormal (geometry)Device driverBootingComputer programmingConfiguration spaceCommunications protocolPOKEComputing platformGoodness of fitPhysicalismContext awarenessSemiconductor memorySoftware bugTerm (mathematics)Level (video gaming)Figurate numberXML
Computer hardwareCodeData integrityImplementationPresentation of a groupComputer hardwareMathematicsCodeElectronic signatureAsynchronous Transfer ModeLatent heatBlogMultiplication signGoodness of fitFormal verificationHydraulic motorLoop (music)InfinitySide channel attackBuffer overflowInjektivitätForcing (mathematics)Meeting/InterviewComputer animation
BefehlsprozessorPower (physics)Computer hardwareStructural equation modelingOpticsFibonacci numberBootingOpticsSpectrum (functional analysis)Key (cryptography)Side channel attackPower (physics)INTEGRALPresentation of a groupHacker (term)CodeDiscrepancy theorySpacetimeCryptographyQuicksortSpherical capComputer animation
Data integrityCodeNP-hardSheaf (mathematics)Electronic mailing listPresentation of a groupBefehlsprozessorComputing platformSoftware bugMereologySpacetimeElectronic signatureElectronic mailing listBootingCodeCuboidGrand Unified TheorySign (mathematics)SurfaceBus (computing)BlogComputer animation
Computer-generated imageryBootingDevice driverComputer fileSystem programmingSurfaceSystem callGroup actionGame theoryCodeDataflowBootingSystem callGroup actionIntegrated development environmentSurfaceMedical imagingSoftwareCodeDevice driverChainINTEGRALLecture/ConferenceMeeting/InterviewComputer animation
DataflowCodeGame theoryBootingMathematical analysisInterface (computing)Group actionSlide ruleGame theoryExploit (computer security)ChainFuzzy logicPoint (geometry)Black boxCore dumpCodeSystem callGroup actionBuildingControl flowInterface (computing)Data structure
InternetworkingRepository (publishing)CodeSource codeInformation securityPhysical lawLaptopNumberNominal numberLine (geometry)FirmwareSoftwareModule (mathematics)Kernel (computing)Fluid staticsBus (computing)Buffer solutionPhysical systemDiscrete element methodSurfaceBootingLecture/ConferenceMeeting/Interview
Core dumpSign (mathematics)Maxima and minimaExtreme programmingRight angleBefehlsprozessorSoftware bugComputer hardwareCodeKernel (computing)Flash memorySurfaceGame theorySemiconductor memoryIntegrated development environmentLaptopBootingModule (mathematics)Physical systemBus (computing)MereologyMeeting/Interview
Source codeReverse engineeringBookmark (World Wide Web)BootingDisassemblerNumberType theoryBitException handlingCuboidCASE <Informatik>Multiplication signLecture/ConferenceMeeting/Interview
FirmwareBooting2 (number)Right angleReliefProjective planeDrum memoryBitReverse engineeringRevision controlData storage deviceSoftware bugTouch typingBootingMachine visionComputer hardwareService (economics)Shared memoryCuboidPoint (geometry)Inheritance (object-oriented programming)Row (database)Block (periodic table)Slide ruleLecture/ConferenceMeeting/Interview
ArmInternetworkingSoftware bugPerspective (visual)BootingMaxima and minimaSurfaceOffice suiteMathematicsContext awarenessLecture/ConferenceMeeting/Interview
Bus (computing)SoftwareNumberConnectivity (graph theory)Integrated development environmentBootingDirect numerical simulationCore dumpLecture/Conference
CASE <Informatik>BitProjective planeRun time (program lifecycle phase)Multiplication signNumberComputer programmingReading (process)Computer hardwareDirection (geometry)LogicSemiconductor memoryError messageSoftware bugProgramming languageFormal languageLecture/ConferenceMeeting/Interview
Lecture/ConferenceComputer animation
Transcript: English(auto-generated)
our next speakers, Joseph and Ilya, 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?
Okay, cool. Welcome to Boot to Root, auditing bootloaders by example. I'm Joseph Tartaro, I hack things for IOactive, and this is my second time at Congress, so I'm really excited to be back here. Hi, I'm Ilya. This is my 18th or 19th 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 and 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.
Yes, 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 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, you know, areas
of attack surface that are interesting, this is probably where you should get started, and then 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
quote unquote bootloaders, 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 bootchain, 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 system standpoint of user land calling into kernel space, you'll have like kind of normal world calling it to 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 controlled 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 underestimate 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 an 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, phones, 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,
C-Bios, Cafe, which is Broadcom, I-Pixie, and TianoCore, 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 by 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've found, we're not going to argue exploitability, we don't know if they're available. We will for one. Yeah, we will for one. We don't really, 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 or 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 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 products 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, I-Pixie 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 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 UFI 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 UFI and exploit that vulnerability, and you're good to go. And then Cbios is the default
BIOS for Kimu, 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 UFI and OVMF. And then broad
com 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. I-Pixie, this would be more network-based
stuff, various parsing, and similar to Grub, there's UFI signed versions, so it's a great potential pivot for secure boot stuff. And then finally, Tianacore, there's a really no introduction needed here. There's been a ton of great presentations over the last
like 15 years of people just, you know, 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 Tianacore, realize that it's way better than everything else. And there's a lot of like implementations built on top of
it, like platform-specific stuff, Qualcomm's, ABL and XBL, things like that, so you'll have all these, you have the base Tianacore EDK2, and then you have all the custom stuff built on top. And then related to boot loaders, you have things like trust zone, 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 get 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's going to process those 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, you know, 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, then verify and load the next thing, and you'll
sometimes have a TPM involvement, you'll have some trust involvement and then OS interaction stuff like the OS basically setting things like NVRAM which will set, you know, configuration stuff and whatnot. So the boot ROM itself is something you've
probably seen the talk by Cordy 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, you know, 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 ARMA trust zone, Windows has VTL0, VTL1,
hypervisor stuff, and then, yeah, I'm basically repeating myself. And then even eventually the operating system, that's going to get, the kernel's 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, DMA and hardware stuff. The interesting thing about buses that we've noticed is that embedded designers
seem to inherently trust anything that an end user 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 spy flash, so just inherently trust it. Or an end
user isn't to the TPM. So 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, you just kind of call for environment Git 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 bug. And so an example of that would be right here you see there's an extra link 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 threw a bunch of bytes and it starts just kind of sending these weird packets over the wire and a bunch of boot piece 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 new 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 this 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 host name, mem copy with stir length. No checks. 128 by buffer, environment 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 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. Ten 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 gets the variable, then they'll grab the very first element of that variable as a length and then they use that as a length. And yep. So we're
going to go find that. 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 NVRAM that you can physically modify because you have physical access. And this is kind of an example of the default NVRAM. 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 this had to do with the GFFS2 file system loading. So you just do FSLoad.
And it's done. 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. Sweet. Cool. Cool. So that was the NVRAM attack surface which is usually the most fun to
play with. Programming the spy flash sometimes may take a little bit of fiddling but in terms of attack surface and fun things to play with, it's as Joe said often overlooked and so it's easy to play with. And so you saw all this S print defs and
mim copies and string copies. So there's a lot of fun there. But obviously there's not just NVRAM. 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 not technically checked or not all of it is because before you can do that, you need to be able to read something, right? And so obviously an example of a common file system would be FAT 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. 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. I think the other ones are
sort of examples of where there could be bugs, but those two will cover. So this is Grub and this is GrubX2 and GrubX2, you know, this is the sim link code. So it looks to file system and it goes, oh, okay, this is a sim link. How do I parse a 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 add, I'll allocate that much size, but I'll do one more for no bytes. And of course that is a classic integer 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 of 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 than disk, it stops reading. So even though you can, say, 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 TianaCore, for example. This was the bitmap splash screen parser. And I don't
know the ending about bitmap internals. It's a very simple format, but basically you can have a 4-bit bitmap and that gives you a palette of 4x4, which is 16 bytes. And so the idea is if you have a 4-bit bitmap, then it has a 16-byte palette and so it goes and reads that 16-byte palette, except you
tell it how big the palette is and you can say, okay, I know you're expecting a 16-byte palette, but I'm giving you a 256-byte palette and it'll 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 this is just the
tip of the iceberg. There are many, many, many more. This did not take long to find. But let's move on. Obviously, okay, now that we've looked at some local stuff and some physical stuff, what about remote? What is there, right? Obviously, if you're talking remote in the modern world, you're talking TCP IP, right? 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, right? And that's BootP and DHCP and DNS and, you know, iSCSI and NFS. And if you're in a corporate, if you're a corpnet, you probably want to have IPsec and then HTTP and HPS and TFTP, right? And sure enough, you know, most bootloaders have code for
this. And then you start asking, okay, well, what's the attack surface? You know, for TCP IP, if you implement your own stack, good luck, because you're gonna 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 TLB parsing. And so you go look into, like, what are the things that can go wrong if you do TLB parsing. And, you know, there'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 protocols top of that, like DHCP and DNS, you know, you can, you have sort of your
standard sort of network attacks where you'll see, like, least stealing or cache 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 know, you can have these kind of poisoning, stealing, man-in-the-middle attacks, right? And then thirdly, obviously, you know, the thing we really like to
see is memory corruption bugs. You know, 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, Heartbleed, of course, was one example. It was a
perfect primitive. But generally, it'll be this thing where, you know, you end up generating some kind of packet as a response to something. And, you know, you'll have done the memory allocation, but for some reason not initialize something, and so you end up sending uninitialized data over the network. So this is sort of the common things you see in 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 Isik. That'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. So U-boot, for example, this is the U-boot 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 U-boot environment is extremely trivial. You guess that 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 DHCP parser, and it basically has this sort of this 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 U-wind 8, so that means it can represent 0 up to 255, and then it reads 0 up 255 into that junk buffer. So that's a stack corruption right there. If you then
look at the coffee, a TFP 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 ICMP ping handler, and this has this really cute sort of use-after-free bug or double-free, where it basically it sends out the ping, and then it sits there receiving, 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 an else loop, it has a timeout, and there's this interesting condition where if the last thing it looked was the packet you're looking for, but it also timed out at the exact same time, it frees 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 handler in 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 the 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 average bootloader. 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, 802.11, and a surprising number of bootloaders don't have 802.11, so I don't know if that's sort of
on purpose, or it's just sort of, we didn't get to having this feature yet, but we will at some point, and obviously we'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 802.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 radios that sort of, you know, they take packets 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 attack servers point of view, if you're looking to attack
the bootloader and not the firmware. So yeah, we looked at I-Pixie, and of course, you know, anytime you do any kind of Wi-Fi stop, 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 IEs that it gets, and then when it finds the right IE for an SSID, it says, okay, we'll take this IE, and we'll do IE length, and the IE length is 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 I-Pixie 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 down-the-coaster 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 somebody invents a new bootloader. And also, if you're gonna do Bluetooth in a bootloader, it's usually for, you know, HID device, right? This is for keyboard and mouse, this usually ends up being for
consumer devices. But in general, if you look at a Bluetooth stack, and you're looking for any kind of, you know, parsing bugs, there's three sort of recurring themes. There's three sort of recurring themes 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 L2 cap 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 65,000 bytes a byte, 65,000 number of bytes. So if you start playing around with
the fragmentation, 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 bootloaders. So moving on to USB. This is a prime attack
surface in bootloaders, 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 to, that's the, if I, anytime I look at a USB load, at a bootloader, my first thought is, you know, and VRAM and number two is USB, right? And USB is interesting because obviously a lot of bootloaders support USB because they'll use it either for storage or, you know, things like Ethernet 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, right? 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 descriptor responses, the host
can then figure out, like, what kind of device you are and, like, 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 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 implementations, what happens is you go get the header, you allocate a buffer, and then you go get the header and payload again, and you overwrite the original header, which means is you get to overwrite the original header length. And so you can have a talk tile 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 Grub, for example, where it goes and gets a descriptor, and the descriptor says, oh, here's my conflict count, I have this number of configurations, go and fetch those in the script as well. And there is a predefined array of number of configurations that Grub has, and it doesn't correlate that with the conflict count,
it just always assumes the conflict count is less to or equal to the array. And so if you have a malicious device and you say, hey, I know your arrays are two bytes, or two 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
the Swiss Tiana core, where they go and get a descriptor, and then 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
UN8, so it can send up to 255 bytes, and so that would have smashed memory and caused 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 UN8, so if you make the buffer 256, then any length you give it will fit within the buffer.
Hold on. Yeah, this is an example in CBIOS, 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 wtotallength is the same thing as whoever calls this sting can no longer trust wtotallength 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 bootloader. So this is a case of the Nintendo Switch, the Tegra, this was done by the failoverflow people about a year or so ago, that basically, you know, you give it a length that's not validated, and then a memcpy 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 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, a bunch of the buses, or almost any bus on your device, if your boot chain uses it, it's an interesting attack surface, and this is spy, I mean, spy
flash shouldn't 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 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 talks to TPM, and it goes and gets this structure, and you can send it less than what it expects, and then basically they subtract some side of the 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 into 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 into overflow is, and technically it's not into overflow because it's a bunch of shifting being done, but it essentially comes
down to an into overflow. Yeah, there we go. Yep, there we go. Okay, so another attack service that is interesting but often overlooked on devices except for Eufy is system management
mode, and I mean there have been over the last decade and a half numerous, numerous presentations about SMM attack service and breaking SMM handlers for Eufy, because it's an x86 thing, and you see this in Eufy stacks, and it was a sort of cat and mouse game where for years, you know, somebody breaks something and then Eufy fixes it, and then somebody breaks it again,
and then you fix it again, and somebody breaks it again, and Eufy 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, Eufy 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 Eufy, right? Well, that means you're going to run into all the same problems Eufy 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 on the first time,
this is what Coreboot 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, the idea has been DMA is game over, right? If you get DMA, then that's that, there's no trust boundary. Obviously, that's no longer true,
right? We have IOMUs, and if you use them, and then if you have a device that has this available, then all of a sudden 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 IMU, 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 IMUs, it depends on your architecture and sort of the board you have and all sorts of things, so Intel's FTD, 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 service, 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 IMU, you have to go back to all your drivers and look at, okay, where am I doing DMA, and now I can no longer trust what's in, when I get back from DMA,
and you've got 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 IMU, because you are assuming the IMU is 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 IMUs and see if I can attack IMUs 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 designy, right? So this is UFI today,
EDK2 platform code, where it has support for IMU and they're ahead of the curve, but if you look at the spec, there's no good handover protocol from UFI to the next stage, and so UFI basically boots up and very early configures the IMU and makes 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 IMU, so it undoes all the IMU 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 at Intel 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 unsigned code. And a recent
example of some glitching was done by failoverflow for the PS4 SysCon. 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 it would say that's not enabled, infinite loop, and then there's a glitch out of it, and then it
initializes debug mode. And so stuff like that obviously should be concerned with. Then clearly side channel with timing discrepancies, power discrepancies, things like spectrum meltdown, speculative execution in general. These are where people are leaking
secrets, right, 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 cems. 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 CEM 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 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 of 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 that was released by Kaspersky. And if that's not on the blacklist of your platform at home, you can just load that up and 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 they can't blacklist anymore. So there's a concern there. And then you'll have issues where they'll only sign certain portions, not the full blob. So you can still modify certain parts or sometimes you'll see they'll just check for a signature existing but they
don't validate it. 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 BIOS 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 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 firstborn to get access to that stuff. 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 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, there 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, overwrite the stored PC and that's it. Like there's
no ASLR, there's no anything like that. Code for 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 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 build instructions were 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 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'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 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 ten minutes for Q&A. And we will start immediately with the internet. Thank you. Has the grub issue been fixed yet? And was the code unique to grub or
borrowed from, you know, elsewhere? I don't think it's been fixed yet. And this was from whatever the official grub 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, please. 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 compiled in, no modules. But what about the text surfaces that say somebody tries to interrupt the line of
booting, for example, that you maybe somehow get into maybe DMA access because you somehow interfere with let's say Broadcom network device that has some special firmware to optimize the traffic or something. And then this
thing gets buffer overflowed and makes some problems on the bus or something. Are you talking about attack surface from devices? Yes, like I said, 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 then just boots. And the kernel is in the core boot and so it's in the flash. But you can get problems by let's say some devices that just spit into your memory because they can do a DMA master. Yeah, that's definitely a concern. And that's one of the things we were like,
okay, well, if you do use DMA as it has been forever, then it's game over. Luckily, nowadays we have IOMUs. So depending on 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 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 of an answer as I can come up with. So this is the maximum you can do against some attacks? I mean, from a device? Let's say you want to make an extreme hardware laptop that you use in an extreme hostile
environment. Say again? You want to make a hardware 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 OS and look at how it parses the stuff that comes from the bus, because there will 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 you have it as minimized as possible, then you just kind of hope there's nothing there. You don't need the code signing because you have everything in your flash, or you still need some stuff. Oh, you mean stuff that runs on the host? Yeah. Let's say you have a core boot on the Linux kernel in the
flash. And so everything is that you have for that time. And you maybe take this discussion after the talk because we have more questions. Thank you. Thanks. Signal Angel, please. What is your favorite disassembler that you use while reverse engineering the boot loaders? We didn't really, we just looked at source code.
We should be in a few places. I mean, for 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 a disassembler. I guess a little bit of GDB. In general, when we do do reverse engineering, I mean,
IDA is my go-to. I've been playing around with Gidro a little bit. It looks promising. It has undo, which is nice. But those are usually, and you know, for doing Linux type stuff, GDB is nice when you're doing debugging. But generally, IDA.
Microphone number one, please. I have two questions. What's your opinion on the untrusted firmware architecture? I have to work with this and I'm a little bit shocked. My opinion is a little bit over complicated. And the second question is, should we also question the boot ROMs?
Because what I've seen in the special project, it leads me to believe that the boot ROM is also very broken. And then it's the question if it's really necessary to harden the other stuff anymore. Right. Yep. Those are really good questions, by the way. It sounds like you're working on this.
So, your first question was what again? What do you think about the untrusted firmware architecture? Right, yes. 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 none. Yeah, I see you're aware of this problem.
But I share your opinion that there are some things in there that are troubling. With regards to the boot ROMs, you are spot on, sir. We tried to bring this up in one of the slides. If there's a bug there, you can't fix it. Hardware revision is the only way to fix it, so you're kind of screwed. There are some designs you can do to try to minimize it.
So you could say, okay, well, in your boot ROM, you could have a feature that allows for quote-unquote patching the boot ROM, where you can have a piece of something on storage that could overwrite what the boot ROM is supposed to do. Obviously, up until that point, whenever it's in the boot ROM, still, you can't fix that. But you can minimize the amount of stuff in the boot ROM that's not patchable.
But you can't minimize all of it. I mean, there's got 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 black box, and it's a 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 stack, and then the switch goes down, or the iPhone, or whatever else, right? So, from my perspective, I would say it would make more sense to do more open auditing,
and let more eyes see it, instead of hiding it in the corner, and pretending like, well, it's okay, because nobody's looking. That's at least my perspective on it. I know why people are super secretive about it, but you need more eyeballs.
Maybe if you've got the right context, my wish would be to get blank chips, so I could flash them with my own boot ROM. So, I have a method to improve things, and keep the text surface minimum. Yeah, and then there's going to be two other armed eyes 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 fuzzer? Ooh, not in this hole.
I mentioned a few places. So, if you're doing any kind of file-based stuff, and you can isolate it, AFL, that's the go-to these days. For network stuff, there's a couple of interesting ones, like ISIC, and there's some Wi-Fi fuzzers, and I think there's some DNS fuzzers, and 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 fuzzer for that environment, you just pull that feature out, and harness it up, and then let it run on a bunch of cores. Yes, I think libFuzzer might be very helpful there.
All right. Number two, please. Hi. Would it help producing the occurrence of such errors by using another programming language like that would feature more secure things at compile time or during run time like maybe Rust?
Would it help? If yes, are there alternative projects that use other languages other than C? I'm not aware. I think you're right. I think we can reduce the amount of, especially the memory corruption stuff. If you switch to something like Rust, even though I think on occasion there's some Rust
corner case that shows up or 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? So there was a talk by Andrea Barasani yesterday or the day before where he's doing a Go run
time 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, there will still be 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're out of time. Please thank our speakers again.