The iPXE Anywhere software suite, manufactured by 2Pint, uses the open source network boot loader iPXE. In order for 2Pint to offer Secure Boot as a feature to this product suite, 2Pint had asked Microsoft to sign an image of iPXE. This review covers a code audit of the iPXE source that is to be included as part of the signed image, as well as a partial review of the iPXE Anywhere product suite.
Microsoft agreed to sign the binary with the following security guarantees:
- All reported bugs that are part of this code review must be resolved, and Microsoft must agree with the resolution. All the fixes will be reviewed by Microsoft.
- If iPXE Anywhere provides a guarantee of EFI signature verification (loadimage, execimage) then they don’t need imgverify / imgtrust. Imgload should only take iPXE scripts and EFI images.
- The image should only contain needed components for 2Pint to operate. This means the suite should contain a restricted set of drivers loaded as well as use UNDI to handle network drivers.
iPXE is written in C, using the gcc compiler / gmake. The developer has provided a guarantee that the signed binary will be for amd64 and x86. iPXE is a relatively large codebase with approximately 500k lines of source code. Microsoft discovered that a large amount of this code constitutes network drivers and an 802.11 stack, contributing to a large amount of attack surface. After a series of meetings, the scope was narrowed down, specifically cutting most network drivers (accounting for about half of the codebase) and relying on UNDI (Universal Network Device Interface, a mini driver and network stack build right into some network cards, specifically for PXE). By and large the source code that touches the following components has been audited and will be part of the signed binary:
- Protocols: Arp, Eapol, Ethernet, Icmp, Ipv4, Ipv6, Ndp, Neighbor, Pccrc, Ping, Rarp, Stp, Tls, Vlan
- TCP: http, https, iscsi
- UDP: dhcp, dhcpv6, dns, slam, tftp
- Images Formats: efi, script
- Crypto: ALL
- Drivers: Usb, Infiniband, UNDI
- HCI: Login, Shell
- Interfaces: Efi, Hyperv, smbios
- Commands: Only commands that these features touch or are in 2pints config
This still left roughly 250k lines of code.
One of the things we noticed early on in the review were enormous fluctuations in code quality on a per-feature basis. We discovered that code written by the main author is of superior quality compared to the rest of the iPXE code written by others (areas such as Wifi Stack and nfs).
The code does not adhere to the Microsoft SDL and banned API list. Specifically, we observed the use of strcpy, memcpy, sprintf, and other such API. We noted that iPXE used no external libraries. All stdlib functions where created by the iPXE developer, using assembly in some cases, and with no dependency on any 3rd-party libc runtime. Crypto code was built from the ground up. It was reviewed for security issues (for example, buffer overflows and integer overflows) but not for cryptographic weaknesses. The latter is because all crypto of significance to Microsoft was done by UEFI Secure Boot mechanism (verify executable code), and not iPXE. iPXE’s use of the EFI boot services stack was exceptionally well documented, and we found the code to be of high quality.
The majority of the network entry points are defined in interface operation structures. For example, the Fibre Channel Over Ethernet uses the following:
This approach is true from the lowest layers of the stack all the way up to the highest, including network drivers, ethernet, ipv4/6, udp, tcp, http(s), ssl, BrancheCache, and more. Every structure that was used to store network layer data was packed properly.
iPXE allows for a scriptable interface that can be used on a per case basis. Entry points for the commands are defined as part of the command structure. For example, to register the DCHP command, iPXE uses the following:
The command interface is very well written. Although we found many potential integer overflows, it turned out none of them could be triggered because they were based on string lengths (with 2-4gb strings being impossible).
The following commands were removed from the signed build because of security implications:
- Gdbstub allowed for remote debugging which allowed remote code execution by design
- Imgtrust allowed for images to be loaded that were self-signed by the developer
- Imgverify allowed for verification to be passed for the above command
Reviewers thoroughly reviewed both network and command parsers using both source code review and runtime testing. Code patterns with potential security issues that were observed during the review are:
- Integer overflows/underflows
- Out of bounds reads/writes
- Unbounded variable length arrays
- Null dereferences
The overall observed code quality of the iPXE code base passes our criteria. As noted earlier, we saw a fairly wide difference in quality depending on the author of any particular code, with the main author writing higher quality code. While the SDL and banned API are not applied, most of the code written by the main developer is still of high quality.
Given the open-source nature of iPXE, should a security issues be reported in iPXE in the future, it will likely be a zero-day bug in the signed code. Updating signed blobs may very well lag behind in fixes compared to what’s in the open source code repository.
For signing the iPXE blob in future iterations, verification needs to be done to make sure that bugs reported in the following sections are fixed if newly included:
- 11 stack (mostly RCE)
- Nfs (several read AVs)
Security Review Guidance
When reviewing the iPXE-based project the security reviewer should focus on:
- Reducing attack surface.
- Ensuring signatures are verified correctly.
- That all input received from remote and local sources is properly validated.
We observed some areas of the iPXE projects that contain common attack surfaces, and which may not be needed by the project. These include: icmp, ndp, neighbour, pccrc, rarp, stp, tls, http/s, ftp, iscsi, syslog, dns, tftp, oncrpc/NFS, infiniband, 802.11 WEP & WPA, file format parsers (efi, elf, png, pnm), ASN.1, and a large number of HCI commands.
Previously observed security flaws have included incorrect file signature validation, integer over/underflows, out of bound reads, buffer overflows, and other potential memory corruption issues. The reviewer should pay particular attention to commonly vulnerable code sections such as ASN.1, memory allocation lifetime, and cryptographic verification. Any discovered vulnerabilities as a part of your audit should be securely reported to the iPXE maintainers and patched in your submission to the MS Hardware Dev Center.