Skip to content
Suzu

OpenBMC Security Part 1: Architecture, Attack Surface, and Lab Setup

A practical and slide-backed walkthrough of OpenBMC architecture, attack surface, D-Bus, and a QEMU lab setup.

Series
3 posts
View the complete series →
On this page

Before looking at CVEs, I want to slow down and answer a simpler question first: what exactly are we attacking when we say “OpenBMC”?

At first glance, OpenBMC can look like just another admin web interface. But that view is too small. A BMC is a small computer sitting next to the host system. It can monitor sensors, control power, expose remote console access, update firmware, and keep working even when the host OS is dead. So if an attacker controls the BMC, they are not just popping a random web service. They are standing very close to the hardware control plane.

This part is a map. Nothing too fancy yet. We will walk through the architecture, the main entry points, why D-Bus shows up everywhere, and how to build a small QEMU lab for safer testing.

Slide defining OpenBMC as an open-source Linux-based BMC platform for remote server management and monitoring.

Big Picture

The easiest way to reason about OpenBMC security is to split it into layers. When a request comes in from the network, it usually does not stop at the first daemon. It moves from an external interface, into userspace services, through D-Bus, and sometimes all the way down to kernel drivers and hardware buses.

Slide showing the layered OpenBMC architecture, from external management interfaces through userspace, D-Bus, kernel, and hardware.

Here is the same idea in text form.

LayerTypical componentsWhy I care about it
External management interfacesRedfish, WebUI, IPMI, SSH, Serial over LAN, KVMThis is where remote input enters the BMC. Parser bugs and auth mistakes usually start here.
OpenBMC userspace servicesbmcweb, phosphor-ipmi-net, phosphor-host-ipmid, dbus-sensors, entity-manager, phosphor-state-manager, phosphor-logging, account and firmware servicesThis is where most policy and business logic lives. A crash here can take down management features.
D-Bus object layerservice names, object paths, interfaces, methods, properties, signalsThis is the internal message bus. External APIs often become D-Bus calls.
Linux kernel and driversnetwork stack, hwmon, MTD, JFFS2/UBIFS, GPIO, I2C, SPI, LPC, KCS, PECIThis is where userspace starts touching real devices and buses.
Hardware layerASPEED SoC, ARM CPU, RAM, SPI flash, NIC, sensors, fans, PSUs, GPIO, I2C, LPC, UARTThis is the real reason BMC compromise matters. The BMC is attached to platform hardware.

The practical lesson is simple: do not review a BMC bug like a normal web app bug. A Redfish request might eventually become a power action, firmware operation, or low-level hardware interaction.

Entry Points

The first place I look is the network-facing surface. OpenBMC exposes several interfaces because different administrators and automation systems need different ways to manage the machine.

Slide showing the relationship between external entry interfaces and OpenBMC userspace services.

The common ones are:

Slide listing OpenBMC external entry points including Redfish, IPMI, SSH, Serial over LAN, and KVM.

InterfaceCommon componentCommon portWhat it is used for
Redfish and WebUIbmcwebHTTPS 443Modern management API, web interface, inventory, settings, firmware workflows
IPMI over LANphosphor-ipmi-net, phosphor-host-ipmidUDP 623Traditional power, sensor, and event commands
SSHOpenSSHTCP 22Shell access, maintenance, debugging, file transfer
Serial over LAN and KVMSOL/KVM/web-console servicesdynamic or proxiedRemote console, BIOS access, OS installation and recovery

Redfish is nice because it is standardized and easy to automate. IPMI is old, but still everywhere. SSH is useful, but it is a direct administrative path. KVM and Serial over LAN are powerful because they may expose pre-boot workflows.

My default assumption is that all of these belong on a management network only. If a BMC interface is reachable from the public internet or from a normal user VLAN, the architecture is already in a bad state before we even talk about CVEs.

Userspace Services

This is the layer where names start to matter. bmcweb handles Redfish and the WebUI. IPMI traffic goes through phosphor IPMI services. Sensors, inventory, state changes, logging, and firmware updates are each handled by their own services.

Slide listing core OpenBMC userspace components and their responsibilities.

The important part is not memorizing every daemon name. The important part is knowing that OpenBMC is a set of cooperating services. If I send a Redfish request to get sensor data, bmcweb probably does not own the sensor itself. It has to ask the service that exposes that sensor object.

That is where D-Bus comes in.

D-Bus Is The Middle Of The Story

When I first learned OpenBMC, D-Bus felt like background plumbing. After looking at real request paths, it becomes much more central. D-Bus is how services discover each other, expose objects, read properties, call methods, and publish state changes.

Slide showing a D-Bus sensor object with object path, interface, properties, methods, and signals.

A temperature sensor may be represented like this:

/xyz/openbmc_project/sensors/temperature/CPU0

It may implement:

xyz.openbmc_project.Sensor.Value

And expose properties such as:

Value: 63.25
Unit: degree Celsius
CriticalHigh: 90.0

From the outside, a Redfish client sees JSON. Inside the BMC, bmcweb maps that request into D-Bus object lookups and property reads. IPMI follows the same general idea: a network command enters an IPMI service, then internal platform state is queried or changed.

Slide introducing why D-Bus is central to OpenBMC.

So when reviewing an OpenBMC path, I like to ask:

  • Which external route accepts the request?
  • Which service parses it?
  • Which D-Bus object does it touch?
  • Which method or property is reachable?
  • Where is authorization actually enforced?
  • What happens if the external parser passes weird values into the internal method?

That last question is where many interesting bugs begin.

Request Flows

The slide deck includes several flow diagrams. They are useful because they show that the protocol is only the first part of the journey.

Slide showing how a Redfish or WebUI request flows through TLS and OpenBMC services.

For Redfish and WebUI, bmcweb is the critical gatekeeper. It terminates HTTPS, parses HTTP, handles sessions or credentials, maps routes, and talks to internal services.

Slide showing how an IPMI request flows through the OpenBMC IPMI service path.

For IPMI, the request shape is different, but the security questions are similar: who parses it, what command is selected, what internal state changes, and whether the BMC should allow it.

Sensor and inventory flows are also worth seeing visually:

Slide showing the OpenBMC sensor data flow.

Slide showing platform model, inventory, and entity-manager flow.

And the same goes for power and logging:

Slide showing state and power control flow inside OpenBMC.

Slide showing event, log, and error handling in OpenBMC.

These flows are why BMC security feels different from normal backend security. A method call may not just update a row in a database. It may change fan behavior, power state, firmware state, or host visibility.

Kernel And Hardware

Below userspace, OpenBMC is still Linux. That means normal kernel and driver concerns are in play, but the devices are very BMC-specific.

Slide showing D-Bus, Linux kernel, device drivers, and BMC hardware such as ASPEED SoC, SPI flash, sensors, GPIO, I2C, LPC, and UART.

This layer is why “just a management controller” is a dangerous phrase. The BMC has access to flash, sensors, GPIO, I2C, LPC/KCS, and other platform paths. The host OS may be off, crashed, or compromised, but the BMC can still be alive and reachable.

Debugging The System

If I had to pick one habit for OpenBMC research, it would be this: watch D-Bus and service logs while sending external requests.

Slide listing useful D-Bus, journalctl, Redfish, and IPMI commands.

List the D-Bus service and object tree:

busctl tree

Inspect a specific object:

busctl introspect <service> <path>

Monitor live D-Bus calls and signals:

busctl monitor

Follow bmcweb logs while testing Redfish or WebUI behavior:

journalctl -u bmcweb -f

Follow IPMI over LAN logs:

journalctl -u phosphor-ipmi-net -f

Query Redfish:

curl -k -u <user:pass> https://<bmc-ip>/redfish/v1/Systems

Query IPMI sensor data:

ipmitool -I lanplus -H <bmc-ip> -U <user> -P <pass> sdr

Once these commands become familiar, OpenBMC stops being a black box.

Building A Lab

For vulnerability analysis, I do not want to test on production BMCs. A QEMU OpenBMC target is slower and less realistic than hardware, but it is repeatable and much safer.

Slide showing suggested OpenBMC development requirements such as Ubuntu, CPU, RAM, and disk space.

The slide recommends:

RequirementMinimumSuggested
OSUbuntu 22.04 or 24.04Ubuntu 22.04 or 24.04
CPU4 cores8 cores
RAM16 GB32 GB
Disk150 GB200 GB
Path hygieneEnglish path, no spacesEnglish path, no spaces

The setup commands are straightforward, but the build can take a while:

Slide showing OpenBMC environment setup commands, dependencies, source clone, and BitBake build command.

echo 'kernel.apparmor_restrict_unprivileged_userns = 0' | \
  sudo tee /etc/sysctl.d/99-bitbake.conf
sudo sysctl -p /etc/sysctl.d/99-bitbake.conf
sudo apt update
sudo apt install -y git gcc g++ make file wget \
  gawk diffstat bzip2 cpio chrpath zstd lz4
git clone https://github.com/openbmc/openbmc.git
cd openbmc
. ./setup romulus
bitbake obmc-phosphor-image

The QEMU run script forwards common BMC services to local ports:

Slide showing a QEMU run script for an OpenBMC Romulus BMC image with forwarded SSH, HTTPS, HTTP, IPMI, and UDP ports.

qemu-system-arm -m 256 -machine romulus-bmc -nographic \
  -drive file=./obmc-phosphor-image-romulus.static.mtd,format=raw,if=mtd \
  -net nic \
  -net user,hostname=qemu,\
hostfwd=tcp::2222-:22,\
hostfwd=tcp::2443-:443,\
hostfwd=tcp::2080-:80,\
hostfwd=udp::6230-:623,\
hostfwd=udp::6640-:664

This gives us a place to reproduce crashes, watch logs, compare patches, and reset the environment when things break.

Takeaways

The main thing I want to keep in mind before moving into the CVEs is this: OpenBMC is a management operating system, not a single service. Redfish, IPMI, SSH, KVM, and SOL are not just random ports. They are entrances into a control plane that can eventually touch platform services, firmware state, power state, and hardware buses.

So when I review an OpenBMC bug, I try not to stop at “which endpoint is vulnerable?” I want to know where the request goes next, which service owns the object, and whether the boundary is still safe after parsing. That mindset is what makes the next two parser bugs much easier to reason about.

In the next part, we will use this map to look at bmcweb multipart parsing bugs.

References

Share this page