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

Baring the system: New vulnerabilities in SMM of Coreboot and UEFI based systems

00:00

Formal Metadata

Title
Baring the system: New vulnerabilities in SMM of Coreboot and UEFI based systems
Title of Series
Part Number
15
Number of Parts
20
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
Production PlaceBrüssel

Content Metadata

Subject Area
Genre
Abstract
Previously, we discovered a number of vulnerabilities in UEFI based firmware including software vulnerabilities in SMI handlers that could lead to SMM code execution, attacks on hypervisors like Xen, Hyper-V and bypassing modern security protections in Windows 10 such as Virtual Secure Mode with Credential and Device Guard. These issues led to changes in the way OS communicates with SMM on UEFI based systems and new Windows SMM Security Mitigations ACPI Table (WSMT). This research describes an entirely new class of vulnerabilities affecting SMI handlers on systems with Coreboot and UEFI based firmware. These issues are caused by incorrect trust assumptions between the firmware and underlying hardware which makes them applicable to any type of system firmware. We will describe impact and various mitigation techniques. We will also release a module for open source CHIPSEC framework to automatically detect this type of issues on a running system.
Pattern languageSummierbarkeitMathematicsSystem programmingBasis <Mathematik>Core dumpSelf-organizationInternetworkingPresentation of a groupComputer animationXML
Type theoryVulnerability (computing)GenderSystem programmingSemiconductor memorySummierbarkeitComputer programmingFunctional (mathematics)Limit (category theory)Metropolitan area networkBasis <Mathematik>Game controllerCASE <Informatik>Data structureOpen setBuffer solutionOperating systemMoment (mathematics)Level (video gaming)Point (geometry)Descriptive statisticsRevision controlStatisticsRight angleBefehlsprozessorQuantificationState of matterImage registrationPresentation of a groupBitEndliche ModelltheorieSystem callDivision (mathematics)Address spaceFirmwarePerspective (visual)Exploit (computer security)Ring (mathematics)ComputerFunction (mathematics)BootingRootCore dumpCodePointer (computer programming)Module (mathematics)Computer animation
Vulnerability (computing)Demo (music)Core dumpExtension (kinesiology)Digital mediaFunctional (mathematics)Bus (computing)Set theoryMessage passingConfiguration spaceMusical ensembleSemiconductor memoryData structureSound effectResultantBitPersonal digital assistantGraphical user interfaceHydraulic jumpSpacetimeResource allocationInformation and communications technologyElectronic mailing listSpring (hydrology)Presentation of a groupCircleSlide ruleCovering spaceMereologyDifferent (Kate Ryan album)Service (economics)Interrupt <Informatik>Game controllerNetwork topologyBridging (networking)MultiplicationPoint (geometry)Link (knot theory)Process (computing)Connectivity (graph theory)Direction (geometry)MappingCommunications protocolNumbering schemeSystem programmingTelecommunicationCartesian coordinate systemType theoryBuffer solutionRevision controlRepresentation (politics)AreaProxy serverBlogBinary multiplierUser interfaceCollisionTable (information)Operating systemStandard deviationMedical imagingRange (statistics)State of matterRight angleBoss CorporationTotal S.A.RobotWindows RegistryCellular automatonoutputCASE <Informatik>Context awarenessSurjective functionReading (process)Moment (mathematics)Open sourceSpeech synthesisCycle (graph theory)SphereFlash memoryProcess capability indexPCI ExpressComputerBootingLimit (category theory)RootLatent heatFile viewerAddress spaceRun time (program lifecycle phase)Pointer (computer programming)DataflowComplex (psychology)Level (video gaming)Dynamic random-access memoryFirmwareExpressionSoftware bugError messageVirtual memoryArithmetic meanFerry CorstenUniform resource locatorEmailComputer hardwareOperator (mathematics)Lecture/ConferenceComputer animation
MultiplicationWeb pageTheoryRange (statistics)WritingSemiconductor memoryVariable (mathematics)Type theoryContent (media)Reading (process)Interrupt <Informatik>Cycle (graph theory)Configuration spaceFlash memoryUniform resource locatorLevel (video gaming)Game controllerLatent heatCodeSystem programmingOrder (biology)Address spaceRing (mathematics)Asynchronous Transfer ModeSystem administratorBus (computing)Control flowFirmwareSpacetimeDatabase transactionNormal (geometry)Different (Kate Ryan album)Computer hardwareFunctional (mathematics)MathematicsMereologyBootingMultiplication signBoundary value problemAdditionRight angleFunction (mathematics)TelecommunicationVirtual memoryLogicRootComplex (psychology)WeightRoutingFormal languagePosition operatorRun time (program lifecycle phase)Moment (mathematics)Graph (mathematics)Core dumpFluid staticsPerspective (visual)CASE <Informatik>Commitment schemeCausalityElectronic mailing listVideo gameParticle systemWebsiteDataflowMedical imagingForcing (mathematics)Metropolitan area networkNP-hardTouchscreenPhysicalismComputer animation
Bus (computing)HexagonAddress spaceGame controllerWritingFunctional (mathematics)Shift operatorFirmwareVirtual memoryConfiguration spaceCore dumpPCI ExpressContent (media)Total S.A.Range (statistics)DecimalSpacetimeProcess capability indexMathematicsTheoryType theoryGreatest elementLogical constantLevel (video gaming)AdditionData managementLocal area networkBit2 (number)Semiconductor memoryQuicksortRoute of administrationDifferent (Kate Ryan album)MereologyPhysicalismCASE <Informatik>Chemical equationNumbering schemeMultiplication signBridging (networking)3 (number)PlanningEvent horizonSlide ruleTouchscreenCartesian coordinate systemWindowBoss CorporationBranch (computer science)EmailReading (process)Position operatorBinary codeCycle (graph theory)Context awarenessComputer animation
Computer architectureBoss CorporationAddress spaceFunctional (mathematics)Semiconductor memoryRight angleCore dumpData compressionLevel (video gaming)Range (statistics)Disk read-and-write headSet theoryGame controllerLine (geometry)Cartesian coordinate systemComputing platformReading (process)MereologyBoundary value problemSoftware developerTouchscreenPlotterIdeal (ethics)CASE <Informatik>Exploit (computer security)Configuration spaceSlide ruleOrder (biology)BlogCycle (graph theory)Limit (category theory)PCI ExpressSystem programmingLogical constantMotherboardInsertion lossNumbering schemeEvent horizonMetropolitan area networkType theoryBit rateFigurate numberGroup actionContent (media)WhiteboardBitSystem on a chipHexagonProcess capability indexBus (computing)Open sourceCodeAsynchronous Transfer ModeFirmwareVirtual memoryPower (physics)Ring (mathematics)SoftwareComputer animation
Computing platformCASE <Informatik>Particle systemPresentation of a groupArithmetic meanCondition numberDefault (computer science)Range (statistics)Parameter (computer programming)MereologyFree variables and bound variablesParallel portWordDifferent (Kate Ryan album)Semiconductor memoryRun time (program lifecycle phase)Entire functionType theoryContent (media)Virtual memoryCodeWeb pageSystem programmingPhysicalismTheory of relativityAddress spaceComputer configurationNumbering schemeAsynchronous Transfer ModeCommunications protocolSocial classQuicksortStandard deviationFerry CorstenUsabilityDataflowUniform resource locatorEstimatorLogical constantPoint (geometry)Regular graphSoftware bugRight angleVariable (mathematics)Limit (category theory)Pointer (computer programming)Game controllerImplementationBridging (networking)MathematicsBoss CorporationHacker (term)EmailRhombusProcess capability indexForcing (mathematics)SpacetimeBitCycle (graph theory)Functional (mathematics)Exploit (computer security)BootingWindowFirmwareComputer hardwareGoodness of fitDigital rights managementHexagonHoaxInterrupt <Informatik>Latent heatDynamic random-access memoryPartial derivativeComputer animation
Multiplication signSystem programmingBitReading (process)Functional (mathematics)Game controllerHexagonMultilaterationOnline helpKeyboard shortcutNumbering schemeLaptopPlanningSource codeComputer animation
Numbering schemeHexagonSemiconductor memoryAddress spacePresentation of a groupContent (media)Source codeComputer animation
Digital rights managementRange (statistics)Virtual memoryPoint (geometry)Content (media)Variable (mathematics)Right angleGame controllerCASE <Informatik>Semiconductor memorySign (mathematics)Operator (mathematics)Address spaceUniform resource locatorBefehlsprozessorCore dumpLoginHexagonSource codeComputer animation
Range (statistics)HexagonUniform resource locatorContent (media)System programmingRight angleOpen sourceEntire functionConfiguration spaceBootingSet theoryFirmwareRun time (program lifecycle phase)CodeRing (mathematics)Semiconductor memoryMathematical analysisScripting languageNegative numberAddress spaceType theoryBinary codeComputer hardwareRootVariable (mathematics)File archiverLogical constantPosition operatorFile formatData compressionSource codeComputer animation
Default (computer science)CASE <Informatik>Uniform resource locatorComputer configurationMultiplication signCodeComputer architectureData dictionaryPresentation of a groupPoint (geometry)Boss CorporationType theoryNormal (geometry)Configuration spaceVector spaceData storage deviceOperating systemAddress spaceVirtual realityReading (process)Semiconductor memoryDatabaseOptical disc driveBinary codeObject (grammar)Vector potentialMathematical analysisCombinational logicIntegrated development environmentGoodness of fitOrder (biology)SpacetimeKernel (computing)Right angleAuthorizationWeb 2.0Ideal (ethics)Cache (computing)Level (video gaming)Generic programmingExtension (kinesiology)Range (statistics)Functional (mathematics)Block (periodic table)Slide ruleBranch (computer science)Event horizonPressureProcess capability indexSoftwareFirmwareExploit (computer security)Loop (music)Ring (mathematics)Run time (program lifecycle phase)Game controllerWritingContext awarenessSeitentabelleQuicksortLaptopComputer hardwareControl flowWindowLattice (group)Virtual memoryVirtualizationLecture/Conference
Computer animation
Transcript: English(auto-generated)
in Brussels 2017.
Hey guys, my name is Alex. Here is Yuri. We're working on advanced internet research in the Intel. And we're here to present the new presentation, Burying the System, New Venerabilities in Core Boot, and unified basis system. Before we go to the presentation,
I want to say thank you to the organizers of Recon, Hugo, Sam, Neo, Asom, Recon, Brussels, Asom, thank you very much. Yeah, so, today we will present the new type of vulnerability and in our agenda we have that small recap about the previous vulnerabilities,
then introduction about memory, MapDAO, then description about MMU bar overlap issue, examples of this issue in UEFI firmware and Core Boot firmware, limitations, mitigations, tools, and conclusion.
The recap is really important for this presentation because the vulnerability is a little bit similar to the previous one and in many perspective and exploitability in the modules when we found them. Like this. Okay, thank you.
So, what is a semi-poison pointer bug? So, in X86 system you have couple privileged level and the most privileged is SMM. And there is a mechanism to communicate between the operation system and SMM mode. And it's going like that.
The operation system allocate the buffer, then pass the address of the buffer through some structure and depends on the version of the firmware and then the SMM code read that buffer and depends on functionality, it can read or write. In ADK one, basic firmware, the buffer,
the address of the buffer will be passing through a general purpose register, RBX. In ADK two, there is a mechanism named COM buffer and the address of COM buffer is passing through a UEFI ECPI table. And in normal behavior, the address of this COM buffer
is somewhere controlled by the operation system. But, if we point in the address back to SMM, SMM doesn't have a check and we have arbitrary write in SMM code. Using this write primitive, we usually control the address where to write, but we not often control the data.
At some of the exploits which we demonstrated previously, we write zeros. And then, to make an exploit, we find the structure in CPU safe state, SMBASE registration. And when we write this register, the next SMI will start executing from unprotected memory
and ring zero attacker can control it and make a privilege escalation to the SMM code. Then, this vulnerability was fixed by adding the check in SMI handlers. So, SMI handler check the address is not pointing to SMM.
But, what if we have scenario when we have hypervisor or, for example, hypervisor-based protection like VSM or just a hypervisor with a root partition? In this case, we can point the address in general purpose register or in COM buffer
to some of the structure of the hypervisor and override it. And in this case, the untrusted guest from ring zero make a privilege escalation to the hypervisor. The interesting fact is that even if this vulnerability is patched in the firmware and firmware is fully
protected, the untrusted guest can use it to make a privilege escalation like confused deputy attack when there is no vulnerability but you can still exploit and make a code execution in the hypervisor. And, we demonstrated the exploit to the VSM which basically uses some firmware vulnerability
to compromise VSM and dump credentials. We made this demo in 2015. There was another example of SMI pointer vulnerability founded by ATR and then published by Sagitti SEQ Lab.
The vulnerability is pretty similar that we found. So, it's reading the buffer from the general purpose registry, that the buffer to the function read flash data and in the function read flash data, it's using the function read and you control
on the offset of the destination, you control on the source and the size. In this case, there is no checks where the address will be. So, if your address is in the surround, you can dump and read and write SMM. Really nice write up. Also, Dimitri Alexuk published many couple presentation,
couple blog post about different type of SMM pointer vulnerabilities. So, how the community and the vendors react on this? How we fix it? There is a protection which I already mentioned to check that the address not pointing to the SMM
and flow function SMM is buffer outside SMM valid. It's fixing the problem with the firmware, but it doesn't fix the problem with the hypervisor and the vulnerability and bypass privilege escalation to the hypervisor. So, to fix this vulnerability,
there was another mitigation added to the limit com buffer address. And so, address now should be fixed. And there is a CPA table, name Windows SMM mitigation CPA table, which is basically should be initialized by the firmware
and read it by the operation system, which is passing the configuration of the mitigation. And there is couple bits there. One is defining that the common buffer is fixed and then define it location and the SMM is checking all of the input and output buffer. Another one is nested, that meaning that if you have a pointer inside the com buffer,
it's checking this pointers as well. And another protection is that you have locked some of the configuration of the hardware after exit boot, during the exit boot services. For example, interrupt controller, IOMMU and so on.
And that kind of mitigation was added after we published this research and communicate with others. A little bit about MMIO, because this bug is really rely on the different behavior of MMIO. In X86 system to communicate to the device, there is PCI express protocol.
And in this protocol, there is a fabrics which contain multiple components, the components interconnected to certain topologies. In this topology, there is a root complex which has multiple ports. There is endpoints, switches, bridges. All of them is connected to be a PCI express link.
Every physical component has up to eight virtual physical functions and all in some of them may integrate to the root complex. So basically, this protocol is allowing to talk to the device and send DMA and so on.
Every device has PC config space in a device and that PC config space contain the header of the, the header, then it contain the PC express capability structure and the extensions. So the entire structure is 4K,
but without extensions, it's 256 bytes. To get the access to the PCI and PC configuration, there is two interfaces. One is to get access to PCI configuration space using port IO CF8 CFC.
When we construct the address, knowing the bus device and function and offset which we want to read from the specific device and then the pass it through the CF8 CFC, we can read and write to specific register in PCIE configuration. To get access to the extended configuration space,
we need to use enhancing configuration access mechanism. We just want it as memory map. So basically, memory which is split by four kilobytes per each bus device function and through that memory, we can access to the extension configuration space of the device
and read the register from there. So to read them, we're using MMU control memory map config register plus bus multiply 32 multiply eight multiply one K plus device multiply eight multiply one K plus function plus offset. Then we construct the address, then we use it as a memory access
and we can read and write registry. So there basically, all of that configuration, all of that PCIE configuration is for storing some configuration registry for the device. But even 4K was not enough for modern devices.
They want to store much more, like graphics want to store megabytes. And here was the error when MMU became, so the MMU is the range of memory and access to that range is forwarding to the device and device will handle that.
And this ranges is defined through MMU bars and MMU bars is in PCIE config space which we are talking in previous slide. And if you see like there is a header of the PCIE configuration space and there is device ID,
there is vendor ID, status registry, some other register, and then the base address zero is the first MMU bar. As you see here, there is just the address, so we don't know the size. The bars itself, they are self-aligned.
Meaning if you write all Fs to the bar, the bits which didn't flip from zero to one is the beliefs which define the size of the MMU bar. For example, if there is one byte didn't flip, then meaning that you have the 256 size of the bar,
256 byte. Here is the simplified version of the layout in the memory just to get the small representation of where MMU is. So we have a low DRAM, then there is SMM protected by SMRIs and there is a graphic memory.
Then we have Tolut and there is a memory map config. Then there is low DRAM with all of the bar which was defined through PCIE config space. And there is a direct map and BIOS and there we have high DRAM. So all of the bars should be defined somewhere here. And here is couple examples of the MMU bars.
There is the name of the bar, like GTTMMRDR, which has the address of 0002010 with 10 offset and then it has the size, the two megabytes. So all of them is, you can use a chipset tool
to just run MMU list and enumerate the known PCIE bars, MMU bars, sorry. Okay, so one of the important aspects of the MMU range registry, MMU bars, is that they can be relocatable at runtime and OS can relocate them to any other location.
Some of the MMU bars is not relocatable. They are fixed or locked by the firmware but some of them is relocated. And now Yuri will explain why it is an issue. Hey everyone.
I take it you can hear me. So I've just noticed that all of the animation that I spent hours on is pretty much gone from the slides. That's convenient. That's how I guess the difference between PowerPoint and PowerPoint Viewer. Anyway, so how's that related to
what Alex been talking about? These issues depend on this memory mapped IO configuration behavior. And in fact they are kind of caused by the way firmware talks to the devices, talks to the devices through the memory mapped IO.
So the way firmware uses this memory mapped IO mechanism and communicates with the devices is that, and this is specifically to the SMI handlers but keep in mind that the entire firmware including the boot firmware, regardless of which type of firmware that is, UEFI based firmware or core based firmware
or just legacy bias or anything else, also talks to the devices through the memory mapped IO mechanism. So there is a PCI configuration space in each device or actually each virtual device or a function of a device, PCI config header. And it has this base address register
which defines the base of the memory range for that particular device. And so what usually as my handlers do, as well as any other firmware, boot firmware, they get the base register, they read the base register to get the base address of this LMI range
and then they either read registers within that range, MMI registers or write those registers or read, modify, write those registers. So basically in order to send IO cycles to the particular device.
And so, yeah. So this is how they essentially communicate with the devices. Now the problem, the theory of the problem becomes that there is an implicit trust assumption on the firmware side, on the firmware part that those are hardware registers.
So therefore they're part of the hardware and hardware is part of the trust boundary. And so basically firmware for the most part trusts all of the hardware including those registers. So there's an assumption that nobody can change those registers. However, those are just ring zero accessible registers
that could be modified by any ring zero code. So that's one example of what the ring zero code, OS level code can do or the code, the ring three code if it has enough privileges to talk to the PCI config space
let's say modify PCI config registers like this bar register. So the problem is that this ring zero code or OS level code can modify those bar registers and relocate the range for a particular device somewhere else in physical addressable space.
It could be somewhere in other MMIO. It could be overlapping with some other things but it can also be in the DRAM in the system memory. And specifically one particular location where the attacker would be interested in is the system management mode memory. So the exploit code could modify
and relocate the memory mapped IO range to overlap with the SMRAM. Then when SMI interrupt is generated either by hardware or by the attack code itself
the firmware, SMI handler firmware attempts to communicate with the device through this memory mapped IO range. Attempts to read registers or write registers. And so basically instead of actually sending cycles to the device as MMIO cycles which are memory cycles on the PCI bus
it sends memory transactions to its own memory or some other memory depending on where the attacker relocated this MMIO range. So that potentially can either expose data because it reads its own memory or basically modify the control flow if it reads some attacker manipulated data.
Or it can potentially corrupt the memory because of the memory write cycles to the MMIO registers. So that's the theory of this problem. And what we've observed in multiple types of firmware including UEFI and corporate firmware
is that the SMI handlers communicate with a lot of MMIO bars. And examples include eHCI USB2 bars, Gigabit Ethernet LAN, root complex MMIO that's the main MMIO for the PCHs.
Or specifically the SPI registers that basically in order to communicate with the SPI flash right to the SPI flash or read from the SPI flash. HCI SATA controller MMIO, XHCI USB3 controller integrated graphics device, MMIO basically GTT MMADR range for the graphics device.
Or some other MMIOs like for example the I think it's a LID controller or something that on a different bus on the specific systems. It could be more. This is what we've seen. It could be more. So there might be a specific system
that has a specific SMI handler which communicates with a specific device. Or maybe has some functionality specific to that system communicating with a generic device. So this is an example. This is an example of communicating with a SPI controller in order to read something from SPI flash
or write something to use SPI flash. So there is a command basically. The first command is attempting to store a persistent configuration for the UEFI firmware into the SPI flash. It's called UEFI variable if you're familiar but basically it's the configuration of the firmware.
So this is the first command attempts to store something into the SPI flash, this configuration. And the second command just dumps the SPI memory map range, all the registers. I don't show all the registers here. I'm just showing the registers that I'm interested in. And so you can see that there's a SPI status
and control register which tells the status of the SPI cycle and also sends that SPI cycle on the SPI bus. There's an SPI flash address. It's the register that is programmed with the flash address on the SPI flash device.
And there's also a whole bunch of registers that are programmed with the contents of what you want to write to the SPI flash. Or what you want to read from the SPI flash. So in this particular case, this is the contents of that variable that I've been writing in the first command.
So you can see all 42, 42, that's B, right? So the contents of the variable was all Bs. And you can see that all of these registers now contain the contents of the variable. So obviously if we overlap this SPI and my range with something else like the SM RAM
or some other page protected, then we can cause this contents of the variables written onto that range. So how do we find this type of issue? So obviously, you know, SMI handler is writing something to SPI bar or to, sorry, to any MMI bar.
So it looks like to find all those problems, it's just easy as dump the contents of the MMI range, then cause the SMI, and then dump again and see which register has changed in the SMI. And now you know that the SMI handler
modified those registers. Unfortunately, this is a lot more complex than that. And initially, we thought it would be very similar to identify those issues at runtime, but in reality, it's pretty complex. And the reason is because those are not memory contents. So in addition to firmware, other parties are also writing to those registers.
So the hardware itself, the devices or integrated controllers or some logic in the hardware writes to those registers in pretty much any MMI bar. For example, some of the bars like graphics bars, the hardware writes to thousands of registers
in the MMI range. So it's pretty difficult to actually, identify which registers have been modified by the SMI code itself. So that's kind of the high level, all entire flow, how we kind of solved that problem. So basically, what we do is that we, for every MMI range, we dump the MMI range
multiple times with a delay, let's say 20 times, and we find all of the registers that normally change without SMI handlers. So we add those registers to the list and call it a normal difference or something like that. And then we trigger SMIs or cause a function like the variable write that would trigger an SMI.
And then we have our, sorry, after every SMI, we dump that range again, see which registers have changed and compare them with that normal difference, with the registers that normally change. If we see any new register
that is not part of that normal difference, basically, we suspect that this register might have been changed in the SMI handler. So we send an SMI, the same SMI again, maybe even multiple times, to confirm that this register changes every time we send the same SMI. And even with that mechanism,
there are lots of false positives, because even when we create normal difference, we don't catch all the registers. So it happens that when you trigger an SMI, some register changes, but it's not really because of the SMI handler, but because of the device decided that at this moment, I want to write to that new register.
Oh, awesome. That's not the end. So that's an example, essentially, just of running this sort of a tool that monitors the changes in the MMI bars.
This particular example, monitors changes in the EHCI USB bar, and you can see that then it created normal difference with just two registers normally change, then it triggered multiple SMIs,
and the first SMI found that one register, additional register changed, so it re-triggered that SMI again, and that register didn't change. It also can be a false negative as well, because the SMI handler might be flipping a bit, flipping one, flipping back, and so on,
but this is a suspect to investigate later. So this was a theory about the other issues, so now I'll give you a few examples of those issues in UEFI firmware as well as in core boot, so we'll start with the UEFI. So how do we find those issues in the binary?
Let's say we have EFI binaries, we load them in IDA, and how do we find those? So one way of finding those type of issues is you can find places where SMI handlers, or the firmware, that reads the contents of the base address register,
and because we know their addresses, for every device we know the address of the base address register. So for example, this GB land LMIO bar, it has a multiple MMI ranges, one of them is so-called MMIO bar A, M bar,
which is defined by the offset 10 hex, and the GB land device is the bus zero device 25, also 29, I think, function zero. So if the firmware can use two mechanisms, as Alex described, one is the legacy mechanism,
through the CF8, CFC, IO ports, and one is enhanced mechanism through the memory map, memory map config space. So the first mechanism used, and the address of that bar register for the first mechanism is calculated as device number, left shift 11 bits,
plus the offset, there's also, of course, bus number, left shift 15 bits, I think, in the function number, but in this case, bus zero and function zero. So we have an address of that register, which is pretty unique in a lot of cases,
when it's used with the legacy PCI config mechanism. And when you set enable bit for the PCI config cycle, which is bit 31, then you have eight and a C8 10. For the seven mile bar of GB LAN device. So for the second mechanism, it's calculated similarly.
So you have a memory map config space, divided into four kilobyte chunks for each bus device function, and the register is somewhere within the four kilobyte chunk for that particular device. And so you need to add a memory map config base address
of this memory map config space, and you need to add an offset. You need to find this four kilobyte chunk within the memory map config space, and then you need to find the register within that four kilobyte chunk. So you calculate the offset to that register pretty similarly, but remember that this mechanism
allows you to access all of the PCIe header, all of the four kilobytes of registers rather than a hundred 256 bytes of registers. So that's why you have C8 0 10 instead of C8 10 as in the previous. So you have a constant.
You have this total address in memory, physical address in memory for that particular bar. Now you can identify all the places where firmware uses that bar or reads that bar. Once you do that, once you do that, you can figure out if the firmware, how the firmware uses that bar.
Does it check that the address is somewhere else, or does it not? Right, so does it read or write to the registers in the bar? So this is the example for the Gblan MOA bar in the device 25. This is the first, we call it MBAR MOA, the yellow thing,
and the second, no sorry, the third access, the third constant, you can see F8 0 C8 0 CC. That's reading configuration register from the Gblan config space, but it's a different register. It's a bar management control status register.
So the bar itself is the F8 0 C8 0 10. That's one of the reds. And so that's where firmware reads the actual address of the bar. Now then, later on, you can see that the firmware
is actually writing or reading some registers in that bar. It's not very clear on this particular screenshot, so it's better to look at it at the next screenshot. Now you can see that the firmware is using that MOA range and bar range and writing some values.
There's writing some register that the attacker controls or writing some constant value, let's say this 7123, I don't know what that constant is, to the address or offset 32 decimal in this MBAR MMIO. So it's writing some values to the registers.
And so this is the, without actually checking, so there's no check for that MMIO range, whether it's overlaps with SMRAM or whether it's overlapping with something else. So there's no checking. So basically, by modifying MBAR in the config space
of that GVLAN device, you could potentially control where the SMI handler is writing data. This is another example for the USB MMIO bar. And it's pretty similar. So you calculate, oh great, I didn't actually put the actual final constant.
But you can see that there's a USB base address register is read from the offset 10 hex of the EHCI MMIO controller.
And then there are accesses to the offsets of that range, access to offset 20 at the bottom of the slide, where it flips the bits. It doesn't write controlled values, it just flips the bits. And this is also an example where in this assembly,
you don't see the actual constant, the actual full address in the memory map config space because the address is calculated. But you do see an address of the memory map config space, then you see the offset of the bar register.
So there are multiple ways to do that. So it also helps with finding those issues. It also helps to find the actual functions that read or write configuration space. So the first function on the left, it uses the legacy PCI configuration mechanism
through CF8CFC, you can see CF8CFC ports there. The bottom one is using extended mechanism, it uses memory map configuration access to read, write configuration registers. The right part is just an example how firmware uses that.
So you can see that it writes, it reads the register B8 in device 31 and then writes some value to that register, so read, modify, write. Yeah, it actually, yeah, it writes and then returns.
So basically what it's doing, it's clearing status bits, most likely. Thank you. So those were examples in the UFI firmware. Let's talk about those examples in the core bit. By now you probably understood that these issues are not really specific to the type of firmware used because those issues are depending
on the platform architecture. It's the firmware trying to communicate with the PCIe endpoint devices on the platform that adheres to PCIe architecture. So regardless of which type of firmware you have,
core bit or legacy BIOS or UFI-based BIOS, those issues might exist. So because we have a source code for core bit, and by the way, I just wanted to thank core bit team and Ron in particular for kind of working with us on this. So because we have a source code for core bit,
we can look at the source code. So in order to find those issues on core bit, you can do this. You can find the functions that read PCIe configuration registers as in the previous slides in the source code.
And then you can find functions that are writing to the memory map type ranges. So in particular in core bit, those are functions BCI read config 32 or BCI read config 16 to read the configuration registers. And then functions write 16 write 32 or read 16 read 32 in order to read or write memory mapped registers.
So in this particular case, you can see that the firmware is reading the MMI range from a integrated graphics device at offset 10 hex. And then it's writing some register to the PP control
offset of that range in the graphics range with a specific value which it's calculating before. Sometimes in the source code, obviously the developers are naming the bars with their names
as they defined in the platform specs or chip set specs or SOC specs. And so for example on Intel systems, you can find those access by just most of the bars by their names. Either RCBA or a spy bar, spy MMIO
or a PCI based address and so on. So you can look up the bar register names and just essentially just grab all the source code by the names. So that's a particular example in main board IO trap handler, SMI handler in Corbett.
So this SMI handler, it's not in software SMI handler so it's not the SMI handler that you would trigger by writing some value into the B2 register IO board. It's an SMI handler that is caused by the chip set on trapping of IO cycle to some other port.
It's called IO trap mechanism. Won't describe in details that mechanism but basically it's another way to trigger a lot of SMI handlers on the platforms. Probably the second most used mechanism to generate SMIs. And so what this SMI handler does,
it reads an MMI range base address from a device zero on bus one at offset 18 hex. It reads the address and then it's checking one register. It's called LVTMA BL mode level in that MMI range.
It checks whether the value is greater than 10 hex. If it is, then it tries to either decrease it. If it's less than F zero, then it tries to increase it. So what it's doing is essentially it's trying
to change the brightness and you probably don't see this. Yeah, so basically when you press the button on that Corbett system, it would generate an SMI and depending on which button you pressed, it decreases the brightness of the screen or increases the brightness of the screen.
So it does that by reading the contents of the register, incrementing or decrementing the contents of the register and then writing it back. So basically, potentially by pressing the button, you can, and overlapping that bar with something else like SM RAM, you can cause the SMI handler to override itself
and get the potentially memory corruption or code execution. Or the ring zero attacker might generate that SMI on your behalf without pressing the button. So another case in Corbett firmware
is another SMI handler. It's called backlight off, which is very similar, but it's triggered when you press the power button and the system goes to S5, soft shutdown. And so, SMIs are generated, the firmware takes control,
it needs to turn off devices, including it wants to turn off the brightness, not brightness, it needs to turn off this backlight to the screen. And so, I don't remember the specific system that this is my handler was on, but it's basically, what it's doing,
it's again, it's reading a register base, the base for the MMIO device, for the MMIO range of the integrated graphics device. And it also writes a different value to the same PP control register on entering S5.
So potentially by entering S5, you can control the value of the offset in the memory that you overlapped, well, in the memory that you overlapped with the graphics device at Myobar. Or the attacker, in this case, would need to simulate the S5 event, trigger event,
and prevent the system from going, actually, into the S5, but still causing the SMI handler by just directly calling that SMI handler. So, by now you might have figured that there are lots of moving parts in this type of bugs,
in this type of issues. There are limitations. The first limitation for the exploit is that the SMI handlers, or any other firm, is writing to specific offsets. So you don't really fully control the address, you don't have an arbitrary write primitive. You only control the base address plus the offset.
And the bars, like Alex mentioned, most of the bars are self-aligned, or size-aligned, so if you have a four kilobyte large bar, the MMI range, then it's aligned on a four kilobyte boundary.
This is not a requirement, this is, most of the platforms do that. But architecturally, PCI-SIG, PCI architecture, defined that the bars might be as small as 16 bytes and aligned at 16 bytes. So there might be MMI ranges
that are as small as 16 bytes, and you pretty much have a fine granularity of the address that you control. But for four kilobyte bytes, you have quite a few possibilities to override. But for larger bars, let's say 16 kilobytes, that becomes more difficult.
For bars that are even larger, like the graphics device bar, those bars are two megabyte large, or four megabyte large. You have a very few possibilities. And the exploit may not be able to control the values that are written, because the firmware or the SMI handlers
typically write specific values, or flip specific bits at those offsets, or even read a value, then modify it somehow and write, or read the value and write to some other register. So you may not, the exploit may not control the values.
Although as you saw for some MMI ranges, the exploit might control. So for example, in the variable writes example, you saw all the contents of the variable that you fully control. The other limitation is that
because those are memory mats, IO ranges, those are not regular memory, DRAM ranges, then that means that the firmware is actually implementing a protocol in a lot of cases. So it's not just writing, like I want to write zero to this offset, no. It usually implements some sort of protocol,
and protocol could be as simple as, read the value, if that value has some, if that register has specific value, or it's greater or less than something, then write to somewhere else. That's easily controllable, because you don't just reallocate the bar into memory,
you also create the contents in memory of all of the registers as if they were in the MMI range. So you can control that. But if the protocol is more complex, like for example, the firmware is issuing specific cycles on a specific bus, then it's typically writing to some registers,
then reading back other registers, pulling on the values in those registers, then writing something else. So in that case, you may not really be able to control that, because you only have one chance. You populated the fake MMI range in memory,
and if the firmware writes something and expects it to change, then you're out of luck, because you don't have any agents running in parallel. In certain cases, that might be bypassable in platforms, but in larger cases, you're out of luck in this case. So plus, there are lots of conditions.
The SMI handler will write to that bar, depending on, let's say, platform mode. Is, are we in a CPI mode or not? Is the device I'm communicating with supporting this functionality, this mode, or this feature, right? And plus, even triggering those SMIs
that communicate with the devices might even cause some complications, because it's not as just you trigger SMI through writing to port B2. No, those SMI handlers that you saw might be caused when you enter S3 or exit S3, resume from S3, or when you enter a soft shutdown or something like that. So kind of a complication on how you even trigger the interrupts.
So yeah, and for a certain number of bars that are non-architectural, basically they're not defined in the PCI compatible space, below 40 hex in the PCI header,
those bars might be locked down by the firmware. So there is a mechanism in the hardware that allows you to just lock down the register, and after you lock it down until reset, nobody can change. So you cannot, for those bars, you cannot relocate them. Of course, the firmware might forget to lock them down,
as we saw many times, but in that case, you can relocate even lockable bars. But if firmware doesn't forget to lock down all the bars, then you cannot relocate them to memory. You can relocate something else and overlap with the bar, but that's a different story. So what are the options for to mitigate those attacks?
One option is that the SMI handlers can verify that the address, base address of the MMI range that it read from the bar register doesn't overlap with SMRAM. That's a pretty straightforward mitigation, and it's similar to the mitigation that was done for the previous type of class of issues, the pointer bugs, and it should be done.
It doesn't hurt to really check the pointer that you're not writing to your own code. But it only solves the problem partially. It prevents you from overriding the contents of SMRAM, but it doesn't prevent you from pointing that address that you will write to,
to something else outside of SMRAM. Let's say hypervisor protected pages for Windows 10, VBS protected pages. So in that case, the mitigation might be a difference. The firmware and SMI handlers might verify that the base address of the MMI range is actually in the MMIO.
In the memory map that you saw from Alex's part of the presentation, it's above this top of low usable DRAM. So you can check that the bar is actually in that range, and not overlapping, not pointing somewhere inside the DRAM. That's a good mitigation,
although you still might be writing to somewhere you shouldn't have been able to write. So it's also partial mitigation, I think. So there is another option that the firmware and SMI handlers might do, is when the system boots, the boot firmware might allocate the default range,
the reserved range in the MMIO, and place all the bars there, and when the SMI handlers are invoked at runtime during the OS execution, then the SMI handler might check the value of the base address for the MMIO range, and check if it's within this default reserved range.
If it's not, force it into the default range, it's in its default location, and use the default location. And then upon exit, just restore the value, or leave it there. Depends on the firmware implementation. So in this case, you're just forcing
that the SMI handler runtime firmware will write to a new and good location, kind of fixed location for the MMIO. And that particular third mitigation was done for the spy bar example, with the arbitrary constants of the variable that could be written by the exploit.
So in that case, starting later, Skylake systems, I think the boot firmware allocates the range at FE01 and 40 zeroes in physical addressable space for the SPI MMIO range.
And so on any SMI, PCH type SMI, the chipset type SMI, the SMI handler checks that the base address of this SPI MMIO range is at that address. And if it's not, then it basically overrides it with the default FE01 value,
then the SMI handler proceeds doing what it needs to do. And basically kind of preventing you from overlapping the range with anything else that you shouldn't have access to. So that's kind of a screenshot
with this example of this mitigation. First, the attacker relocates the spy bar, overlaps it with something else, just regular DRM memory, then causes the variable write that generates an SMI.
And upon exit from the SMI, I'm just checking the value of the spy bar and you can see that it actually changed to its default location. So I'll basically try to show you that on the system.
You may not be able to see that on the back, but later on you can check. So I'm reading a offset 10 hex
and the device 31 function five, that's the SBI controller on later systems. So I'm reading in and you can see it has value FE0140.
On this laptop, the keyboard is typing numbers on its own without my help. So now we'll check just the number of SMIs. So you can see that 15 hex SMIs has been generated so far.
Then I'm relocating the bar. Yeah. So I'm, sorry, since I started showing that
with the individual commands. So I'm relocating the bar to this address which is in memory. Before the presentation I had prepared it and copied contents of the spy bar into that memory.
So, okay, checking the bar again. So you can see that it relocated now points the spy SBI memory map range and it points to DRM.
And then I'm writing contents of the variables. You can see that the write was successful even though the SMI handler should not have access to the spy controller in this case because I relocated to some bogus memory.
It's not a spy LMIO range anymore any longer. So it's already a sign that, hey, the attack didn't really succeed. Yeah. So I'm reading the contents of the bar again and you can see that it got restored
to the original location. I'm checking the value of the SMI and you saw 15 there now it's 19 hex. So you got four SMIs generated during this operation, one per logical CPU. And so I'm checking the contents of the bar.
So MMIO dump SBI bar and not at this address. I'll just dump it to somewhere here, SBI log. And you can see that the contents of the variable
that I wrote are actually in the MMIO range. So the variable that I wrote is this. It has all of the bees, so 42 hex. So that basically shows that this laptop,
this system restores the SBI MMIO range to default location and then only then proceeds to communicate with the SBI flash device. All right. So we will have a couple of tools
that can find those issues at runtime. Obviously you can proceed with the disassembling, the binaries or looking at the source code, but we will release a couple of tools that will help finding those issues.
So one is that just finds all of the registers that the SMI handlers writes to modify. And the other one is the one that attempts to actually relocate all the MMI ranges into memory, then fuzz SMIs and see if the memory contents changed.
None of these tools are perfect. They give false positives, false negatives. So it's more of a kind of a, they need to be complemented with manual analysis. So the root causes that of this type of issues is that the firmware assumes
that all of the hardware is trusted, including all of the registers in the configuration registers for all the hardware devices or the entire chip sets that are not modified by some malicious code, for example, lockdown. And so the firmware shouldn't assume
that the contents of the base address registers are immutable because any rings or code can modify most of them. And they can be relocated to anywhere in memory, including on top of the SM RAM itself. And so therefore kind of a check of the contents or addresses of those registers.
This problem is not specific to the SMM because the SMM, it's pretty obvious target here because there's a runtime firmware. But even the boot firmware that reads contents of some of the registers upon, let's say, resume from sleep using the boot script
or reads contents of the MMI ranges from somewhere else, like UFI variables. It also can be tricked into using memory ranges which are not really MMI ranges but something else and potentially can override its own code.
So the boot firmware should do the same thing as the runtime firmware. So I think that's all. We have a couple of minutes for questions. Thank you for listening.
Thanks guys for your talk. So you were talking about kind of with a goal in mind of getting code execution in the context of the SMI. But have you seen this type of attack utilized in a virtualized environment where if you're a guest in a hypervisor that's allowing pass through to PCI devices, causing relocation so that you
would overwrite into the host kernel or something like that to break out? Yeah, thanks Rach for the question. So we haven't verified all of the hypervisors but we have done some analysis on let's say VSM and when you are in Windows 10, normal world partition,
it allows you to write to the bar registers. So we have not done the full analysis of whether this can be used or cannot be used as an attack but at least the entry points are there.
And for other hypervisors, if that would be possible to use this type of attacks against the hypervisors, then that might be possible from administrative guests only, not from unprivileged guests. Okay and then one other quick question.
You were talking about a lot of the behavior in the SMIs is to do a read, modify, and write. So I was just thinking like this vector, if you had an offset into a kernel where you have a predictable increment of that counter, is there a way basically to block it and loop that increment in normal behavior? Does that make sense?
It does, I'm definitely not sure that there's a way to block it on the kernel level. But also I don't think you would attack the kernel itself with this because in the general case, you have to have an access to the PCI configuration space of the devices.
So in order to relocate the memory map to base addresses somewhere else in the memory. And that already assumes that you have right access to the PCI config space, which is ring zero in majority of the cases. So you wouldn't use this attack to attack kernel, I guess.
Well, I was thinking in the virtualized environment, but yeah. Oh yeah, okay. Yeah, thank you. On the virtualized environment, sorry. In the virtualized environment, the hypervisor might prevent, of course, the first way to prevent that is to not allow any guest.
including administrative guest from Not allowed to modify the base address of my arranges that's the first and Pretty straightforward and should be done But you can also monitor memory with With extended page tables and cause a PT violations on certain events, but that would be I guess performance heavy. I
Thanks for the interesting talks. I have a question regarding the relocation of the MMI bar
Register that you are talking about in the last slides you tell that some new SMI handler may verify the contact of the register and the restore it to the original location, right? but the sort of things that I have not understood is that the hardware as design a diesel for a reason that maybe some device can would like to
relocate the MMI O bar register for some reason of Adjusting the memory mapper register and my question is how can you recognize when it's legal to do that? Or it's not legal to that. I mean there is some way to trigger an SMI handler. That is an outdoor one from software
Let me see Andrea You had like multiple questions in the same in the same question, so is it legal to modify the
You know, which software legitimately can modify the base address registers for the for the MMI bars Generally PCI can PCI architecture allows a west you relocate MMI ranges any time and it anytime at once In a lot of cases. I don't think that happens often rather than when a west just you know bits, but
This is a PCI architectural Capability so that any operating system can relocate ranges because they need to do, you know devices may be added They have ranges and so they they should be able to relocate all the ranges
So I don't think there is a generic way to know where that where the you know, relocation of the ranges is legal or not Again with a virtualized environment you can prevent it at runtime exactly the last lattice mitigation that you show in your laptop you show that the
Mm. Mm. Hi-yo bar Register has been restored might and what I was one wondering In that case you can't do for each SMI and learn the same things because maybe someone needs to do legally Oh, okay. Yeah, I get it. So you cannot you cannot do the same mitigation for all the SMI handlers
That's that's that's your question. I I think you're correct that It's not a very generic mitigation And that's why there are like three options that you that that the firmware should consider and a kind of combination of those three options should
Be implemented I think but it also works for if you if you know because the SMI handlers are You know shouldn't be installed at runtime. They should be fixed. So, you know you know where each SMI handler is is Is that you know, which device it's communicating with which I own in my range it's
writing to or reading from and in that case it might be a Relatively generic mitigation because you know that in advance But yeah, I think it's a combination of three options that should be there yes, that's exactly the question, thank you
Hi, I had actually a suggestion maybe for Possible additional mitigation for some devices that Should not be normally located by those like the same as PI controller. Maybe the firmware could just stores the
bar and Not read it from the device each time Yep, except when you store the bar of the cache the value Let's say OS or exploit code relocates it You're still writing to your original Valley because you cached it and you're not using it not reading from the device
But then you are not really talking to the device, right? Yeah, the functionality is broken, but you don't care because this is an attack The trouble is it's not it's more than the functionality is broken. The the the exploit code might force you to Read writes to the cache location, which now might be used by something else
There's a potential for the issue here, that's why this option 3 is is more of a you you do cache that beforehand when the firmware boots, but you also force the the This default location into the actual registers. So you know that you are actually talking to the device as well. So yeah
All right. I think that's time for the next presenter. Yeah. Thank you