Analysis of a trojanized anydesk
This blog provides a detailed analysis of anydesk application that has been trojanized and distributed from a ranked unofficial website. The malware has been hitting browsers and stealing bitcoin crypto wallets of multiple vendors. I believe this is a Russian malware since it is targeting everyone excluding Russia and some neighboring countries like Belarus and Kazakh.
It all started when I came across a tweet saying a trojanized anydesk version has been circulating in the wild. I was very interested since I am also a frequent user of anydesk. I searched around a little bit and found that the malware has been distributed from an unofficial domain called as www.anydesk.computer, yet the official domain is www.anydesk.com. I downloaded the malicious installer. Opened my Windows 10 VM with IDA pro, process hacker and procmon installed in it and started exploring this installer. With the help of procmon, I found that the installer extracts two files, one is the anydesk1.exe, which is the actual malware and deletes itself after the execution. I quickly made a copy of it for further analysis. The second file was anydesk2.exe, which I believe is the genuine anydesk software application. It works in such a way that the malware executes itself and deletes the evidences leaving only the original anydesk binary so that the user won’t get suspicious.
The installer was trojanized in such a way that it extracted malware along with the real application and executed the malware. I checked the integrity of the second anydesk2.exe by binary diffing the malware exe with the anydesk exe downloaded from the official website. There was no difference in the code or assembly of both versions, which means that the second file is the genuine anydesk software. So I will only do analysis on anydesk1.exe further in this blog.
When I disassembled and decompiled the malware, the first look gave me the impression that it will be very simple malware. It is simple to some extent but there were areas which really gave me tough time. Let us walk down the rigid path of analyzing stripped and obfuscated malware binaries, in this case anydesk1.exe. On the entry point or start function, there are multiple checks that can be considered anti-reverse engineering techniques to bypass sandboxes or VM’s. Once the malware had successfully passed those functions, then it will come to the real TTPs (Tactics, techniques, and procedures), a MITRE term every cybersecurity researcher must be familiar with.
The first and second function were used to indirectly import multiple APIs. The function call obfuscation method used here was indirectly loading the external dlls through LoadLibraryA and the external APIs using GetProcAddress. An example of function call obfuscation could be seen in the screenshot below where, the malware is importing multiple dlls and function APIs
Now the malware checks certain conditions that would decide weather this malware must execute or exit the execution process. The very fist check was sort of like an anti-VM technique. I’m assuming it was to check the processing speed of the virtual machine and compare it with the real-time. So, if the difference crossed a certain threshold, then malware decides that this is not a virtual machine and continue further execution. The first function dword_417A50 contains the address of GetTickCount and the second function dword_417874 contains the address of Sleep.
The second function was a very clear yet very confusing at the same time. It was just checking the desktop name and the username of computer and comparing with some predefined strings. If the string match, the malware stops further execution, if not then it continues.
This particular function didn’t make any sense to me. Why would the malware look for such a specific computer name with such a generic username? I searched around the internet and came across a tweet which made all sense. Apparently, this specific computer name and username is used by Microsoft Defender’s emulator to test a suspicious binary in their sandboxed environment. It was a kind of anti-sandbox techniques used to bypass detection from Microsoft Windows Defender.
The third check before executing actual malicious functionality is somewhat interesting. This function gets the language ID from computer and compares it with some of the specified language IDs. If any of them matches, then the execution of malware stops, and exits. Basically, the malware will execute in every computer except the listed countries. I believe this may be a Russian malware since it’s not targeting its own country and the countries close to Russia.
If we look up these language IDs on Microsoft Documentation page MSDN, we can see which countries are excluded from infection by this malware. Those 5 languages are listed below:
- Uzbek (1091)
- Azeri (2092)
- Kazakh (1087)
- Russian (1049)
- Belarusian (1059)
After all these checks had been bypassed. The real malware execution begins where the first function contains hundreds of encoded strings. In a reverse engineering, the thing that makes the most sense are the strings. I believe if the strings are properly decoded, 70% of malware intent is exposed. We can easily make sense of what the malware is doing. So, the first step, is to try and decode these encoded strings. For that we need to know which type of encoding has been used?
The function responsible for decoding these strings is sub_403C70. The first thing I tried to do is to write a decoder for these strings so that I can reverse engineer the malware in static analysis only and no need of dynamic analysis is required. I decompiled the decoder function and found that there are multiple layers of decoding being done like the first 2 functions are allocating some buffer and decoding strings using the API CryptStringToBinaryA. At first, I thought that it might only be a single layer encoding like most of the malware and I wrote a decoder using the same API and same encoding which is Base64 without headers.
In the code snippet above, we can see that a function is being called that takes 7 parameters and same function has been called twice. This function is CrypytStringToBinaryA. I wrote same decoder to see weather the strings are properly being decoded or not?
However, it looks like this is just a first step for decoding these strings. A custom encoding has been used. I tried to complete the decoder, but the next code snippets looked very very tricky and could take a lot of time to understand the code. Look at the screenshot below
Looking at such a tricky code, I gave up doing static analysis only. I decided to decode the strings in dynamic analysis which would save me a lot of time. So, I shifted the binary in a Windows 10 VM, attached windows local debugger. Added the breakpoint to the decoder and started decoding these strings one by one. I had gone through a lot of strings, there are probably more than 400 strings. I decoded half of those and understood that it was a trojan that downloads some malicious file and steals browser cookies and passwords. I’ve added comments in the IDA database, some of the decoded strings are given below:
After decoding the strings, I continued with my dynamic analysis and found that next function indirectly imports all the libraries that have been decoded from the strings. Some of the loaded modules are listed below:
The malware loaded these libraries and resolved hundreds of function address using GetProcAddress. The very last function opens a pandora’s box of multiple functions that does further exploitation. The malware downloads another file called sqlite3.dll which is used to fetch the database files from local databases of browsers. This database often contains cookies and passwords stored in the browsers. The c2 server from which it downloads the sqlite3.dll file is www.box525.bluehost.com using TCP connection on port 80. It saves the file in C:\ProgramData\sqlite3.dll. The function that downloads this file is Sub_403D20.
After the file has been downloaded, it loads the downloaded dll file using LoadLibraryA from the download path and gets some function addresses from the binary using GetProcAddress. The function that loads this malicious dll module is sub_405DE0.
There is another c2 server that I’ve also noticed during my dynamic analysis, when the malware created connection to another domain known as www.panel.computer as shown in the screenshot. I believe this is also used for sending computer information and exfiltrating stolen data.
In the next function sub_409090, the malware is looking for different browsers and then looking for specific logins and cookies to steal in each browser database information. The malware is looking for all different browsers like chrome, chromium, Microsoft edge, firefox, opera and others.
The VM that I tested this malware doesn’t have chrome installed in it therefore, all the paths that normally chrome have its database will show that they are not found. In the events captured by Process Monitor (procmon) shows us the malware is looking for chrome database in AppData where the cookies or credentials are stored normally.
The malware looks for only crypto coin wallets and steal specified credentials and passwords. I’ve debugged the program further and found that for every browser it looks for multiple crypto wallets. If it doesn’t find any wallets, then it moves on to the next browser. If it found something, then it creates a temporary file and collect data for exfiltration. In the screenshot below, it is looking for multiple types of crypto wallets for stealing their credentials and cookies.
These are only a few of the wallets that it is looking for. The list of all the crypto wallets that it tries to steal are provided in the list below:
- Guarda
- Coinbase wallet
- Math wallet
- Nifty wallet
- Yoroi
- Saturn wallet
- Binance chain wallet
- Jaxx liberty
- GuildWallet
- Mew CX
- iWallet
- BitApp wallet
- Equal wallet
- Ronin wallet
- Neoline
- Clover wallet
- Liquality wallet
- Terra station
- Kepler
- Sollet
- Cyano wallet
- Onekey
- Dappplay
- Steem keychain
- Hycon lite wallet
- Coin98 wallet
- Authy
- GAuth authenticator
- Auro wallet
- Polymesh
- ICONex
- Nabox wallet
- KHC
- Temple
- TezBox
- Byone
- Leaf wallet
- Bitclip
- Nash Extension
- Ziplay
- Authenticator
- EOS Authentication
- Trezor Password Manager
For Microsoft Edge, the malware accessed the paths where its database is stored and copied the database file to path where malware has executed itself. Once the file has been copied there then it tries to collect and steal data using sqlite3.dll for exfiltration.
In case of Microsoft Edge it copied the browser history file for querying to extract the required data which in this case are the provided crypto wallets. However, for some reason after it downloaded the sqlite3.dll file it cannot load it using the LoadLibraryA function and therefore the program crashes when it tires to find wallets in this database file.
The reason for this is because the sqlite3.dll file is corrupted. Because it is a custom created file for stealing browsers data, so the attacker changed the file with dummy file when the exploit got caught. That is what I am assuming. I tried to load sqlite3.dll file in IDA pro but it can not detect this as a portable executable file and even the size is only 1 kb. The attackers replaced the real malicious file with the dummy file on their c2 server. However, our analysis of anydesk1.exe has been successful because we uncovered all the TTPs and exposed the intent of this trojanized software. It was used to steal crypto wallets from multiple browsers. Malware targets everyone except some specific languages that includes Russia and neighboring countries, which gave me a hint that this might be linked to a Russian hacker group.
For analysis, if a sample is required. Please email me at shayanjadoon.sj@gmail.com
Thank you!