在上一篇文章中,我们了解了什么是 SOME/IP 协议,本次来看看 SOME/IP-SD 协议是什么以及如何利用 SOME/IP-SD 协议来模糊测试 SOME/IP 协议。
What is SOME/IP-SD Protocol?
SOME/IP-SD 是一个实现在 SOME/IP 层之上的协议。它用来在网络中查找服务实例,检测某个服务实例是否正在运行,并实现发布/订阅处理。
每个设备都会广播(多播)一条包含该设备提供的所有服务的消息。如果客户端应用程序需要当前没有提供的服务,则也可以发送“查找消息”。其他 SOME/IP-SD 消息可以用来发布/订阅事件组。(默认设置下 SOME/IP-SD 消息通过 UDP 端口 30490 传输。)
SOME/IP-SD packet structure
SOME/IP-SD 的 SOME/IP 头部区域具有固定的值,如下图所示。由于消息类型为 0x02,因此 SOME/IP-SD 消息不期望收到回复。
Message ID (Service ID/Method ID) [32 bit]: 0xFFFF 8100
Protocol Version [8 bit]: 0x01
Interface Version [8 bit]: 0x01
Message Type [8 bit]: 0x02 (Notification)
Return Code [8 bit]: 0x00
SOME/IP-SD 标志字段的第一个标志位被称为重启标志。在重启后直到 SOME/IP 头部中的会话 ID 滚动并再次以 1 开始之前,所有 SOME/IP-SD 头部的重启标志都将设置为 1。在此次滚动之后,重启标志将设置为 0。SOME/IP-SD 标志中的第二个标志位称为单播标志。单播标志是早期 SOME/IP 版本的历史遗留物,仅为了兼容性而保留。其使用范围非常有限。单一 SD 消息支持多个条目,这些条目用于同步服务实例的状态或用于发布/订阅处理。
Service Entry / Eventgroup Entry
服务通告消息被服务提供者用来向网络公布他们的服务,而服务发现消息被服务消费者用来在网络中搜寻服务。下图描述了服务条目中每个元素的详细信息。
Type Field [uint8]:查找服务(0x00)、提供服务(0x01)、停止提供服务(0x01,TTL=0x00)
Index 1st Option [uint8]:选项数组中的第一个选项的索引。
Index 2nd Option [uint8]:选项数组中的第二个选项的索引。
Number of Options 1 [uint4]:第一个选项运行使用的选项数量。0 表示没有选项。
Number of Options 2 [uint4]:第二个选项运行使用的选项数量。0 表示没有选项。
Service-ID [uint16]:服务或服务实例的服务 ID。
Instance ID [uint16]:服务实例的服务实例 ID。0xFFFF 表示所有服务实例。
Major Version [uint8]:服务(实例)的主版本号。
TTL [uint24]:条目的生存周期,以秒为单位。
Minor Version [uint32]:服务的次版本号。
事件组条目长度为 16 字节,并按以下顺序包括以下字段:
Type Field [uint8]: 订阅(0x06)、停止订阅事件组(0x06,TTL=0)、订阅确认(0x07)、订阅事件组 NACK(0x07,TTL=0)
第一个选项运行的索引 [uint8]、第二个选项运行的索引 [uint8]:与服务条目相同。
第一个选项的数量 [uint4]、第二个选项的数量 [uint4]:与服务条目相同。
Service-ID [uint16]: 与服务条目相同。
Instance ID [uint16]: 任何实例的服务实例 ID 不应设置为 0xFFFF。
Major Version [uint8], TTL [uint24]: 与服务条目相同。
Reserved [uint12]: 应设置为 0x000.
Counter [uint4]: 用于区分同一订阅者的相同订阅事件组。如果不使用则设置为 0x0。
Eventgroup ID [uint16]: 传输事件组的 ID。
Options formet (IPv4 Endpoint)
这包括例如服务实例信息(IP 地址、传输协议、端口号)。选项用于传输附加到条目的信息。
SOME/IP-SD 消息分析和模糊测试
我得到了由宝马私人漏洞赏金计划提供的MGU22的模拟环境。该模拟环境配置为树莓派,树莓派上的QEMU模拟了MGU22环境。一个虚拟的二进制文件在树莓派上运行,模拟连接到MGU22的其他控制器,如激光雷达、车身电子控制单元和底盘电子控制单元。该环境通过虚拟二进制文件和QEMU(MGU22)之间的通信模拟了内部SOME/IP通信和整个车载系统。
对于SOME/IP,使用了160.48.199.xx范围的网络。在MGU22控制器的情况下,分配了IP地址160.48.199.99,车身.caraccess被分配了IP地址160.48.199.16,车身被分配了160.48.199.64,底盘被分配了160.48.199.93。除了160.48.199.99之外的其他IP地址都绑定在QEMU机器外的虚拟二进制文件上。
Binding Table
Address | ECU |
160.48.199.6 | dass |
160.48.199.16 | caraccess |
160.48.199.20 | UPCP_Safety |
160.48.199.34 | dassproposal |
160.48.199.64 | body |
160.48.199.72 | LIDAR_D_H |
160.48.199.73 | LIDAR_D_V |
160.48.199.74 | LIDAR_D_L |
160.48.199.75 | LIDAR_D_R |
160.48.199.76 | FRR_D_VL |
160.48.199.77 | FRR_D_VR |
160.48.199.78 | FRR_D_HL |
160.48.199.79 | FRR_D_HR |
160.48.199.93 | chassis |
160.48.199.96 | interiorillumination |
160.48.199.97 | infotainment |
160.48.199.98 | sapoverip |
160.48.199.121 | infotainment |
160.48.199.125 | testability |
由于我们的模糊测试目标IP是160.48.199.99,即MGU22,我们可以考虑两种情况。第一种是对MGU22提供的服务进行模糊测试(请求/响应)。第二种是篡改MGU22订阅的服务发送给MGU22的事件消息。 如果MGU22和控制器之间已经建立了连接,也可以使用message hooking。如果虚拟二进制文件(ECUs)和QEMU(MGU22)之间的连接断开,模拟将结束,因此我们只能通过hook消息来修改从IP 160.48.199.16(body.access)发送到160.48.199.99的消息进行模糊测试。
使用像Frida这样的工具,你可以通过hook从虚拟二进制文件发送到QEMU的消息,对其他控制器和MGU22之间的SOME/IP通信进行模糊测试。
在真实的测试台设置环境中,你可以从网络中移除一个控制器,然后从PC发送SOME/IP消息到MGU22以模拟正常系统状态。
例如,如果你从SOME/IP网络中移除了地址为160.48.199.74的左侧激光雷达,然后连接PC到SOME/IP网络并发送左侧激光雷达发送给MGU22的数据包,你可以用PC模拟一个虚拟激光雷达。你可以通过修改数据包进行模糊测试,这是模糊测试基于CAN或以太网的车辆网络的常用方法。
现在让我们来看一下实际的SOME/IP-SD消息pcap捕获。Wireshark从3.2.0版本开始支持SOMEIP模式。
SOME/IP提供服务消息的详细信息如下。提供服务消息是从地址160.48.199.99向网络中的地址进行多播。数据包内容使用上述的SOME/IP头部,使用消息ID(服务ID/方法ID)0xFFFF 8100,并使用协议版本、接口版本0x1、消息类型0x02通知和返回代码0x00的固定值。
消息类型为提供服务(Offer Service)。由于存在一个选项数组,选项数量(opts)为1。索引为1的选项和索引为2的选项都指向第0个选项数组。服务ID为0xb063,且主版本号与接口版本号匹配。
在对应的SOME/IP-SD消息中,提供服务条目的选项数组索引为0,因此它对应于第0个选项数组。选项数组包含IP地址、协议类型和端口号。
因此,上述提供服务消息的总结是,IP地址160.48.199.99在TCP端口32501上提供了对应于服务ID 0xb063的服务。在MGU22的情况下,开机时会持续发送提供服务消息,但如果没有提供服务消息,也可以通过发送查找服务消息来了解所提供服务的服务ID。
对于服务ID 0xb063,由于您不知道方法ID和负载结构,需要随机模糊测试(fuzz)方法ID和负载。在这种情况下,负载必须序列化为随机数据类型。
第二种方法是找到MGU22订阅的服务ID,并发送修改后的事件消息。
如果你能够捕获发送到地址 160.48.199.99 的事件数据包,那么你可以了解方法 ID 和有效载荷的结构,使得模糊测试更容易。
DEMO
以下是通过模糊测试发现的一个漏洞的示例视频。
如果某个进程被终止,恢复管理器将会重启该进程,或者 MGU22 可能会重启。