TeamViewer authentication protocol (part 1 of 3)Posted by Braden Thomas
When a coworker recently gave me access to his system he recommended I use TeamViewer. TeamViewer is a free tool that is used to set up and use a VPN connection as well as allowing the user to remotely take control of another person’s computer from their system. Given that it was my first time using this software, I decided to take a peek at the traffic. TeamViewer’s network traffic was a custom protocol operating on TCP port 5938 and many of the packets began with 0×1724. I initially thought that these were TLS Application Data record packets, since that’s usually the case when I see traffic starting with 0×17. However, since the next byte would be the major version number if it were TLS, and the value I was seeing was 0×24, TLS didn’t make sense. So I set it aside to look at later.
Eventually, I busted out the trusty Hopper Disassembler and set to work on reverse engineering TeamViewer’s Mac OS X binary, focusing on the network protocol. I was most interested in the authentication scheme because my experience was that problems, generally, were likely to exist. By default, TeamViewer auto-generates a 4 digit numeric passcode to authenticate clients that connect to your computer. I was looking for answers to a few basic questions:
- How can they get away with using such a weak passcode?
- What prevents an attacker from brute-forcing the passcode remotely?
- Is the authentication protocol encrypted, or can an attacker snoop on the passcode as it’s transmitted on the wire?
For this analysis, I focused on TeamViewer 7, as it was already installed on my system. However, since TeamViewer 8 was recently released, some of my findings may no longer be relevant.
Initial Protocol Analysis
TeamViewer can operate over raw TCP or HTTP. When it’s operating over HTTP, it appears to layer the TCP protocol on top of HTTP POST requests (although I will admit that I did not investigate the HTTP protocol closely). HTTP is merely a fallback since if it can’t reach the server on TCP port 5938, the default mode is TCP port 5938.
When reverse engineering TeamViewer, I was immediately struck by the complexity of the application. It is a very mature application with extensive functionality, so reverse engineering it was no simple task. However, it does keep a fairly detailed log file in ~/Library/Logs/TeamViewer/TeamViewer7_Logfile.log. Using the log as a starting point, I was able to get my bearings, and began to pull apart the various parts of the protocol, focusing on authentication.
From a binary analysis perspective, the application is a mixed bag: some symbols are present while others are absent. It appears to me that the symbols that are present (the TeamViewer_Helpernamespace) are statically linked from a helper library. The application is written mostly in C++ (with some Objective-C), so methods are mangled, which is a blessing in disguise: even though method names are ugly and obfuscated, they contain far more detailed information than would be present in a standard C-style method name, such as the types of the method arguments. The application also uses standard C++ and Boost objects, and Crypto++.
I began by writing a basic Wireshark Dissector, which you can download here: teamviewer.lua. Once you install the Wireshark Dissector, you will be able to determine which commands are being sent—though not much else, as the dissector is in a fairly nascent state. There are two different high-level command formats: v1 and v2, differentiated by the packet magic (0×1724 vs 0×1130, big-endian). It seems that TeamViewer initially uses v1 commands from client to server, but transitions to more v2 commands in later authentication stages.
While many commands are in clear text, some commands are obfuscated (v1 commands are almost universally obfuscated, though a few v2 commands are also obfuscated). The obfuscation algorithm is extremely simple: when command data is received the bytes are rotated left by one bit, when command data is sent the bytes are rotated right by one bit.
The first stage that a TeamViewer client performs on launch is Network Ping, then Login to the Master server. TeamViewer has multiple Master servers available (master<integer>.teamviewer.com). I’m not sure what rules are used to choose a master server, but my client stuck to just a couple master servers.
Network Ping and Login are very straightforward, and their purpose is to identify the client, and direct it towards a KeepAlive server. Once the client connects with the KeepAlive server, it will establish a persistent session and online presence. The client initiates outbound connections through the Master while the server initiates inbound connections through the open KeepAlive connection.