uds診斷協議-逆向題 WP
介紹
這是一道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腳本
#!/bin/bashfor((i=1;i<1000000;i++));do./uds;done
啟動多個該腳本同時進行。增加并發減小爆破時間。
patch 測試 exp
patch Server初始化中random返回結果




將randomNum返回值修改為0x125000
在linux 根目錄創建getflag文件賦予777權限,/getflag文件內容如下
#!/bin/shecho hello
執行exp 成功返回hello

真正的exp
正常情況下這樣爆破是沒問題的,但我一直在想這是CTF沒有那么多時間讓你爆破,肯定還有其他辦法。得知....//....//可以路徑穿越后。又有了攻擊思路:
和前面一樣。
這里不直接讀內存,通過UdsRequestFileTransferService設置路徑
讀取路徑為....//....//proc/self/maps
經過過濾拼接后得到/tmp/data/../../proc/self/maps
設置路徑包構造


調用UdsTransferDataService讀取文件



對返回的/proc/self/maps進行解析獲取到backdoorMem基址。基址減去0x123000獲取到偏移
將0xdeadbeef寫入backdoorMem基址
調用getflag

成功獲取flag