A tl;dr summary on System Management Mode (SMM), light covering hardware backdoors. Check out www.c7zero.info
This all started with a blog post on building a reliable SMM backdoor, but went into a rabbit hole. These were my notes when reading into it.
My understanding of sitting in SMM is:
- System Management Mode (SMM) “pauses” the OS, then runs its own code
- Pause - Comes as a ‘System Management Interrupt (SMI)’, highest priority, can’t be masked
- Copied into memory at power-on(DXE phase? PEI?), then locked to SMM only use (D_LCK)
- Internals: Theres a internal-only CPU register for SMBASE (Where SMM code gets stored)
- You’ve got full read/write of all memory (just swap from real to long mode)
- Theres no way of picking this up (in memory, at least) from the OS
Summarised: It’s a pretty good place to sit in, you’re not going to be observed when running.
In terms of when it spins up:
- UEFI has 3 boot phases (SEC, PEI, DXE)
- SEC(urity) - Verify components, four responsibilities
- handle boot/restart event - (There’s a bunch of bugs in S3 resume, leading to some cool bugs)
- create temporary memory map using cpu registers - Cache-As-Ram
- start Root of Trust
- hand pointers to PEI
- PEI (Pre-EFI initialisation) - goal is to initialise memory for DXE phase
- Uses PEI Modules (PIEM)
- These are stored in Flash (Flash file system)
- PIEMs are PE’s or TE’s (Smaller, and also has a VZ header rather than MZ header)
- Describing memory in Hand Off Blocks (HOBS) - describes firmware volume (PI FFS, has a guid, linked to a DXE Driver)
- Notably, this also handles resuming from S3
- DXE (Driver Execution Environment) - SMM starts here!
- Initialise system components (Chipsets, add-on cards), then hand over to an Architecture Protocol (i.e. boot selection)
- 3 elements, DXE core, DXE Services, DXE Dispatcher
- DXE Core - produce the boot runtime (DXE Services), populate EFI system table, create handle database
- DXE Services - Consume HOBS, creates Architecture Protocol (Boot selection)
- DXE Dispatcher - Ties a HOB(’s GUID) to a DXE driver, which will then boot the driver
- Pretend the DXE phase is an Option ROM in legacy bios
- This is a good place for persistence :)
Unrelated to this, the rest of the UEFI booting seems to be:
- BDS/TSL/RT
- BDS (Boot Device Selection) is where you could consider the human interacts - (ie, a boot menu/setup menu)
- if BDS fails, it’ll go back to DXE and look for different HOBs to try
- TSL (Transient System Load) - ie, EFI shell, or OS bootloader runs here. These are generally EFI applications, stored under
/EFI/BOOT/BOOT
- RT (Runtime) - OS executed, provide services to OS for UEFI management/runtime (Will call ExitBootServices() at this point)
Deploying things to the actual host:
- Flash to SPI, physical access (chip programmer, et al)
- Firmware ‘upgrade’ (code signing might stop this?)
- According to a 2017 paper Discovering Vulnerable UEFI firmware at scale, code signing (on UEFI) isn’t really used on a sizeable number of systems (or system flash is writeable by software, or will let you write over SPI)
- Sample size was 32987 UEFI packages, with 21204 unique UEFI images (~3417 images were vulnerable)
Unsure when to detect this kind of thing - If you’re lucky you might be able to dump UEFI out of SPI flash and find things that way? [Edit: It looks like the intel team made a tool for this exact thing, chipsec. ]
Is anyone looking for this stuff when doing IR? I didn’t see any content in SANS (sans this paper - Which described the attack surface, but no courses on the matter. Lazy googling of popular forensics tools (encase) looked like it was also not a consideration.
Some research has been done into detection Chip based approach to detect rootkits, 2007 - ‘deepwatch’ - Intels idea of using a seperate microcontroller to do detection, but it doesn’t appear like this ever went anywhere (or was adopted in a widespread manner). There’s also a cool paper on the Acquisition of compromised firmware using memory analysis (2015).
According to the paper:
- On dumping firmware (non-SMM, AMT, etc)
Major OS like windows, Linux and OSX don't consider firmware regions to be RAM
- You can pull off dumping firmware via PCI Introspection
winpmem
has been able to do this since 2016
The same names keep popping up in this sphere (Yuriy Bulygin, Oleksandr Bazhaniuk), which propose quite a few cool ideas (time measurement), They appear to have quite a bit of research - http://www.c7zero.info/
There’s also the question of AMT or just flashing firmware on other devices
The posts I’m referring to are: