publisherUpdate() does not update subscriber's list of publishers
Hi there, I am currently trying to implement the "Stealth Publisher attack" as presented in section 3.1 of this paper (Dieber, et al. 2019). This attack explores ROS1 authentication/authorization vulnerabilities by manipulating a subscriber's list of publishers without the master node knowledge, making use of the publisherUpdate
API . This technique allows fake data injection to a target node and potential man-in-the-midlle attacks.
Experiment
I created a simple experiment to reproduce the publisherUpdate
behavior (updating a subscriber's publishers list), however it is not working as intended. Below you can find the code snippets for reproducing the behavior.
- Node 1 ("Publisher 1"):
Code Snippet:
import rospy
from std_msgs.msg import String
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker_1', anonymous=True)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
hello_str = "hello world pub_1 %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
- Node 2 ("Publisher 2"):
Code Snippet:
import rospy
from std_msgs.msg import String
def talker():
pub = rospy.Publisher('chatter', String, queue_size=10)
rospy.init_node('talker_2', anonymous=True)
rate = rospy.Rate(10) # 10hz
while not rospy.is_shutdown():
hello_str = "hello world pub_2 %s" % rospy.get_time()
rospy.loginfo(hello_str)
pub.publish(hello_str)
rate.sleep()
if __name__ == '__main__':
try:
talker()
except rospy.ROSInterruptException:
pass
- Node 3 ("Subscriber"):
Code Snippet:
import rospy
from std_msgs.msg import String
def callback(data):
rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
def listener():
rospy.init_node('listener', anonymous=True)
rospy.Subscriber("chatter", String, callback)
# spin() simply keeps python from exiting until this node is stopped
rospy.spin()
if __name__ == '__main__':
listener()
publishUpdate
Trigger:
In order to call the XML-RPC API of the "Subscriber" node, I created the following python script which will create a XML-RPC ServerProxy for this node and call its publisherUpdate
API with the desired new publishers.
Code Snippet:
Please note that the URIs of the XML-RPC servers are hidden as they will change evrytime there is a new run.
from xmlrpc.client import ServerProxy
# XML-RPC URI of the "Subscriber" Node
SUBSCRIBER_URI = XXXXX
# XML-RPC URI of the "Publisher_2" Node
PUBLISHER_2_URI = XXXXX
s = ServerProxy(SUBSCRIBER_URI)
s.publisherUpdate('/master', '/chatter', [PUBLISHER_2_URI])
With this experiment, the subscriber was supposed to only listen to the talker ("Publisher 2") specified through the publisherUpdate
API only. In other words, it should remove the "Publisher 1" node from the list of known publishers and keep only the "Publisher 2" node, receiving only messages from the latter. However, this behavior is not observed.The subscriber is still receiving the "Publisher 1" node messages and thus the publisherUpdate
API call was not successful in updating the publishers.
The curious part is that the ROS master node invokes this API of the "Subscriber" node to advertise the presence of the publisher nodes, so the API is working well in that case as these are being listened by the "Subscriber" node.
Is this the expected behavior when "manually" calling the publisherUpdate
API? How is this call different from the one made by the master node?
System Information
- OS: Ubuntu 18.04
- ROS Distro: Melodic
- ROS Version: 1.14.9
Thanks in advance!
Asked by Drumstick on 2020-11-08 18:58:52 UTC
Comments
Excuse me, I am also troubled by this problem, have you solved this problem now? How to use publishUpdate API, can we discuss it, thank you!
Asked by pepe on 2021-04-02 22:02:47 UTC
Hi there! I am sorry but I was not able to find a way to use this API successfully.. I eventually stopped trying...
Asked by Drumstick on 2021-04-03 11:27:18 UTC
I would like to ask you some questions. Have you studied the vulnerabilities of ROS1 before? In addition to this article, have you performed system interference on ROS1? Could you give me some suggestions? Do you have any relevant materials or codes to share with me? Thank you!
Asked by pepe on 2021-04-06 00:45:18 UTC
HI there, sorry for just replying to you now. I looked into some vulnerabilities of ROS1 as part of a research project in which we tried to understand how such vulnerabilities could be exploited for the context of the problem. In the end we opted to discard ROS-specific security details as we were diverging from our initial goal. However, during the time diving into the subject I found that there are different materials on ROS1 security, specifically different articles about it:
These are just a few examples but more exist and are worth taking a look at. I suggest you to to do a quick search throughout different platforms (arXiV, Google Scholar, etc.) so that you can easily find them. Hope it helps!
Asked by Drumstick on 2021-04-28 14:03:25 UTC
Just wanted to leave a few more links to some other interesting papers:
Asked by Drumstick on 2021-04-28 14:05:19 UTC
If you are able to find the solution for my question above please share it :)
Asked by Drumstick on 2021-04-28 14:06:26 UTC