publisherUpdate() does not update subscriber's list of publishers

asked 2020-11-08 17:58:52 -0500

Drumstick gravatar image

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 ... (more)

edit retag flag offensive close merge delete

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!

pepe gravatar image pepe  ( 2021-04-02 22:02:47 -0500 )edit

Hi there! I am sorry but I was not able to find a way to use this API successfully.. I eventually stopped trying...

Drumstick gravatar image Drumstick  ( 2021-04-03 11:27:18 -0500 )edit

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!

pepe gravatar image pepe  ( 2021-04-06 00:45:18 -0500 )edit

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!

Drumstick gravatar image Drumstick  ( 2021-04-28 14:03:25 -0500 )edit

If you are able to find the solution for my question above please share it :)

Drumstick gravatar image Drumstick  ( 2021-04-28 14:06:26 -0500 )edit