记一次汽车T-BOX分析

汽车安全 11个月前 admin
201 0 0

记一次汽车T-BOX分析

Part1前言

近期对汽车Tbox进行了一些逆向分析,由于只有一个零部件分析起来还是较为困难的,本次呢,针对TBOX对外开放服务进行了逆向分析,这里就分享一下过程。下一次我们将分析TSP->TBOX->MCU->CAN的过程。

Part2代码分析

拿到设备点亮之后,通过adb拿到shell,netstat -antpl可以看到监听在0.0.0.0的端口为53、8888。根据AVN这个程序名,就可以猜测8888端口这是一个与车机交互的程序。

记一次汽车T-BOX分析

Ida打开AVN服务Main方法往下可以看到这里有一个HU服务初始化的函数,这里8888就是端口,刚刚通过netstat -antpl也看过。

记一次汽车T-BOX分析

进入到函数实现,有几个指向,虽然我们已经知道这个服务的端口是8888,但是我们可以先关注传过来的a1跟踪一下看看,进入到TCPServer_init的实现。

记一次汽车T-BOX分析

a1传给了addr接着调用了bind,很明显了这就是绑定的端口。

记一次汽车T-BOX分析

记一次汽车T-BOX分析

不理解的朋友没关系,我们先来看一个经典的socket通信代码。

服务端:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <arpa/inet.h>#define PORT 8080#define BUFFER_SIZE 1024int main() {int server_fd, new_socket;struct sockaddr_in address;int addrlen = sizeof(address);char buffer[BUFFER_SIZE] = {0};char *response = "Server response";// 创建套接字if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 设置服务器地址和端口address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 绑定套接字到指定地址和端口if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 监听连接if (listen(server_fd, 3) < 0) {perror("listen failed");exit(EXIT_FAILURE);}printf("Server listening on port %dn", PORT);// 接受客户端连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) {perror("accept failed");exit(EXIT_FAILURE);}// 接收客户端数据int bytes_read = recv(new_socket, buffer, BUFFER_SIZE, 0);printf("Received from client: %sn", buffer);// 发送响应给客户端send(new_socket, response, strlen(response), 0);printf("Response sent to clientn");return 0;}

客户端:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <arpa/inet.h>#define SERVER_IP "127.0.0.1"#define PORT 8080#define BUFFER_SIZE 1024int main() {int client_socket;struct sockaddr_in server_address;char buffer[BUFFER_SIZE] = {0};char *message = "Hello from client";// 创建套接字if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}// 设置服务器地址和端口server_address.sin_family = AF_INET;server_address.sin_port = htons(PORT);// 将IPv4地址从点分十进制转换为二进制格式if (inet_pton(AF_INET, SERVER_IP, &server_address.sin_addr) <= 0) {perror("inet_pton failed");exit(EXIT_FAILURE);}// 连接服务器if (connect(client_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0) {perror("connect failed");exit(EXIT_FAILURE);}// 发送数据给服务器send(client_socket, message, strlen(message), 0);printf("Message sent to server: %sn", message);// 接收服务器响应int bytes_read = recv(client_socket, buffer, BUFFER_SIZE, 0);printf("Response from server: %sn", buffer);return 0;}

通过看这个socket通信例子,想必一下子就明白了。那我们接下来继续看。

开了一个线程,跟进看看。

记一次汽车T-BOX分析

这里recv函数代表接收车机端的数据,数据为空移除客户端句柄否则就指向dword_1AFA4,但是并不知道这个函数的作用是什么不过根据上面提到的socket的代码,可以推断出就是发送了。

记一次汽车T-BOX分析

那我们验证一下。Ida中快捷键CTRL+T,搜索一下。

记一次汽车T-BOX分析

取决于v3,v3取决于result,CTRL+X继续回溯。

记一次汽车T-BOX分析

很明显了,dword_1AFA4就是newDataInCb。

记一次汽车T-BOX分析

newDataInCb可以看出这是一个跟车机端交互的逻辑,但似乎要满足某些数据校验,还需要登录呢,先不着急构造,这里我的目的是要模拟一个车机跟tbox去交互,先看看可不可行。

记一次汽车T-BOX分析

记一次汽车T-BOX分析

记一次汽车T-BOX分析

看到一个地方,猜测是一个设置用户登录信息的部分哇。

记一次汽车T-BOX分析

确实是,*(_BYTE *)(result + 4) = 1应该是代表登录的状态,剩下的猜测就是类似token的东西了。那思路就来了,我们模拟一个车机客户端去跟服务端tbox交互,构造特定的socket数据包,就可以是一个登录状态的client了。

记一次汽车T-BOX分析

看一下哪里能走进 LABEL_18。

记一次汽车T-BOX分析

通过分析,只需要满足下图框起来的几个条件就可以了,这看起来是安全可行的,满足头部,长度,命令ID,以及校验码就可以了。

记一次汽车T-BOX分析

构造如下客户端socket:

记一次汽车T-BOX分析

查看tbox这个程序的日志,成功进入预想的逻辑且client也已经绕过了 HUClient_checkLogin变成登录状态。

记一次汽车T-BOX分析

那在继续看其他的,命令ID为1025,且长度满足为9的时候会进入到一个SendAVNSystemLangToRRSrv方法,传入了请求头中的第8个字节v11[7]。

记一次汽车T-BOX分析

通过分析得知tbox里面的进程其实都是通过消息队列去交互的,通过函数名可以猜测是发给了一个叫RR的服务。

记一次汽车T-BOX分析

核心的几个方法有:

FmcOsGetMsg 创建消息队列,参数一为消息队列的长度,参数二为消息队列的类型。

记一次汽车T-BOX分析

FmcOsMsgQSend 发送消息队列:参数一为发送的消息队列ID,参数二为具体的消息。

记一次汽车T-BOX分析

FmcOsMsgQWait 接收消息队列:参数一为接收的消息队列ID,参数二为超时实际,参数三为具体的消息。

记一次汽车T-BOX分析

ida打开RR服务,找到FmcOsMsgQWait参数一为23的位置,重点为参数三,是消息队列的结构。

记一次汽车T-BOX分析

这里recv msg到的*238代表第一个字节代表了消息队列的类型也决定了下面case的走向。

记一次汽车T-BOX分析

所以只需要修改命令ID为1025,[7]为想传入的数据即可,构造socket脚本如下:

记一次汽车T-BOX分析

Tbox日志看到走到了预想的逻辑内。

记一次汽车T-BOX分析

到这里迷茫了,消息队列的ID不能直接控,只有数据可控,也就是FmcOsGetMsg(1, 40)中的参数二,newDataInCb中也没有其他的发送消息队列到其他服务的地方了,登录进来啥也干不了?就突然想起来初始化之后还有个定时器呢,继续跟进。

如下代码在满足登录认证后,在满足某些条件的情况下还是可能会进入到lnm,gnss等一些服务,但很遗憾重要的功能应该控制不了比如类似sendMsgToMCUByTSPApp(TSP->TBOX),然后进程之间都是通过消息队列等待某个消息,执行proc表里面的回调函数。

记一次汽车T-BOX分析

记一次汽车T-BOX分析

记一次汽车T-BOX分析

Part2总结

整个tbox分析起来还是挺复杂的,一个tbox起好多服务它们之间的相互调用关系分析要花费大量的时间,还是要明确你分析的目标是什么,侧重点还是看跟目标有关的,还有就是在没有一个好的环境下要花费很多本来不需要花费很多时间的事,这次分析由于只有一个tbox很多东西没法调试,所以这种情况只能去硬看代码了。


“D&X 安全实验室”
专注渗透测试技术
全球最新网络攻击技术

记一次汽车T-BOX分析

原文始发于微信公众号(DX安全实验室):记一次汽车T-BOX分析

版权声明:admin 发表于 2023年6月12日 下午3:53。
转载请注明:记一次汽车T-BOX分析 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...