Advertisments on Russian forums
The researcher @3xp0rtblog discovered T-RAT 2.0 and posted about it on Twitter, including a sample hash and selling threads on Russian forums. One extravagant advertisment is shown below.
The images below show a section each of a 1000x5429 advertisment banner posted on lolz.guru (found and reported by 3xp0rtblog). The Russian text praises comfort and convenience while using T-RAT because it can be controlled via smartphone with Telegram app.
Infection chain and persistence
The first known stage of infection is the downloader[4]. It obtains an encrypted file[6] from hxxps://hgfhhdsf.000webhostapp.com/1DJjnw(dot)jpg and saves it to %TEMP%/gfdggfd.jpg.
For decrypting the payload, the downloader applies XOR with the key 0x01. The resulting file is a ZIP archive which it saves to %TEMP%/hrtghgesd.zip. The downloader proceeds to delete %TEMP%/gfdggfd.jpg and extracts the ZIP archive. Sidenote: Both hardcoded names consist of characters whose keys are right besides each other on a QWERTY keyboard, so the threat actor likely just rolled a body part on the keyboard to create them.
The location of the extracted malware is determined as follows:
1) The downloader checks if the current user has administrator rights. If they have, the first part of the path is one of the following (chosen randomly)
- %APPDATA%\Microsoft\Windows\
- %USERPROFILE%\Windows\System32\
- %LOCALAPPDATA%\Microsoft\Windows\
If they don't have administrator rights, the first part of the path is one of the following
- %SYSTEM%\Microsoft\Protect\
- %COMMONAPPDATA%\Microsoft\Windows\
- %USERPROFILE%\AppData\LocalLow\Microsoft\Windows\
- C:\Windows\assembly\GAC\
2) For the second part of the malware path the downloader generates a random number between 347 and 568203, converts that to a string, then generates the hash either using MD5, SHA1 or SHA256. It uses the hash's hexadecimal representation as second part of the malware path.
The archive contains the actual T-RAT executable, named sihost.exe, as well as several DLLs that the RAT needs. Some notable libraries are the Telegram.Bot.dll and socks5.dll.
A subfolder named service contains six more files (hashes are in the IoC listing):
Filename | Description |
---|---|
conv.exe | High Performance MPEG 1.0/2.0/2.5 Audio Player |
in.exe | RDP Wrapper |
ultravnc.ini | UltraVNC configuration file |
vnchooks.dll | UltraVNC - VNCHooks DLL |
winserv1.exe | VNC Server 32 bit |
winserv2.exe | VNC Server 64 bit |
The downloader persists sihost.exe by scheduling a daily task. The name for the task is the processor ID of the system. If the current user has admin rights, it will set the run level to HIGHEST. Afterwards the downloader deletes itself with the help of a Batch file.
Packer and obfuscator
The original T-RAT sample[1] as well as the downloader[4] are .NET assemblies and packed the same way. The packed part is embedded as base64 string in the overlay of the file. Beginning and end of the strings are marked by the sequence "ghjghjbnv". The packer stub searches the sequence to find the packed image, decodes the base64 string and dynamically loads the resulting .NET assembly.
The unpacked .NET assemblies[2][4] are obfuscated with a variant of ConfuserEx. Some Russian strings are visible but most of the referenced strings are base64 encoded.
After deobfuscating the assembly with NoFuserEx, the base64 encoded strings remain. I wrote a small Python script to do the rest (see Appendix A). It replaces the IL code for calls to FromBase64String with NOPs and replaces the base64 strings with their decoded counterparts. Since the decoded strings are shorter, the remainder is filled with U+200B which is the zero width space Unicode character. (Sidenote: this is a rather lazy solution which does not create a perfectly working executable but is good enough for continuing static analysis.)
The most time-intensive part of deobfuscation for this assembly cannot be automated. The symbol names for methods and classes were eradicated by the obfuscator. So while analysing the code of T-RAT, I added my own names along the way. The code base is comparably on the large side with 98 different commands to control the T-RAT client.
Functionality overview
The attacker controls T-RAT via Telegram using text based commands and command buttons provided by the RAT. The commands are in English, the help messages mostly Russian. One section of the advertisment banner demonstrates the controls and how they look like on the phone (see picture below).
T-RAT has 98 commands. Instead of describing every single command within the main article, I categorized them into groups which are explained below. The full command listing is in Appendix B.
1. Menu navigation
These are commands to enter or exit certain modules like the file manager. They help to make controls via smartphone more convenient.
2. File manager
T-RAT can navigate on the file system, show information about the drives and available space, folder contents and modify files and folders. It can also send files to the attacker. Interestingly it mixes in Unix command names. E.g., the file listing is done with ls.
3. Stealer
This module allows to obtain passwords, cookies, autofill data from browsers, session or config data of Telegram, Discord, Steam, Nord, Viber, Skype and Filezilla. Most of the data files are either saved besides the T-RAT executable in text files or to a ZIP archive in %TEMP%/winsys/ before being sent to Telegram.
4. Clipper
The clipper checks the clipboard for coin addresses and replaces them, thus, any digital currency is sent to the attacker's wallet. It supports Qiwi, WMR, WMZ, WME, WMX, Yandex money, Payeer, CC, BTC, BTCG, Ripple, Doge and Tron. The attackers uses the clipper commands to save their addresses for the specified crypto currency and to start or stop execution of the clipper.
5. Monitoring and spying
Enables the attacker to run a keylogger, create screenshots, record audio via the microphone, take pictures via webcam, send clipboard contents.
6. Evasion
T-RAT has various methods to bypass UAC, including Fodhelper, Cmstp, Cleanup, Computerdefaults. It can disable Windows Defender and Smart Screen notifications. It can disable various security settings, e.g., Association policies can be changed to set ".exe" as a low-risk file extension, and ZoneIdentifiers can be turned off. It has a check for sandboxes and virtual machines.
7. Disruption
These commands kill processes, block websites via the hosts file, block and redirect programs by setting a debugger via Image File Execution Options (for blocking the debugger is one that doesn't exist), disable the taskbar and the task manager.
8. Remote control
T-RAT provides a Powershell or CMD terminal via Telegram. Remote control can also be done via HRDP or VNC.
T-RAT runs the HRDP client named service\in.exe which resides in the executable's location. Then it will create a new user account with a randomized password and name and send the credentials to the attacker. It adds the newly created user to the Remote Desktop Users group and enables remote access by setting fDenyTSConnections to "0".
The VNC server is service\winserv1.exe on 32 bit systems and service\winserv2.exe on 64 bit systems.
Indicators of Compromise
Sample hashes
Sample | Filename | SHA256 |
---|---|---|
[1] T-RAT, packed | Update Service.exe sihost.exe | dfa35a3bed8aa7e30e2f3ad0927fa69adecb5b6f4c8a8535b05c28eacbd0dad8 |
[2] T-RAT, unpacked from [1] | NA | 0388c08ae8bf8204ed609a4730a93a70612d99e66f1d700c2edfb95197ab7cc9 |
[3] ZIP archive containing [1][7-11] | %TEMP%/hrtghgesd.zip | 9fe677aa81790414db3187bba2e159c5aafda6dc0411fbd5d4786b7e596143f3 |
[4] T-RAT downloader | Update Service.exe | b6093289ff0470053bd7dde771fa3a6cd21dae99fc444bfebcd33eb153813263 |
[5] T-RAT downloader, unpacked from [4] | NA | e7604cc2288b27e29f1c0b2aeade1af486daee7b5c17b0478ce336dcdbeee2f1 |
[6] Raw download | 1DJjnw.jpg %TEMP%/gfdggfd.jpg | 27dcb69c1d010da7d1f359523b398e14e0af0dd5bad1a240734a31ffce8b9262 |
[7] Audio Player | conv.exe | 96ba1d40eb85f60a20224e199c18126b160fe165e727b7dee268890dc5148c68 |
[8] RDP Wrap | in.exe | ac92d4c6397eb4451095949ac485ef4ec38501d7bb6f475419529ae67e297753 |
[9] VNC Server | winserv1.exe | c1316ac68d5f3f5ec080d09ffc7c52670a7c42672f0233b9ef50e4b739bd0586 |
[10] VNC Server | winserv2.exe | 912913d897dd2f969fbcbdb54dde82e54f287ade97725380232dce664417c46c |
[11] Ultra VNC Hooks DLL | vnchooks.dll | c8164ccc0cf04df0f111d56d7fb717e6110f8dee77cfc3ef37507f18485af04d |
IoCs for downloader[4]
Download URL | hxxps://hgfhhdsf.000webhostapp.com/1DJjnw.jpg |
---|---|
Download location | %TEMP%/gfdggfd.jpg |
Decrypted download | %TEMP%/hrtghgesd.zip |
Mutex | dwm |
Scheduled task | for sihost.exe[1], task name is the processor ID of infected system |
IoCs for T-RAT[1]
File name | sihost.exe |
---|---|
Mutex | srvhost |
Creates processes | winserv1.exe, winserv2.exe, in.exe |
IFEO Debugger | fghdshdzfhgsdfh.exe |
User account on system | usr[1000-10000], e.g., usr3432 |
Data folder | %TEMP%/winsys/ |
Appendix A: Deobfuscation script
#!/usr/bin/env python2.7
import re
import base64
import sys
import os
import argparse
from shutil import copyfile
def isBase64(s):
try:
return base64.b64encode(base64.b64decode(s)) == s
except Exception:
return False
def searchAndReplace(search, replace, binfile):
content = ""
with open(binfile,"rb") as bif:
content = bif.read()
new_content = content.replace(search, replace)
if new_content == content:
print "Search string not found."
return
with open(binfile,"wb+") as wif:
wif.write(new_content)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Decode and replace base64 strings in binary. Karsten Hahn @ G DATA CyberDefense')
parser.add_argument('str_listing', help='Text file with strings listing of sample. E.g. use Sysinternals strings.exe')
parser.add_argument('sample', help='Sample file where base64 strings should be replaced')
args = parser.parse_args()
inputfile = args.sample
outputfile = args.sample + ".decoded"
copyfile(inputfile, outputfile)
base64Regex = re.compile(r'^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$')
str_listing = args.str_listing
with open(str_listing) as ref_file:
print 'Extracting base64 strings...'
base_strings = []
for line in ref_file:
base_strings += base64Regex.findall(line)
print "Replacing base64 strings..."
for base_str in sorted(base_strings, key=len, reverse=True):
if len(base_str) > 3 and isBase64(base_str):
decoded_string = base64.b64decode(base_str)
decoded_bytes = bytearray(str(decoded_string).decode('utf-8').encode("utf-16le"))
base_bytes = bytearray(str(base_str).decode('utf-8').encode("utf-16le"))
while len(decoded_bytes) < len(base_bytes):
decoded_bytes.extend(b'\x0B\x20')
#print decoded_bytes
searchAndReplace(base_bytes, decoded_bytes, outputfile)
print "Replacing calls to decode Base64..."
# Optional: remove calls to Base64 conversion, this is specific to the sample
# for T-RAT
# searchAndReplace(b'\x28\x27\x00\x00\x0A', b'\x00\x00\x00\x00\x00', outputfile)
# for T-RAT downloader
# searchAndReplace(b'\x28\x17\x00\x00\x0A', b'\x00\x00\x00\x00\x00', outputfile)
print 'All done'
print 'Deobfuscated file written to', outputfile
Appendix B: T-RAT Commands
These are all T-RAT 2.0 commands and a description for some of them.
Command | Description |
---|---|
/help | Print available commands (shows different commands depending on the state of the menu) |
/getscreen | Takes a screenshot and sends as photo to Telegram |
/webcam | Takes a picture using the webcam and sends as photo to Telegram |
/record | Records audio using the microphone. Saves it to record.wav in the executable's folder. |
/sysinfo | Shows: username, IP, MAC, computername, processor model, number of cores, processor size, graphics card model, RAM, operating system, architecture, system directory, antivirus, firewall, drive info and available space |
/isadmin | Checks if executable has admin rights |
/activewindow | |
/openwindows | |
/programs | Shows list of installed programs by obtaining all DisplayName values for all subkeys of SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall |
/processlist | |
/killprocess [process] | |
/run [path] | Creates a hidden folder in %TEMP% named winsys. Puts a VBScript file named <random_digits>.vbs in this folder. The VBScript uses ShellExecute to run the file given in [path] parameter. |
/clipboard | Posts clipboard content to Telegram |
/location | |
/path | |
/blocksite [example google.com] | Blocks a site via hosts file redirection to localhost |
/redirectprogram [first] [second] | Sets the second parameter as debugger for the first via Image File Execution Options (IFEO) |
/blockprogram [name] [block|unblock] | block: Sets a non-existant debugger ("fghdshdzfhgsdfh.exe") for the program via Image File Execution Options (IFEO) |
/CmstpUACBypass | UAC bypass via cmstp.exe |
/CleanupUACBypass | UAC bypass via SilentCleanup |
/FodHelperUACBypass | UAC bypass via fodhelper.exe |
/ComputerDefUACBypass | UAC bypass via computerdefaults.exe |
/OffCertChecking | In Attachment Policies sets: HideZoneInfoOnProperties to "1" and SaveZoneInformation to "2" (= Off) In Associations Policies sets: DefaultFileTypeRisk to "6152" (= Low) and LowRiskFileTypes to ".exe" (yes, only ".exe") |
/DisableWindowsDefender | Disables TamperProtection; enables DisableAntiSpyware, DisableBehaviorMonitoring, DisableOnAccessProtection and DisableScanOnRealtimeEnable |
/OffAvNotification | Disables SmartScreen and sets registry values to "0" for: EnableLUA, ConsentPromptBehaviorAdmin, PromptOnSecureDesktop |
/cmd | Provides a remote cmd terminal |
/powershell | Provides a remote powershell console |
/settings | |
/disconnect | |
/opencd | Calls mciSendStringA with "set cdaudio door open" |
/closecd | Calls mciSendStringA with "set cdaudio door closed" |
/exploreroff | Sets DisableTaskMgr to "1" |
/exploreron | Deletes subkey tree for Software\Microsoft\Windows\CurrentVersion\Policies\System |
/hidetaskbar | Calls user32.dll ShowWindow with SW_HIDE parameter |
/showtaskbar | Calls user32.dll ShowWindow for Shell_TrayWnd |
/wallpaper | Asks the user to send a picture to set as wallpaper |
/collapsewindows | |
/reboot | |
/kill | |
/suicide | |
cd [directory] | Sets working directory |
back | Goes one step back in the command listing |
ls | |
drives | |
action [name] | Provides file operations: info, run, delete, read, send, cd |
mkdir [NameFileInFolder] | Creates a directory |
remove [NameFileInFolder],[AnotherDirectory] | |
rename [NameFileInFolder],[NewName] | |
/hrdp | 1) Runs service\in.exe from executable folder. |
/StartProxyServer | Starts a Socks5 proxy using port 5901 |
/StopProxyServer | Stops above proxy |
/StartVNC | Runs service\winserv1.exe for 32 bit architecture, or service\winserv2.exe for 64 bit architecture. Both reside in the executable folder. |
/StopVNC | Kills any process with a name containing the substring winserv1 (32 bit)or winserv2 (64 bit) |
/CheckVNC | Returns if a process name containing winserv1 or winserv2 exists |
/commands | Menu navigation |
/control | Menu navigation |
/stealer | Menu navigation |
/filemanager | Menu navigation |
/StealPasswords | |
/StealWebData | Searches for Web Data folder in the %LOCALAPPDATA% directory and extracts autofill information. This folder is part of Chrome. |
/StealCookies | Saves cookies to Cookies.txt in the executable folder and uploads it to Telegram |
/GetTelegramSession | Steal Telegram data |
/GetSteamFiles | Steal Steam data |
/GetNordData | Steal Nord data |
/GetFilezillaConfig | Steal Filezilla configuration |
/GetSkypeSession | Saves skype appdata folder contents to %TEMP%/winsys/Skype.zip and uploads this file to Telegram |
/GetDiscordSession | Saves Discord\Local Storage\leveldb folder contents to %TEMP%/winsys/Discord.zip and uploads this to Telegram |
/GetViberSession | Steal Viber data |
/SetQiwi [wallet] | Set Qiwi wallet for clipper |
/SetWMR [wallet] | Set WMR wallet for clipper |
/SetWMZ [wallet] | Set WMZ wallet for clipper |
/SetWME [wallet] | Set WME wallet for clipper |
/SetWMX [wallet] | Set WMX wallet for clipper |
/SetYandexMoney [wallet] | Set Yandex Money wallet for clipper |
/SetCC [wallet] | Set CC wallet for clipper |
/SetPayeer [wallet] | Set Payeer wallet for clipper |
/SetRipple [wallet] | Set Ripple wallet for clipper |
/SetDogechain [wallet] | Set Doge wallet for clipper |
/SetTron [wallet] | Set Tron wallet for clipper |
/SetBTCG [wallet] | Set BTCG wallet for clipper |
/SetBTC [wallet] | Set BTC waller for clipper |
/wallets | |
/SaveConfig | |
/SendConfig | |
/StartScreenLogger | |
/StartKeyLogger | |
/SendLog | |
/StopKeyLogger | |
/SendScreenshots | |
/StopScreenLogger | |
/ClipperStart | |
/ClipperStop | |
/ClipboardLoggerStart | |
/ClipboardLoggerSend | |
/ClipboardLoggerStop | |
/clipboard | |
/functions | |
/exit | Menu navigation |