-
-
[原创]2022数字中国车联网安全CTF writeup - uds_server
-
发表于:
2022-7-25 23:17
17110
-
[原创]2022数字中国车联网安全CTF writeup - uds_server
这是一道uds诊断协议的逆向题。比赛的时候时间太短没做出来,又花时间研究了一下拿出来分享。
1、注册,使客户端能访问uds服务
2、构造满足UdsRoutineControlService的条件
3、backdoorMem取值范围0x123000-0xfffff000后三位固定为0。
4、通过UdsWriteMemoryByAddressService向0x125000写入内存deadbeef
5、n随机区间[0~1048284] 多进程循环调用直到 n==2 backdoormem=0x125000
6、调用UdsRoutineControlService
调用handleRoutingActivationMessage
需要满足的条件
启动多个该脚本同时进行。增加并发减小爆破时间。
patch Server初始化中random返回结果
将randomNum返回值修改为0x125000
正常情况下这样爆破是没问题的,但我一直在想这是CTF没有那么多时间让你爆破,肯定还有其他办法。得知....//....//可以路径穿越后。
又有了攻击思路:
调用getflag
成功获取flag
服务号 |
服务名称 |
0x10 |
UdsSessionControlService |
0x27 |
UdsSecurityAccessService |
0x31 |
UdsRoutineControlService |
0x36 |
UdsTransferDataService |
0x37 |
UdsRequestTransferExitService |
0x38 |
UdsRequestFileTransferService |
0x3d |
UdsWriteMemoryByAddressService |
doip协议 |
protocolVersion |
inverseProtocolVersion |
dataType |
length |
userdata |
1字节 |
1字节 |
2字节 |
4字节 |
任意长度 |
0x02 |
0xfd |
0x5 0x8 0x8001 |
4字节 |
任意长度 |
注册协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
ActivationType 1字节 |
sourceAddres 2字节 |
8字节 |
0x02 |
0xfd |
0x5 |
0x00 0x00 0x00 0x0b |
0x00 |
0x01 0x00 |
0x00*8 |
session协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
sessionid 1字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x06 |
0x00 0x01 |
0x01 0x00 |
0x10 |
0x03 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x06 |
0x00 0x01 |
0x01 0x00 |
0x10 |
0x02 |
security协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
accessType 1字节 |
Key 4字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x06 |
0x00 0x01 |
0x01 0x00 |
0x27 |
0x01 |
|
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x0A |
0x00 0x01 |
0x01 0x00 |
0x10 |
0x02 |
根据seed计算的key |
writememory协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
memSizeLen&memAddrLen 1字节 |
address |
写入内容长度 1字节 |
写入内容 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x0F |
0x00 0x01 |
0x01 0x00 |
0x3d |
0x14 |
0x00 0x00 0x20 0x00 |
0x04 |
0xef 0xbe 0xad 0xde |
getflag协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
controlType 1字节 |
Identifier 2字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x08 |
0x00 0x01 |
0x01 0x00 |
0x31 |
0x01 |
0xba 0xc4 |
for
((i
=
1
;i<
1000000
;i
+
+
));
do
.
/
uds;
done
for
((i
=
1
;i<
1000000
;i
+
+
));
do
.
/
uds;
done
echo hello
设置读取文件协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
modeOfOperation 1字节 |
filePathAndNameLength 2字节 |
filePath |
compressionMethod encryptingMethod 1字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x23 |
0x00 0x01 |
0x01 0x00 |
0x38 |
0x04 |
0x00 0x1a |
....//....//proc/self/maps |
随便1字节 |
读取文件协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
blockSequenceCounter 1字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x06 |
0x00 0x01 |
0x01 0x00 |
0x36 |
0x01 |
服务号 |
服务名称 |
0x10 |
UdsSessionControlService |
0x27 |
UdsSecurityAccessService |
0x31 |
UdsRoutineControlService |
0x36 |
UdsTransferDataService |
0x37 |
UdsRequestTransferExitService |
0x38 |
UdsRequestFileTransferService |
0x3d |
UdsWriteMemoryByAddressService |
doip协议 |
protocolVersion |
inverseProtocolVersion |
dataType |
length |
userdata |
1字节 |
1字节 |
2字节 |
4字节 |
任意长度 |
0x02 |
0xfd |
0x5 0x8 0x8001 |
4字节 |
任意长度 |
注册协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
ActivationType 1字节 |
sourceAddres 2字节 |
8字节 |
0x02 |
0xfd |
0x5 |
0x00 0x00 0x00 0x0b |
0x00 |
0x01 0x00 |
0x00*8 |
session协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
sessionid 1字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x06 |
0x00 0x01 |
0x01 0x00 |
0x10 |
0x03 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x06 |
0x00 0x01 |
0x01 0x00 |
0x10 |
0x02 |
security协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
accessType 1字节 |
Key 4字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x06 |
0x00 0x01 |
0x01 0x00 |
0x27 |
0x01 |
|
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x0A |
0x00 0x01 |
0x01 0x00 |
0x10 |
0x02 |
根据seed计算的key |
writememory协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
memSizeLen&memAddrLen 1字节 |
address |
写入内容长度 1字节 |
写入内容 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x0F |
0x00 0x01 |
0x01 0x00 |
0x3d |
0x14 |
0x00 0x00 0x20 0x00 |
0x04 |
0xef 0xbe 0xad 0xde |
getflag协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
controlType 1字节 |
Identifier 2字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x08 |
0x00 0x01 |
0x01 0x00 |
0x31 |
0x01 |
0xba 0xc4 |
1
2
3
4
5
|
for ((i = 1 ;i< 1000000 ;i + + ));
do
. / uds;
done
|
设置读取文件协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
modeOfOperation 1字节 |
filePathAndNameLength 2字节 |
filePath |
compressionMethod encryptingMethod 1字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x23 |
0x00 0x01 |
0x01 0x00 |
0x38 |
0x04 |
0x00 0x1a |
....//....//proc/self/maps |
随便1字节 |
读取文件协议 |
1字节 |
1字节 |
type 2字节 |
length 4字节 |
srcaddr 2字节 |
dstaddr 2字节 |
服务号 1字节 |
blockSequenceCounter 1字节 |
0x02 |
0xfd |
0x8001 |
0x00 0x00 0x00 0x06 |
0x00 0x01 |
0x01 0x00 |
0x36 |
0x01 |
- main
- 启动后监听13400端口
- 接收client请求
- 启动Server
- Server初始化后进入loop
- 接收处理客户端发送的请求
- 其中handleRoutingActivationMessage函数负责注册
- 注册后可以调用提供的service
- jmp rax跳转到不同的服务
- 所提供的服务如下
- UdsRequestFileTransferService
构造满足的条件后,我们传送的路径字符串会拼接到/tmp/data/后面。同时过滤../。
- UdsRoutineControlService
这个函数从getflag这看起来就像目标函数,要求的条件很多。
唯一一个不可控因素backdoorMem是random出来的。
可以通过UdsWriteMemoryByAddressService写内存。
- sourceAddress=0x1
- targetAddress=0x100
- securityLevel=1
- currentSession=2
- retineControlType=1
- routineIdentifier=0xbac4
- backdoorMem地址中内容为0xdeadbeef
- activationType=0
- sourceAddress=1
- 调用UdsSessionControlService
- 需要先将currentSession设置成3 保证下次设置2的时候可以走else分支
- 调用UdsSecurityAccessService
- 请求seed
- 根据seed计算key
- seed进行变换后调用xteaEncryptGetKey进行加密计算key
- 相等的话设置securityLevel=1
- 调用UdsWriteMemoryByAddressService
- 设置memoryAddress为0x2000 0x123000+0x2000=0x125000
- 设置写入的内容为0xdeadbeef
- 判断是否有返回,有返回则写入成功
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-7-26 11:30
被scxc编辑
,原因: 忘写标题