本文为看雪论坛精华文章
看雪论坛作者ID:scxc
介绍
这是一道uds诊断协议的逆向题。比赛的时候时间太短没做出来,又花时间研究了一下拿出来分享。
题目
uds_server程序逻辑
main
启动后监听13400端口
接收client请求
启动Server
Server初始化后进入loop
接收处理客户端发送的请求
其中handleRoutingActivationMessage函数负责注册
注册后可以调用提供的service
jmp rax跳转到不同的服务
所提供的服务如下
服务列表
两个目标分析
UdsRequestFileTransferService
构造满足的条件后,我们传送的路径字符串会拼接到/tmp/data/后面。同时过滤../。
UdsRoutineControlService
这个函数从getflag这看起来就像目标函数,要求的条件很多。
唯一一个不可控因素backdoorMem是random出来的。
可以通过UdsWriteMemoryByAddressService写内存。
攻击思路
1、注册,使客户端能访问uds服务
-
sourceAddress=0x1
-
targetAddress=0x100
2、构造满足UdsRoutineControlService的条件
-
securityLevel=1
-
currentSession=2
-
retineControlType=1
-
routineIdentifier=0xbac4
-
backdoorMem地址中内容为0xdeadbeef
3、backdoorMem取值范围0x123000-0xfffff000后三位固定为0。
4、通过UdsWriteMemoryByAddressService向0x125000写入内存deadbeef
5、n随机区间[0~1048284] 多进程循环调用直到 n==2 backdoormem=0x125000
6、调用UdsRoutineControlService
构造请求
doip协议
构造注册请求
调用handleRoutingActivationMessage
需要满足的条件
activationType=0
sourceAddress=1
执行后 hasRegisterd=1
设置currentSession
调用UdsSessionControlService
需要先将currentSession设置成3 保证下次设置2的时候可以走else分支
设置securityLevel
调用UdsSecurityAccessService
请求seed
根据seed计算key
seed进行变换后调用xteaEncryptGetKey进行加密计算key
相等的话设置securityLevel=1
写入0xdeadbeef到backdoorMem
调用UdsWriteMemoryByAddressService
设置memoryAddress为0x2000 0x123000+0x2000=0x125000
设置写入的内容为0xdeadbeef
判断是否有返回,有返回则写入成功
调用getflag函数
调用UdsRoutineControlService
bash脚本
for((i=1;i<1000000;i++));
do
./uds;
done
启动多个该脚本同时进行。增加并发减小爆破时间。
patch 测试 exp
patch Server初始化中random返回结果
将randomNum返回值修改为0x125000
在linux 根目录创建getflag文件赋予777权限,/getflag文件内容如下
echo hello
执行exp 成功返回hello
真正的exp
正常情况下这样爆破是没问题的,但我一直在想这是CTF没有那么多时间让你爆破,肯定还有其他办法。得知….//….//可以路径穿越后。又有了攻击思路:
和前面一样。
这里不直接读内存,通过UdsRequestFileTransferService设置路径
读取路径为….//….//proc/self/maps
经过过滤拼接后得到/tmp/data/../../proc/self/maps
设置路径包构造
调用UdsTransferDataService读取文件
对返回的/proc/self/maps进行解析获取到backdoorMem基址。基址减去0x123000获取到偏移
将0xdeadbeef写入backdoorMem基址
调用getflag
成功获取flag
看雪ID:scxc
https://bbs.pediy.com/user-home-638330.htm
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!
原文始发于微信公众号(看雪学苑):uds诊断协议-逆向题 WP