Baring the system: New vulnerabilities in SMM of Coreboot and UEFI based systems
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.
Bulygin, Yuriy
Bazhaniuk, Oleksandr
Furtak, Andrew
Loucaides, John
Gorobets, Mikhail
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.
 Hey guys, my name is Alex, here is Yuri. We are working on Advanced and Threat Research Team at Intel and we are here to present the new presentation, Bering the System, new vulnerabilities in Corbuth and UFI-based system. Before we go to the presentation, I want to say thank you to the organizers of Recon, Hugo Sam, NeoAsum, Recon Brussels, Asum. 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 Mapo-Dio, then description about MMIO bar overlap issue, examples of this issue in UFI, firmware and Corbuth 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. So what is a semi-poisoned point or bug? So in NIC-36 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 impression system allocates 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 reads that buffer and depends on functionality, it can read or write. In ADK 1, based on the buffer, the address of the buffer will pass through general purpose register, RBX. In ADK 2, there is a mechanism named combBuffer and the address of combBuffer is passing through UFI's API table. And in normal behavior, the address of this combBuffer 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 are write zeros. And then to make an exploit, we find the structure in CPU state, SMB register, and when we write this register, the next SMM 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 SMM handlers. So SMM handler check the address is not pointing to SMM. But what if we have scenario when we have hypervisor or for example hypervisor basis protection like VSM or just a hyperread with root partition. In this case, we can point the address in general purpose register or in combBuffer to some of the structure of the hypervisor and overwrite 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 gravity 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 used some firmware vulnerability to compromise VSM and dump credentials. We made this demo in 2015. And it was another example of SMI pointer vulnerability founded by ATR and then published by Sogeti as a club. The vulnerability is pretty similar that we found. So it reading the buffer from the general purpose registry, but the buffer to the function read flash data. And in the function read flash data using the function read and you control on the offset of the destination you control the source and the size. In this case, there is no checks where the address will be. So if you address is in the surround, you can dump and read and write SMM. Really nice write up. Also the material published many couple presentation, couple blog post about different type of SMM pointer vulnerabilities. So how the community and 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 through function SMM is buffer outside SMM valid. It 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 comb buffer address. So address now should be fixed and there is a CPI table, name Windows SMM mitigation CPI table, which is basically should be initialized by the firmware and read 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 defined 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 comb buffer, it checking this pointers as well. And another protection is that you have locked some of the configuration of the hardware after exit boot serve. And the exit boot services, for example, interrupt controller, IOMMU and so on. That kind of mitigation was added after we published this research and communicators and others. A little bit about MMO because this bug is really reliant to different behavior of the MMO. In the system to communicate to the device, there is a special express protocol and in this protocol, there is a fabrics which contain multiple components that 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 via PCI express link. Every physical component has up to eight virtual physical functions and all of them may integrate to the root complex. So basically, this protocol is aligned to talk to the device and send DMA and so on. Every device has PCI config space in the device and the PCI config space contain the header of the... The header then it contain the PCI 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 PCI configuration, there is two interfaces. One is to get access to PCI configuration space using port IO CFA, CRC. Then 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 CRC. We can read and write to specific register in PCI configuration. To get access to the extended configuration space, we need to use an enhanced configuration access mechanism. We just apply it as memory map. We basically use memory which is split by 4K by 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 are using MMU control memory map config register plus bus multiply 32 multiply 8 multiply 1k plus device multiply 8 multiply 1k plus function plus offset. Then we construct the address, then we use it as a memory access and we can read and write register. So there basically all of that configuration, all of that PCI configuration is for storing some configuration register 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 the MMO became. So the MMO 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 MMO bars. And MMO bars is in PCI config space which we are talking in previous slide. And if you see like there is a header of the PCI configuration space and there is device ID, there is vendor ID, status register, some other register and then the base under zero is the first MMO 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 base which didn't flip from zero to one is the base which defined the size of the MMO bar. For example, if there is one byte, didn't flip, then meaning that you have the 256 size of the bar, 256 byte. There is the simplified version of the layout in the memory just to get the small representation of where is MMO is. So we have a loader arm, then there is SMM protected by SMRRs and there is a graphic memory. Then we have Tolloot and there is a memory map config. Then there is loader arm with all of the bar which was defined through PCI config space. And there is a direct map and BIOS and there we have high gerund. So all of the bars should be defined somewhere here. And here is a couple of examples of the MMO bars. There is the name of the bar, like GTT MMO other which has the address of 0,0,0,2,0,10 with 10 is offset and then it has the size, the two megabytes. So all of them is you can use a chip seg tool to just run MMO list and then write the known PCIe bars, MMO bars, sorry. So one of the important aspects of the MMO range registry, MMO bars is that they can be reallocatable at runtime and OS can relocate them to any other location. Some of the MMO bars is not reallocatable. They are fixed or locket by the firmware but some of them are reallocated. 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. I guess the difference between PowerPoint and PowerPoint Viewer. Anyway, so how is that related to what Alex has been talking about? These issues are dependent on this memory mapped IE configuration behavior. In fact they are kind of caused by the way firmware talks to the devices through the memory mapped IE. So the way firmware uses this memory mapped IE 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, UFI based firmware or core boot based firmware or just legacy bias or anything else also talks to the devices through the memory mapped IE mechanism. So there is a PCI configuration space in each device or actually each virtual device or a function of a device PCI configurator and it has this base address register which defines the base of the memory range for that particular device. And so what usually SMI handlers do as well as any other boot firmware, they get the base register, they read the base register to get the base address of this SMI range and then they either read registers within that range, SMI 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 are 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 is 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 or west 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 the string zero code or west level code can modify those bar registers and relocate the range for a particular device somewhere else in physical address addressable space. It could be somewhere in other MMO. 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 map to a range to overlap with the SMRAM. Then when SMI interrupt is generated either by hardware or by the attack code itself, the SMI handler firmware attempts to communicate with the device through this memory map to a range. Attempts to read registers or write registers. And so basically instead of actually sending cycles to the device as MMO 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 attack code relocated this MMO range. So that potentially can either expose data because it reads its own memory or basically modify the control flow somehow if it reads some attacker manipulated data or it can potentially corrupt the memory because of the memory write cycles to the MMO registers. So that's the theory of this problem. And what we've observed in multiple types of firmware including UFI and Corbett firmware are is that the SMI handlers communicate with a lot of MMO bars. My examples include EHCI USB2 bars, Gigabit Ethernet LAN, root complex MMO, that's the main MMO for the PCIHS. Or specifically the SPI registers, then basically in order to communicate with the SPI flash, write to the SPI flash or read from the SPI flash. HCI SATA controller MMO, XHCI USB3 controller, integrated graphics device MMO basically GTT MMADR range for the graphics device. Or some other MMOs like for example the I think it's a LID controller or something 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 SPI flash. So there's a command basically, the first command is attempting to store a persistent configuration for the UFI firmware into the SPI flash. It's called UFI 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. 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 memory range with something else like the SMRAM 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 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 registers changed in the SMI. And now you know that the SMI handler modified those registers. And 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 ever, 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 of 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 SMI bar. 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 issues. So now I'll give you a few examples of those issues in UFI firmware as well as in Corbwood. So we'll start with the UFI. So how do we find those issues in the binary? Let's say we have EFI binaries, we load them in EIDA, 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 reads the contents of the base address register. Because we know their addresses, for every device we know the address of the base address register. So for example, this GBE LAN MMO bar, it has multiple MMO ranges, one of them is so-called MMO bar A, M-bar, which is defined by the offset 10 hex. And the GBE LAN device is the bus zero device 25, also 29, I think, function zero. So the firmware can use two mechanisms, as Alex described. One is the legacy mechanism through the CFA, CFC, IO ports, and one is enhanced mechanism through the memory map config space. So the first mechanism used in 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, and 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 access mechanism. And when you set enable bit for the PCI config cycle, which is bit 31, then you have eight and C8, 10 for the semi-bar of GBE 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. And remember that this mechanism allows you to access all of the PCI header, all of the four kilobytes of registers, rather than 100 to 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 how the firmware uses that bar. Does it check that the address is somewhere else or does it not? So does it read or write to the registers in the bar? So this is the example for the GB LAN MOU bar in the device 25. This is the first, we call it M-bar, M-M-I-O, the yellow thing. And the second, no, sorry, the third access, the third constant, you can see F80C80CC. That's reading configuration register from the GB LAN config space, but it's a different register. It's a bar management control status register. So the bar itself is the F80C010. That's one of the reds. And so that's where a firmware reads the actual address of the bar. And 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 the next screenshot. Now you can see that the firmware is using that M-M-I-O range, M-bar-O range, and writing some values. There is 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 edges or offset 32 decimal in this M-bar M-M-I-O. So it's writing some values to the registers. And so this is the, without actually checking, so there's no check for that M-M-I-O range, whether it overlaps with SMRAM or whether it's overlapping with something else. So there's no checking. So basically by modifying M-bar in the config space of that GB LAN device, you could potentially control where the SMI handler is writing data. This is another example for the USB M-M-I-O 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 is a USB base address register is read from the offset 10 hex of the EHCI M-M-I-O 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 control values, it just flips the bits. And this is also an example where in this assembly you don't see the actual constant, the 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 CFA TFC. You can see CFA TFC 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 of 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 it reads modify write. Yeah, it actually, yeah, it writes and then returns. So basically what it's doing, it's clearing status bits, most likely. 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 PCIe, on the platform that adheres to PCIe architecture. So regardless of which type of firmware you have, core boot or legacy BIOS or UFI based BIOS, those issues might exist. So because we have a source code for core boot, and by the way, I just wanted to thank the core boot team and Ron in particular for working with us on this. So because we have a source code for core boot, we can look at the source code. So in order to find those issues on core boot, 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 to your ranges. So in particular in core boot, those are functions PCIe read config 32 or PCIe 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 PPControl 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 chipset specs or SOC specs. And so for example, on Intel systems, you can find those accesses by just most of the bars by their names, either our CBA or spy bars by MMI or PCIe 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 mainboard IO trap handler, SMI handler in core boot. 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 chipset on trapping of IO cycle to some other port. It's called IO trap mechanism. I 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 based address from a device 0 on bus 1, it 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 F0, 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. So basically when you press the button on that core boot 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 SMM 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 is a core bit firmer, 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 firmer takes control, it needs to turn off devices, including it wants to turn off the brightness, not brightness, it needs to turn off the backlight to the screen. And so I don't remember the specific system that this SMI handler was on, but basically what it's doing, it's again, it's reading a register base, the base for the MMO range of the integrated graphics device, and it also writes a different value to the same PPControl 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 my bar, 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 cards 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 firmware is writing to specific offsets. So you don't really control, 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. And 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 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 model or the SMI handler typically writes specific values or flips 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 maps, 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, you know, 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 relocate 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. Are we in the ACPI mode or not? Is the device I'm communicating with supporting this functionality, this mode or this feature? And plus, even triggering those SMIs that communicate with the devices might even cause some complications because it's not as just the trigger SMI 3 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 shut down 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 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 overwriting the contents of SMRAM, but it doesn't prevent you from pointing that address that you will write to something else outside of SMRAM. Let's say hypervisor protected pages or Winner-Stan, VBS protected pages. So in that case, the mitigation might be a difference. The firmware and SMI handlers might verify that the address, 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 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 reserve 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 MMI range and check if it's within this default reserve range. If it's not forced 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. It depends on the firmware implementation. In this case, you're just forcing that the SMI handler runtime firmware will write to a known 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 40s 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 perceives 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 SPI 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 SPI bar and you can see that it actually changed to the default location. So I'll basically try to show you that on this system. You may not be able to see that on the back, but you can later on, you can use that. You can check. So I'm reading a offset 10 hex and the device 31 function 5, that's the SPI controller on later systems. So I'm reading 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. You can see that 15 hex SMIs has been generated so far. Then I'm relocating the bar. Yeah. Sorry, since I started it, showing that with the individual commands. So I'm relocating the bar to this address, which is in memory. For the presentation, I've prepared it and copied the contents of the SPI bar into that memory. So checking the bar again, so you can see that it relocated now points to SPI, SPI memory map range now 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 this SPI controller in this case, because I relocated to some bogus memory. It's not a SPI and OMI range anymore, no longer. So it's already assigned that the attack didn't really succeed. 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 SPI bar, and not at this address. I'll just dump it to somewhere here, SPI log. And you can see that the contents of the variable that I wrote are actually in the MMI range. So the variable that I wrote is this. It has all of the Bs, so 42 hex. So that basically shows that this laptop, this system, restores the SPI MMI range to default location, and then only then proceeds to communicate with the SPI flash device. All right, so we will have a couple of tools that can find those issues at runtime. Obviously you can proceed with 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 handler writes to, modify, and the other one is the one that attempts to actually relocate all the MMI ranges into memory, then files the 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, they need to be complemented with manual analysis. So the root causes 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 chipset 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 SMRM itself. And so therefore kind of check 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 minutes for questions. Thank you for listening. Hello. Thanks guys for your talk. So you were talking about kind of with the goal in mind of getting code execution in the context of the SMI. Have you seen this type of attack utilized in the virtualized environment where if you're a guest and 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 it 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 would have a predictable increment of that counter, is there a way basically to block it and loop that increments in normal behavior? Does that make sense? It does. I definitely not sure that there is 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 mapped base addresses somewhere else in the memory. And that already assumes that you have write access to the PCI config space, which is bring zero in majority of the cases. So you wouldn't use this attack to attack kernel, I guess. Right. Well, I was thinking in the virtualized environment. But yes. Oh, yeah. Okay. So 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 allow to modify the base address of MI ranges. That's the first and pretty straightforward and should be done. But you can also monitor memory with extended page tables and cause a bit of violations on certain events. But that would be, I guess, performance heavy. Hi. 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 told that some new SMI handler may verify the contact of the register and restore it to the original location, right? But the sort of things that I have not understood is that the hardware has designed this for a reason that maybe some device would like to relocate the MMI bar register for some reason of accessing the memory map register. And my question is, how can you recognize when it's legal to do that or it's not legal to do that? I mean, there is some way to trigger an SMI handler that is an hardware one from software. Let me see, Andrea. You had multiple questions in the same question. So is it legal to modify the, you know, which software legitimately can modify the base address registers for the MMI bars? Exactly. Generally, PCI architecture allows OS to relocate MMI ranges any time at once. In a lot of cases, I don't think that happens often rather than when OS just, you know, bits. So 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 should be able to relocate all the ranges. So I don't think there is a generic way to know where the, you know, relocation of the ranges is legal or not. Again with a virtualized environment, you can prevent it at runtime. Actually, the latest mitigation that you show in your laptop, you show that the MMI bar register has been restored. Right. And what I was wondering, in that case, you can't do for each SMI handler the same things because maybe someone needs to do legally. Oh, okay. Yeah, I get it. So you cannot do the same mitigation for all the SMI handlers. That's your question. I think you're correct that it's not a very generic mitigation. And that's why there are like three options 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 know, because the SMI handlers shouldn't be installed at runtime, they should be fixed. So you know where each SMI handler is, which device it's communicating with, which MMI 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. Thanks. I had actually a suggestion maybe for possible additional mitigation for some devices that should not be normally located by the US like the same SPI controller. Maybe the firmware could just store the bar and not read it from the device each time. Yeah, except when you store the bar, the cash develop, let's say a OS or exploit code relocates it. You're still writing to your original value because you cashed it and you're not using it, not reading from the device. But then you're not really talking to the device, right? I see. Yeah, the functionality is broken, but you don't care because this is an attack. The trouble is it's more than the functionality is broken. The exploit code might force you to read writes to the cash location which now might be used by something else. So there's a potential for the issue here. That's why this option three is more of a you do cash that beforehand when the firmware boots, but you also force this default location into the actual registers so you know that you're actually talking to the device as well. All right, I think that's time for the next presenter. Thank you.
 Hey guys, my name is Alex, here is Yuri.  We are working on Advanced and Threat Research Team at Intel and we are here to present the  new presentation, Bering the System, new vulnerabilities in Corbuth and UFI-based system.  Before we go to the presentation, I want to say thank you to the organizers of Recon,  Hugo Sam, NeoAsum, Recon Brussels, Asum.  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 Mapo-Dio,  then description about MMIO bar overlap issue, examples of this issue in UFI, firmware and  Corbuth 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.  So what is a semi-poisoned point or bug?  So in NIC-36 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 impression system allocates 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 reads  that buffer and depends on functionality, it can read or write.  In ADK 1, based on the buffer, the address of the buffer will pass through general purpose  register, RBX.  In ADK 2, there is a mechanism named combBuffer and the address of combBuffer is passing through  UFI's API table.  And in normal behavior, the address of this combBuffer 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 are write zeros.  And then to make an exploit, we find the structure in CPU state, SMB register, and when we write  this register, the next SMM 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 SMM handlers.  So SMM handler check the address is not pointing to SMM.  But what if we have scenario when we have hypervisor or for example hypervisor basis  protection like VSM or just a hyperread with root partition.  In this case, we can point the address in general purpose register or in combBuffer to  some of the structure of the hypervisor and overwrite 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 gravity 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 used some firmware vulnerability  to compromise VSM and dump credentials.  We made this demo in 2015.  And it was another example of SMI pointer vulnerability founded by ATR and then published  by Sogeti as a club.  The vulnerability is pretty similar that we found.  So it reading the buffer from the general purpose registry, but the buffer to the function  read flash data.  And in the function read flash data using the function read and you control on the offset  of the destination you control the source and the size.  In this case, there is no checks where the address will be.  So if you address is in the surround, you can dump and read and write SMM.  Really nice write up.  Also the material published many couple presentation, couple blog post about different type of SMM  pointer vulnerabilities.  So how the community and 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 through function SMM is buffer outside SMM valid.  It 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 comb buffer address.  So address now should be fixed and there is a CPI table, name Windows SMM mitigation  CPI table, which is basically should be initialized by the firmware and read 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 defined 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 comb buffer, it checking this pointers  as well.  And another protection is that you have locked some of the configuration of the hardware  after exit boot serve.  And the exit boot services, for example, interrupt controller, IOMMU and so on.  That kind of mitigation was added after we published this research and communicators  and others.  A little bit about MMO because this bug is really reliant to different behavior of the  MMO.  In the system to communicate to the device, there is a special express protocol and in  this protocol, there is a fabrics which contain multiple components that 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 via PCI express link.  Every physical component has up to eight virtual physical functions and all of them may integrate  to the root complex.  So basically, this protocol is aligned to talk to the device and send DMA and so on.  Every device has PCI config space in the device and the PCI config space contain the header  of the...  The header then it contain the PCI 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 PCI configuration, there is two interfaces.  One is to get access to PCI configuration space using port IO CFA, CRC.  Then 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 CRC.  We can read and write to specific register in PCI configuration.  To get access to the extended configuration space, we need to use an enhanced configuration  access mechanism.  We just apply it as memory map.  We basically use memory which is split by 4K by 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 are using MMU control memory map config register plus bus multiply  32 multiply 8 multiply 1k plus device multiply 8 multiply 1k plus function plus offset.  Then we construct the address, then we use it as a memory access and we can read and  write register.  So there basically all of that configuration, all of that PCI configuration is for storing  some configuration register 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 the MMO became.  So the MMO 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 MMO bars.  And MMO bars is in PCI config space which we are talking in previous slide.  And if you see like there is a header of the PCI configuration space and there is device  ID, there is vendor ID, status register, some other register and then the base under zero  is the first MMO 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 base which didn't flip from zero to one is  the base which defined the size of the MMO bar.  For example, if there is one byte, didn't flip, then meaning that you have the 256 size  of the bar, 256 byte.  There is the simplified version of the layout in the memory just to get the small representation  of where is MMO is.  So we have a loader arm, then there is SMM protected by SMRRs and there is a graphic memory.  Then we have Tolloot and there is a memory map config.  Then there is loader arm with all of the bar which was defined through PCI config space.  And there is a direct map and BIOS and there we have high gerund.  So all of the bars should be defined somewhere here.  And here is a couple of examples of the MMO bars.  There is the name of the bar, like GTT MMO other which has the address of 0,0,0,2,0,10  with 10 is offset and then it has the size, the two megabytes.  So all of them is you can use a chip seg tool to just run MMO list and then write the known  PCIe bars, MMO bars, sorry.  So one of the important aspects of the MMO range registry, MMO bars is that they can  be reallocatable at runtime and OS can relocate them to any other location.  Some of the MMO bars is not reallocatable.  They are fixed or locket by the firmware but some of them are reallocated.  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.  I guess the difference between PowerPoint and PowerPoint Viewer.  Anyway, so how is that related to what Alex has been talking about?  These issues are dependent on this memory mapped IE configuration behavior.  In fact they are kind of caused by the way firmware talks to the devices through the  memory mapped IE.  So the way firmware uses this memory mapped IE 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, UFI based  firmware or core boot based firmware or just legacy bias or anything else also talks to  the devices through the memory mapped IE mechanism.  So there is a PCI configuration space in each device or actually each virtual device or  a function of a device PCI configurator and it has this base address register which defines  the base of the memory range for that particular device.  And so what usually SMI handlers do as well as any other boot firmware, they get the base  register, they read the base register to get the base address of this SMI range and then  they either read registers within that range, SMI 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 are 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 is 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 or west 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 the string zero code or west level code can modify those bar registers  and relocate the range for a particular device somewhere else in physical address addressable  space.  It could be somewhere in other MMO.  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 map to a range to overlap with  the SMRAM.  Then when SMI interrupt is generated either by hardware or by the attack code itself,  the SMI handler firmware attempts to communicate with the device through this memory map to  a range.  Attempts to read registers or write registers.  And so basically instead of actually sending cycles to the device as MMO 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 attack code relocated this MMO range.  So that potentially can either expose data because it reads its own memory or basically  modify the control flow somehow if it reads some attacker manipulated data or it can potentially  corrupt the memory because of the memory write cycles to the MMO registers.  So that's the theory of this problem.  And what we've observed in multiple types of firmware including UFI and Corbett firmware  are is that the SMI handlers communicate with a lot of MMO bars.  My examples include EHCI USB2 bars, Gigabit Ethernet LAN, root complex MMO, that's the  main MMO for the PCIHS.  Or specifically the SPI registers, then basically in order to communicate with the SPI flash,  write to the SPI flash or read from the SPI flash.  HCI SATA controller MMO, XHCI USB3 controller, integrated graphics device MMO basically GTT  MMADR range for the graphics device.  Or some other MMOs like for example the I think it's a LID controller or something 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 SPI flash.  So there's a command basically, the first command is attempting to store a persistent  configuration for the UFI firmware into the SPI flash.  It's called UFI 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.  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 memory range with something else like the SMRAM 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 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 registers changed in the  SMI.  And now you know that the SMI handler modified those registers.  And 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 ever, 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 of 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 SMI bar.  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 issues.  So now I'll give you a few examples of those issues in UFI firmware as well as in Corbwood.  So we'll start with the UFI.  So how do we find those issues in the binary?  Let's say we have EFI binaries, we load them in EIDA, 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 reads the contents of the base address register.  Because we know their addresses, for every device we know the address of the base address  register.  So for example, this GBE LAN MMO bar, it has multiple MMO ranges, one of them is so-called  MMO bar A, M-bar, which is defined by the offset 10 hex.  And the GBE LAN device is the bus zero device 25, also 29, I think, function zero.  So the firmware can use two mechanisms, as Alex described.  One is the legacy mechanism through the CFA, CFC, IO ports, and one is enhanced mechanism  through the memory map config space.  So the first mechanism used in 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, and 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 access mechanism.  And when you set enable bit for the PCI config cycle, which is bit 31, then you have eight  and C8, 10 for the semi-bar of GBE 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.  And remember that this mechanism allows you to access all of the PCI header, all of the  four kilobytes of registers, rather than 100 to 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 how the firmware uses that bar.  Does it check that the address is somewhere else or does it not?  So does it read or write to the registers in the bar?  So this is the example for the GB LAN MOU bar in the device 25.  This is the first, we call it M-bar, M-M-I-O, the yellow thing.  And the second, no, sorry, the third access, the third constant, you can see F80C80CC.  That's reading configuration register from the GB LAN config space, but it's a different  register.  It's a bar management control status register.  So the bar itself is the F80C010.  That's one of the reds.  And so that's where a firmware reads the actual address of the bar.  And 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 the next screenshot.  Now you can see that the firmware is using that M-M-I-O range, M-bar-O range, and writing  some values.  There is 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 edges or offset 32 decimal in this  M-bar M-M-I-O.  So it's writing some values to the registers.  And so this is the, without actually checking, so there's no check for that M-M-I-O range,  whether it overlaps with SMRAM or whether it's overlapping with something else.  So there's no checking.  So basically by modifying M-bar in the config space of that GB LAN device, you could potentially  control where the SMI handler is writing data.  This is another example for the USB M-M-I-O 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 is a USB base address register is read from the offset 10 hex of  the EHCI M-M-I-O 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 control values, it just flips the bits.  And this is also an example where in this assembly you don't see the actual constant,  the 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  CFA TFC.  You can see CFA TFC 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 of 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 it reads modify write.  Yeah, it actually, yeah, it writes and then returns.  So basically what it's doing, it's clearing status bits, most likely.  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 PCIe, on  the platform that adheres to PCIe architecture.  So regardless of which type of firmware you have, core boot or legacy BIOS or UFI based  BIOS, those issues might exist.  So because we have a source code for core boot, and by the way, I just wanted to thank  the core boot team and Ron in particular for working with us on this.  So because we have a source code for core boot, we can look at the source code.  So in order to find those issues on core boot, 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 to your ranges.  So in particular in core boot, those are functions PCIe read config 32 or PCIe 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 PPControl 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 chipset specs or SOC specs.  And so for example, on Intel systems, you can find those accesses by just most of the  bars by their names, either our CBA or spy bars by MMI or PCIe 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 mainboard IO trap handler, SMI handler in core boot.  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 chipset on trapping of IO cycle to some other port.  It's called IO trap mechanism.  I 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 based address from a device 0  on bus 1, it 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 F0, 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.  So basically when you press the button on that core boot 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 SMM 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 is a core bit firmer, 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 firmer takes control, it needs to turn off devices, including  it wants to turn off the brightness, not brightness, it needs to turn off the backlight to the screen.  And so I don't remember the specific system that this SMI handler was on, but basically  what it's doing, it's again, it's reading a register base, the base for the MMO range  of the integrated graphics device, and it also writes a different value to the same  PPControl 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 my  bar, 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 cards 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 firmware is  writing to specific offsets.  So you don't really control, 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.  And 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 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  model or the SMI handler typically writes specific values or flips 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 maps, 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, you know, 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 relocate 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.  Are we in the ACPI mode or not?  Is the device I'm communicating with supporting this functionality, this mode or this feature?  And plus, even triggering those SMIs that communicate with the devices might even cause  some complications because it's not as just the trigger SMI 3 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 shut down 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 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 overwriting the contents of SMRAM, but it doesn't prevent you from  pointing that address that you will write to something else outside of SMRAM.  Let's say hypervisor protected pages or Winner-Stan, VBS protected pages.  So in that case, the mitigation might be a difference.  The firmware and SMI handlers might verify that the address, 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  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 reserve 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 MMI range and check if it's within  this default reserve range.  If it's not forced 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.  It depends on the firmware implementation.  In this case, you're just forcing that the SMI handler runtime firmware will write to  a known 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 40s 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 perceives 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 SPI 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 SPI bar and you can see that  it actually changed to the default location.  So I'll basically try to show you that on this system.  You may not be able to see that on the back, but you can later on, you can use that.  You can check.  So I'm reading a offset 10 hex and the device 31 function 5, that's the SPI controller on  later systems.  So I'm reading 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.  You can see that 15 hex SMIs has been generated so far.  Then I'm relocating the bar.  Yeah.  Sorry, since I started it, showing that with the individual commands.  So I'm relocating the bar to this address, which is in memory.  For the presentation, I've prepared it and copied the contents of the SPI bar into that  memory.  So checking the bar again, so you can see that it relocated now points to SPI, SPI memory  map range now 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 this SPI controller in this case, because I relocated to some bogus memory.  It's not a SPI and OMI range anymore, no longer.  So it's already assigned that the attack didn't really succeed.  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 SPI bar, and not at this address.  I'll just dump it to somewhere here, SPI log.  And you can see that the contents of the variable that I wrote are actually in the MMI range.  So the variable that I wrote is this.  It has all of the Bs, so 42 hex.  So that basically shows that this laptop, this system, restores the SPI MMI range to  default location, and then only then proceeds to communicate with the SPI flash device.  All right, so we will have a couple of tools that can find those issues at runtime.  Obviously you can proceed with 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 handler writes to, modify, and  the other one is the one that attempts to actually relocate all the MMI ranges into memory,  then files the 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, they need to be complemented with manual analysis.  So the root causes 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 chipset 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 SMRM itself.  And so therefore kind of check 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 minutes for questions.  Thank you for listening.  Hello.  Thanks guys for your talk.  So you were talking about kind of with the goal in mind of getting code execution in the  context of the SMI.  Have you seen this type of attack utilized in the virtualized environment where if you're  a guest and 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 it 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  would have a predictable increment of that counter, is there a way basically to block  it and loop that increments in normal behavior?  Does that make sense?  It does.  I definitely not sure that there is 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 mapped base addresses somewhere else in the memory.  And that already assumes that you have write access to the PCI config space, which is bring  zero in majority of the cases.  So you wouldn't use this attack to attack kernel, I guess.  Right.  Well, I was thinking in the virtualized environment.  But yes.  Oh, yeah.  Okay.  So 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 allow to modify  the base address of MI ranges.  That's the first and pretty straightforward and should be done.  But you can also monitor memory with extended page tables and cause a bit of violations  on certain events.  But that would be, I guess, performance heavy.  Hi.  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 told that some new SMI handler may verify the contact of the register and restore it  to the original location, right?  But the sort of things that I have not understood is that the hardware has designed this for  a reason that maybe some device would like to relocate the MMI bar register for some  reason of accessing the memory map register.  And my question is, how can you recognize when it's legal to do that or it's not legal  to do that?  I mean, there is some way to trigger an SMI handler that is an hardware one from software.  Let me see, Andrea.  You had multiple questions in the same question.  So is it legal to modify the, you know, which software legitimately can modify the base address  registers for the MMI bars?  Exactly.  Generally, PCI architecture allows OS to relocate MMI ranges any time at once.  In a lot of cases, I don't think that happens often rather than when OS just, you know,  bits.  So 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  should be able to relocate all the ranges.  So I don't think there is a generic way to know where the, you know, relocation of the  ranges is legal or not.  Again with a virtualized environment, you can prevent it at runtime.  Actually, the latest mitigation that you show in your laptop, you show that the MMI bar  register has been restored.  Right.  And what I was wondering, in that case, you can't do for each SMI handler the same things  because maybe someone needs to do legally.  Oh, okay.  Yeah, I get it.  So you cannot do the same mitigation for all the SMI handlers.  That's your question.  I think you're correct that it's not a very generic mitigation.  And that's why there are like three options 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 know, because the SMI handlers shouldn't be installed at  runtime, they should be fixed.  So you know where each SMI handler is, which device it's communicating with, which MMI  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.  Thanks.  I had actually a suggestion maybe for possible additional mitigation for some devices that  should not be normally located by the US like the same SPI controller.  Maybe the firmware could just store the bar and not read it from the device each time.  Yeah, except when you store the bar, the cash develop, let's say a OS or exploit code relocates  it.  You're still writing to your original value because you cashed it and you're not using  it, not reading from the device.  But then you're not really talking to the device, right?  I see.  Yeah, the functionality is broken, but you don't care because this is an attack.  The trouble is it's more than the functionality is broken.  The exploit code might force you to read writes to the cash location which now might  be used by something else.  So there's a potential for the issue here.  That's why this option three is more of a you do cash that beforehand when the firmware  boots, but you also force this default location into the actual registers so you know that  you're actually talking to the device as well.  All right, I think that's time for the next presenter.  Thank you.
recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_0_71.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_72_119.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_120_167.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_168_215.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_216_263.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_264_311.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_312_1271.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_1272_1415.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_1416_1631.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_1632_2015.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_2016_2123.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_2124_2171.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_2172_2255.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_2256_6899.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_6900_7271.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_7272_8663.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_8664_11147.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_11148_11195.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_11196_11363.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_11364_13223.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_13224_15167.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_15168_17603.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_17604_18443.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_18444_18863.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_18864_19187.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_19188_19787.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_19788_19859.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_19860_20087.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_20088_20435.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_20436_20507.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_20508_20711.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_20712_20759.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_20760_20915.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_20916_21035.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_21036_21359.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_21360_22019.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_22020_27263.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_27264_28847.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_28848_29363.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_29364_32255.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_32256_36515.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_36516_36575.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_36576_36683.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_36684_36731.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_36732_36791.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_36792_36851.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_36852_38087.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_38088_43367.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_43368_48551.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_48552_50183.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_50184_50423.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_50424_51047.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_51048_51191.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_51192_54287.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_54288_57899.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_57900_68951.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_68952_71675.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_71676_71723.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_71724_72443.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_72444_75479.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_75480_75539.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_75540_75803.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_75804_76235.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_76236_76451.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_76452_76547.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_76548_76859.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_76860_76979.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_76980_77279.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_77280_77567.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_77568_77891.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_77892_77951.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_77952_78071.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_78072_78191.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_78192_78239.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_78240_78299.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_78300_78491.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_78492_78563.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_78564_78683.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_78684_78767.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_78768_79127.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_79128_79223.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_79224_79295.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_79296_80375.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_80376_80579.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_80580_80807.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_80808_81371.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_81372_81419.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_81420_82871.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_82872_85151.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_85152_85211.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_85212_98327.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_98328_98519.png recon2017-brx-19-yuriy-bulygin-oleksandr-bazhaniuk-Baring-the-system--New-vulnerabilities-in-SMM-of-_98520_98608.png