前言:ToDesk v4.2.8逆向分析
我在win10上和XP上它運行的機制不同,在x64上的話它會用到一個zrtc.dll的動態鏈接庫,而x32比如xp上就沒有用到
比起360瀏覽器記錄密碼功能的加密算法,這個有點難,我沒分析出來,等之后學了相關的算法之后再看吧,這里就做個分析記錄
應用結構
主程序todesk.exe啟動 -> 啟動服務todesk_service.exe和加載zrtc.dll
1、todesk.exe 界面程序
2、todesk_service.exe 后端程序
3、zrtc.dll 提供相關的函數功能
總體過程
我一開始想要直接調試ToDesk,但是發現程序會直接結束,然后通過pchunter也沒發現有相關的鈎子存在,接着分析ToDesk.exe,會發現ToDesk.exe主程序運行起來之后,它會把ToDesk_service.exe作為服務啟動,此時ToDesk_service.exe會跑起來,然后ToDesk會發送一個信號給ToDesk_service,接着ToDesk_service.exe才算真正的運行起來,接着就是ToDesk_service.exe會檢測ToDesk.exe(不知道具體的,它會進行檢測是不是被調試的狀態還是什么),如果不是的話那么它會將ToDesk.exe殺掉,然后ToDesk_service.exe再重新啟動ToDesk.exe作為子進程。
因為沒有相關的鈎子存在,所以我這里就通過附加的方式來進行調試,這里的話是可以繼續調試的,然后接着就通過相關定位來到加密的過程,雖然找到了相關的加密方式,分析應該是通過了三段的加密方式,但是我發現第一段是自己通過隨機數梅森旋轉算法來生成一段初始的隨機數字節大小為32個字節的數組,接着是通過Salsa20來繼續生成22個字節,這里一共是54個字節,然后第三段的話就是通過這54個字節繼續生成108個字節,這個108個字節就作為密文寫入到config.ini的tempAuthPassEx字段
不太懂相關的算法,它第一步既然是隨機數也不知道如果逆向之后該如何進行解密操作,所以就想去找它本身是如何解密的,本身的解密應該也是在ToDesk中,我是通過兩個調試器來互相進行調試,因為如果Todesk直接調試,它啟動的service會殺掉Todesk,當啟動service就可以通過另外一個調試器來進行附加操作,然后service繼續啟動todesk進程,這個時候將其進程掛起操作,但是我發現最后還是調試不到ToDesk是如何解密密碼然后展示到界面的,所以這個只能留着,因為逆向不是自己主長,希望通過后面的繼續學習然后回頭過來再看看,到時候再看能不能解決,有大佬知道如何操作請告知教教我
ToDesk啟動服務ToDesk_service.exe
004AD932 . FF15 2CF00801 CALL DWORD PTR DS:[<&ADVAPI32.StartServi>; ADVAPI32.StartServiceW
004AD938 . 68 7CFD2001 PUSH ToDesk.0120FD7C ; /String = "controller.start"
004AD93D . FF15 98F50801 CALL DWORD PTR DS:[<&KERNEL32.OutputDebu>; \OutputDebugStringW
004AD943 . 68 DC050000 PUSH 5DC ; /Timeout = 1500. ms
004AD948 . FF15 90F50801 CALL DWORD PTR DS:[<&KERNEL32.Sleep>] ; \Sleep
ToDesk通知ToDesk_service.exe啟動
004AD96A . 50 PUSH EAX ; /pWSAData
004AD96B . 68 02020000 PUSH 202 ; |RequestedVersion = 202 (2.2.)
004AD970 . FF15 38FB0801 CALL DWORD PTR DS:[<&WS2_32.#115>] ; \WSAStartup
004AD976 . 6A 00 PUSH 0 ; /Arg1 = 00000000
004AD978 . 8D8D 60FEFFFF LEA ECX,DWORD PTR SS:[EBP-1A0] ; |
004AD97E . E8 9DB10B00 CALL ToDesk.00568B20 ; \ToDesk.00568B20
004AD983 . FF15 34FB0801 CALL DWORD PTR DS:[<&WS2_32.#116>] ; [WSACleanup
創建文件config.ini
00007FF67C5F8A35 | E8 06F9FFFF | call todesk.7FF67C5F8340 | 創建config.ini
00007FF67C5F8A3A | 84C0 | test al,al | 判斷config.ini是否創建成功
00007FF67C5F8A3C | 0F84 07010000 | je todesk.7FF67C5F8B49 | 成功則不跳轉
加密函數
00007FF67C5F8AB0 | FF50 18 | call qword ptr ds:[rax+18] | 里面有進行相關的算法操作
00007FF67C5F8AB3 | 48:634424 30 | movsxd rax,dword ptr ss:[rsp+30] | eax 0x36 -> 54長度
00007FF67C5F8AB8 | 48:8B9C24 90040000 | mov rbx,qword ptr ss:[rsp+490] |
00007FF67C5F8AC0 | 85C0 | test eax,eax | 判斷加密的長度是否為0
00007FF67C5F8AC2 | 0F84 81000000 | je todesk.7FF67C5F8B49 | 不為0的話不跳轉
00007FF67C5F8AC8 | 4C:8BC0 | mov r8,rax |
00007FF67C5F8ACB | 48:8D5424 60 | lea rdx,qword ptr ss:[rsp+60] | rdx = 上面的CALL加密出來的數據
00007FF67C5F8AD0 | 48:8D4C24 38 | lea rcx,qword ptr ss:[rsp+38] | rcx = 上面的CALL加密出來的數據
00007FF67C5F8AD5 | E8 966AFEFF | call todesk.7FF67C5DF570 | 重要的加密函數
寫入文件
00007FF67C5F8AF1 | 4C:8D4424 38 | lea r8,qword ptr ss:[rsp+38] | r8 = 密文的地址
00007FF67C5F8AF6 | 48:8D15 2B82EF00 | lea rdx,qword ptr ds:[7FF67D4F0D28] | tempAuthPassEx的字段
00007FF67C5F8AFD | 4C:0F434424 38 | cmovae r8,qword ptr ss:[rsp+38] | r8 = 密文的地址
00007FF67C5F8B03 | 48:8D0D A681EF00 | lea rcx,qword ptr ds:[7FF67D4F0CB0] | configInfo的字段頭的信息
00007FF67C5F8B0A | FF15 C89ECE00 | call qword ptr ds:[<&WritePrivateProfil | 寫入到對應的config.ini文件中
過程分析
關鍵CALL 00007FF67C599586 | E8 85F40500 | call <todesk.sub_7FF67C5F8A10> | 創建文件-加密字段-寫入文件-恢復現場
算法一:通過隨機數梅森旋轉算法生成一段大小為32個字節數組A
- 外輪32次,內輪624次,外輪每次最終產生一個字節大小,總共就是32個字節大小
算法二:通過相關的Salsa20流式對稱加密算法一段大小為22個字節數組B
- 生成的22個字節大小的數組B拼接到數組A的后面,36+22個字節,也就是總共為54個字節大小的數組
算法三:將前面大小為54個字節的數組進行加密相關的操作生成一段0x6C大小的字節數組密文
- 總共循環54次,每次循環都會用到一個字節,一個字節有兩段操作,每次一個字節都會經過兩段操作,生成兩個字節,最后填充到一個大小為0x6C的字節數組C中