Finding TeamViewer 0days. Part 2: Reversing the Authentication Protocol
正在查找 TeamViewer 0 天。第 2 部分:反转身份验证协议
I started reversing the client in order to find how the authentication was being made. I will skip this whole part as I finally ended understanding the authentication method revering the service.
我开始反转客户端,以找出身份验证是如何进行的。我将跳过整个部分,因为我最终结束了对服务的身份验证方法的理解。
Reversing the client was a tedious task because of Overlapped I/O, multiple threads handling it, CFG and so on. This conducted me so many times to rabbit holes and messy routes.
反转客户端是一项繁琐的任务,因为 Overlapped I/O、多个线程处理它、CFG 等。这让我多次陷入兔子洞和凌乱的路线。
I think that showing the reversing process of the client will not contribute worthy to the post, so skipping it to the important part.
我认为展示客户端的倒车过程对这篇文章没有贡献,所以跳过它到重要的部分。
Summarizing the process: 总结过程:
- The client send a challenge in the Authentication Message we saw at part 1.
客户端在我们在第 1 部分看到的 Authentication Message 中发送质询。 - The server responds with its challenge plus the calculated response from client challenge.
服务器使用其质询以及来自客户端质询的计算响应进行响应。 - The client should validate the challenge to detect that is no connecting to a rogue TV service. In our case we can omit this part, we only care about authenticating correctly to the service.
客户端应验证质询以检测是否未连接到流氓电视服务。在我们的例子中,我们可以省略这部分,我们只关心正确地向服务进行身份验证。 - The client calculates the response based on the server challenge and send it in a new message.
客户端根据服务器质询计算响应,并在新消息中发送。
Where To Start? 从哪里开始?
When starting to reverse the client I thought that we had a very nice clue. We known that TeamViewer logs:
当开始反转客户端时,我认为我们有一个非常好的线索。我们知道 TeamViewer 会记录:
2024/05/26 19:03:04.770 3268 3660 S0!! InterProcessNetwork::Received_IPCAuth() invalid response
So, the first thing was to find this string. A simple search string in IDA returned the following cross reference.
所以,第一件事是找到这个字符串。IDA 中的简单搜索字符串返回以下交叉引用。
Pulling back we can reach where the final compare is being made, checking if the response send by the client matches the correct value.
拉回我们可以到达进行最终比较的位置,检查客户端发送的响应是否与正确的值匹配。
Following the process 遵循流程
When studying the process, the following function was the responsible for returning the expected output.
在研究该过程时,以下函数负责返回预期的输出。
I will show the process that this functions follows.
我将展示此函数遵循的过程。
This function is a helper that actually calls another one.
此函数是实际调用另一个函数的 help程序。
We finally ends (after another call to a helper), calling the function that performs all the magic.
我们最终结束(在再次调用帮助程序之后),调用执行所有魔法的函数。
We then end in a loop that calls one function in its body.
然后,我们以一个循环结束,该循环调用其主体中的一个函数。
What is this function peforming?
这个函数执行什么?
I will show you the first lines of the decompiled code.
我将向您展示反编译代码的第一行。
_int64 __fastcall sub_7FF7E93DD240(_DWORD *a1, _DWORD *a2) { [...VARS...] v2 = a1[1]; v3 = a2; v4 = a1[2]; v5 = a1[3]; v6 = a2[5]; v83 = *a2; v85 = a2[1]; v7 = v2 + __ROL4__(*a2 + (v5 ^ v2 & (v4 ^ v5)) + *a1 - 680876936, 7); v80 = a2[2]; v8 = v7 + __ROL4__(v85 + (v4 ^ v7 & (v2 ^ v4)) + v5 - 389564586, 12); v84 = v3[3]; v9 = v8 + __ROL4__(v80 + (v2 ^ v8 & (v7 ^ v2)) + v4 + 606105819, 17); v78 = v3[4]; v10 = v9 + __ROL4__(v84 + (v7 ^ v9 & (v7 ^ v8)) + v2 - 1044525330, 22); v77 = v3[6]; v11 = v10 + __ROL4__(v78 + (v8 ^ v10 & (v9 ^ v8)) + v7 - 176418897, 7); v12 = v11 + __ROL4__(v6 + (v9 ^ v11 & (v10 ^ v9)) + v8 + 1200080426, 12); v13 = v12 + __ROL4__(v77 + (v10 ^ v12 & (v11 ^ v10)) + v9 - 1473231341, 17); |
Do you recognize it? It so, congrats. If not, do not worry, me too at the first time and ChatGPT helped me.
你认得它吗?是的,恭喜。如果没有,别担心,我也是第一次和 ChatGPT 帮助了我。
This is the MD5 Core function. So basically TV is performing MD5 hashing. Let’s take a look at what is being hashed.
这就是 MD5 Core 功能。所以基本上 TV 正在执行 MD5 哈希。让我们来看看正在哈希的内容。
In this example execution of the exploit we received the following challenge.
在这个漏洞利用的执行示例中,我们收到了以下质询。
03 f2 2f ac bc 14 1e e3 42 84 22 e9 55 cc e3 e3
But, when analyzing the parameters passed to the MD5 hashing core function we see the following.
但是,在分析传递给 MD5 哈希核心函数的参数时,我们看到以下内容。
So TV concatenates the challenge the following bytes
因此,TV 将以下字节连接了挑战
40 C2 89 05 3B E8 C1 69 7D 74 D8 36 FC 1D 2F 6E
I have not tested it, but I believe this can be changed with the IPCPassword registry key we saw in part 1.
我还没有测试过它,但我相信这可以使用我们在第 1 部分中看到的 IPCPassword 注册表项来更改。
One important thing, this is the password used by the SERVER challenge.
一件重要的事情,这是 SERVER 挑战使用的密码。
For CLIENT challenges a different one is used: 43 6E 67 62 F2 5E A8 D7 04 E5 22 BF A5 5D A1 6A
对于 CLIENT挑战,使用不同的挑战: 43 6E 67 62 F2 5E A8 D7 04 E5 22 BF A5 5D A1 6A
So basically in order the authenticate we just need to MD5(CHALLENGE+STATIC KEY).
所以基本上为了进行身份验证,我们只需要 MD5(CHALLENGE+STATIC KEY)。
After that we then need to send the ControlIPC indicating the correct PID. I believe that any current process PID could be valid, but I have not tested it. In the exploit the current process PID is sent. Indicating a PID for a non-existent process will make it fail.
之后,我们需要发送指示正确 PID 的 ControlIPC。我相信任何当前的进程 PID 都可能是有效的,但我还没有对其进行测试。在漏洞利用中,发送当前进程 PID。指示不存在的进程的 PID 将导致其失败。
In Part 3 we will have fun writing the exploit and finally use it to elevate privileges.
在 第 3 部分 中,我们将从编写漏洞利用程序的过程中获得乐趣,并最终使用它来提升权限。
原文始发于Peter Gabaldon:Finding TeamViewer 0days – Part II