Trickbot rdpscanDll – Transforming Candidate Credentials for Brute-Forcing RDP Servers

After some weeks of not seeing the RDP scanner module of Trickbot, I recently observed that the module was again distributed among the bots in our tracking lab. Since Bitdefender already published a report on the module in March 2020, I focused on checking whether or not the command-and-control (C2) communication of the module remained more or less the same or if there was anything groundbreakingly new. Short answer: there wasn’t. There may be some under-the-hood fixes or improvements but I (as of yet) did not stumble upon anything significant that wasn’t already found by Bitdefender: the module still receives its mode of action, target servers, usernames, and password candidates from the C2 server and then does what the mode tells it to do. But while I was checking that, I also had a look at the actual data that we received from the C2 server.

Password List

My intuition on the password list was that it is just a dictionary of words to try. This is also suggested by the URL which is used to retrieve the password list: hxxps://%c2%/%gtag%/%bot_id%/rdp/dict. Thus I did not have a closer look at the password list at that time, because everything looked the way Bitdefender described it and I had no reason to look at it in detail. But one or two days later, I re-requested the list of passwords to see whether the list changed in the meantime – and it did indeed. Because of that I had a quick look at what changed and then I noticed that I overlooked something right from the start (literally, duh!). On the left side of the picture you see what I had a quick look at after retrieving the password list from the C2 server with curl (and thus seeing only the last lines of the output). On the right side there is the very same password list, just seen from the start.

trickbot_passwordlist

To the keen eye it seems that they may be using some kind of templating mechanism to adjust the list of passwords and use more specific credential candidates. With that thought in mind I spun up my analysis environment and started digging into the module to see what the Trickbot gang is actually doing there (spoiler: yes, they do some kind of templating – but not just the find-and-replace kind).

Transforming them P@ssw0rds

As mentioned before, this is not a simple find-and-replace but instead they can change the credential candidates to better fit the attacked host. In that sense, I decided to call those things transforms instead of templates because they are not just templates that are filled out but a little bit more dynamic. Example:

  • %username%123 → myuser123 (lowercase)
  • %Username%123 → Myuser123 (lowercase but first char uppercase)
  • %UsErNaMe%123 → MyUsEr123 (alternating case, starting with uppercase char)
  • %EMANRESU%123 → RESUYM123 (uppercase and reversed)

And that is essentially how the markers in the password list work. I was able to extract all 91 transformations that are currently available to the rdpscanDll (as of 2020-08-14). Please find the list with all transforms with an example and a description for each of them at the end of this blog post.

Some of the transforms can even be parameterized to a certain degree: %OriginalUsername%, %OriginalDomain%, and %domain% can be prepended or appended with an (N) to indicate whether the first N or last N characters of the element should be used (or everything if no parameters are present).

Reconnaissance

After finding the list of transforms, I decided to ask my favorite internet search engine whether these names for the transforms are known related to RDP. And I indeed found a RDP brute force tool by a certain z668 which seemingly makes use of some of the transforms that are used in the rdpscanDll. Although this tool seems to be a standalone application, the names of the transforms and the context of their use could suggest a connection between z668 and the Trickbot gang – at least to a certain degree. Sure, the connection may not be really strong because the Trickbot module is written in C++ and the RDP tool seems to be written in C#. But given the fact that C# can load and use native DLLs and considering that z668 forked the FreeRDP project on Github, the actual scanner may indeed be written in C/C++ (and probably using FreeRDP). Thus it is possible that the Trickbot gang may have obtained the source code from z668 to integrate the RDP scanner into their module framework and to use their C2 communication protocol. But: this is just guessing based on some more or less loose facts – I could easily be completely wrong with that.

Transform List

Transform Identifier Example Description
EmptyPass tries an empty password
GetHost fills in the hostname of the currently attacked IP (ex: myhost)
IP the currently attacked IP address (ex: 234.234.234.234)
Port fills in the currently attacked port (ex: 3389)
IpReplaceDot 234.234.234.234 → 234234234234 remove the dots of the IP address
RemoveNumerics us3rn4me → usrnme removes all number from the username
RemoveLetters us3rn4m3 → 343 removes all letters from the username
RemoveOtherSymbols usern@m3 → usernm3 removes all non-alphanumeric characters from the username
OriginalUsernameLettersBeginInverse 123admin456 → 123654nimda keeps all non-letters (i.e. digits, special chars) at the beginning of the username and reverses the rest (“invert [from where] letters begin
OriginalUsernameLettersBeginSwap 123admin456 → admin456123 swaps all non-letters (i.e. digits, special chars) at the beginning of the username with the rest (“swap [where] letters begin”)
OriginalUsernameLettersEndInverse admin123root → admintoor321 keeps all letters at the beginning of the username and reverses the rest (“invert [where] letters end”)
OriginalUsernameLettersEndSwap admin123root → 123rootadmin swaps all letters at the beginning of the username with the rest (“swap [where] letters end”)
OriginalUsernameNumsBeginInverse admin123root → admintoor321 keeps all non-digits at the beginning of the username and reverses the rest (“invert [from where] nums begin
OriginalUsernameNumsBeginSwap admin123root → admintoor321 swaps all non-digits at the beginning of the username with the rest (“swap [where] nums begin”)
OriginalUsernameNumsEndInverse 123admin → 123nimda keeps all digits at the beginning of the username and reverses the rest (“invert [where] nums end”)
OriginalUsernameNumsEndSwap 123admin456 → admin456123 swaps all digits at the beginning of the username with the rest (“swap [where] nums end”)
OriginalUsernameInsert %OriginalUsernameInsert%(N)SOMESTRING → SOMEusernameSTRING (ex: N = 4) insert username after Nth character of SOMESTRING
OriginalUsername use the username as password
OnlyName Firstname Lastname → Firstname uses only the first name (everything left of the first space) of the username as password
OnlySurname Firstname Lastname → Lastname uses only the last name (everything right of the first space) of the username as password
username Admin → admin username in lowercase
Username AdMin → Admin username lowercase but first char upper
UsErNaMe Admin → AdMiN username in alternating case, starting with uppercase
uSeRnAmE Admin → aDmIn username in alternating case, starting with lowercase
USERNAME Admin → ADMIN username in uppercase
EMANRESU Admin → NIMDA username in uppercase and reversed
EmanresuLowercase AdMin → Nimda username reversed and lowercase, first char uppercase
Emanresu AdMin → NiMdA username reversed, first char upper
emanresuLowercase AdMin → nimda username reversed and lowercase
emanresuUppercase AdMin → NIMDA username reversed and uppercase
emanresu Admin → nimda username reversed and lowercase
ReplaceFirst_X-x administrator → @dministrator (ex: %ReplaceFirst_a-@%) replaces the first occurrence of X with x in the username (needle and replacement can be more than 1 char)
ReplaceFirstI_X-x Administrator → @dministrator (ex: %ReplaceFirstI_a-@%) case insensitively replaces the first occurrence of X with x in the username (needle and replacement can be more than 1 char)
ReplaceLast_X-x administrator → @dministrator (ex: %ReplaceLast_a-@%) replaces the last occurrence of X with x in the username (needle and replacement can be more than 1 char)
ReplaceLastI_X-x Administrator → @dministrator (ex: %ReplaceLastI_a-@%) case insensitively replaces the last occurrence of X with x in the username (needle and replacement can be more than 1 char)
ReplaceAll_X-x administrator → @dministrator (ex: %ReplaceAll_a-@%) replaces all occurrences of X with x in the username (needle and replacement can be more than 1 char)
ReplaceAllI_X-x Administrator → @dministrator (ex: %ReplaceAllI_a-@%) case insensitively replaces all occurrences of X with x in the username (needle and replacement can be more than 1 char)
DomainRemoveNumerics test-123.com → test-.com removes all digits from the domain
DomainRemoveLetters test-123.com → -123. removes all letters from the domain
DomainRemoveOtherSymbols test-123.com → test123com removes all non-alphanum chars from the domain
OriginaldomainInsert %OriginaldomainInsert%(N)SOMESTRING → SOMEdomainSTRING (ex: N = 4) insert domain after Nth character of SOMESTRING
OriginaldomainPart test-123.com → 123com (ex: %OriginaldomainPart%(6)) takes the last N chars of the domain name (ignoring any dots)
OriginaldomainNumsBeginInverse test-123.com → test-moc.321 keeps all non-digits at the beginning of the domain and reverses the rest (“invert [from where] nums begin
OriginaldomainNumsBeginSwap test-123.com → 123.comtest- swaps all non-digits at the beginning of the domain with the rest (“swap [where] nums begin”)
OriginaldomainNumsEndInverse 123-test.com → 123moc.tset- keeps all digits at the beginning of the domain and reverses the rest (“invert [where] nums end”)
OriginaldomainNumsEndSwap 123-test.com → -test.com123 swaps all digits at the beginning of the domain with the rest (“swap [where] nums end”)
OriginaldomainLettersBeginInverse test-123.com → test-moc.321 keeps all non-letters (i.e. digits, special chars) at the beginning of the domain and reverses the rest (“invert [from where] letters begin
OriginaldomainLettersBeginSwap 123-test.com → test.com123- swaps all non-letters (i.e. digits, special chars) at the beginning of the domain with the rest (“swap [where] letters begin”)
OriginaldomainLettersEndInverse test-123.com → testmoc.321- keeps all letters at the beginning of the domain and reverses the rest (“invert [where] letters end”)
OriginaldomainLettersEndSwap test-123.com → -123.comtest swaps all letters at the beginning of the domain with the rest (“swap [where] letters end”)
Originaldomainleft test-123.com → test-123 takes the left part of the domain (everything left of the first dot) and lowercases the first character
OriginalDomainleft test-123.com → Test-123 takes the left part of the domain (everything left of the first dot) and capitalizes the first character
Originaldomainright test-123.com → test-123 takes the right part of the domain (everything right of the first dot) and lowercases the first character
OriginalDomainright test-123.com → Test-123 takes the right part of the domain (everything right of the first dot) and capitalizes the first character
Originaldomain uses the plain domain name
OriginalDomain test-123.com → Test-123.com uses the domain name and capitalizes the first character
NiamodLowercase abc%NiamodLowercase%123 abc123
niamodLowercase test-123.com → Moc.321-tset reverses and lowercases the domain name, first character capitalized
niamodUppercase test-123.com → mOC.312-TSET reverses and capitalizes the domain name, first char lowercase
domainleftHyphen test-123.com → test takes everything left of the first hyphen
DOMAINLEFTHYPHEN test-123.com → TEST takes everything left of the first hyphen, capitalized
DomainleftHyphen test-123.com → Test takes everything left of the first hyphen, first char capitalized
domainrightHyphen test-123.com → 123.com takes everything right of the first hyphen
DOMAINRIGHTHYPHEN test-123.com → 123.COM takes everything right of the first hyphen, capitalized
DomainrightHyphen test-abc.com → Abc.com takes everything right of the first hyphen, first char capitalized
domainleftUnderscore test_123.com → test takes everything left of the first underscore
DOMAINLEFTUNDERSCORE test_123.com → TEST takes everything left of the first underscore, capitalized
DomainleftUnderscore test_123.com → Test takes everything left of the first underscore, first char capitalized
domainrightUnderscore test_abc.com → abc.com takes everything right of the first underscore
DOMAINRIGHTUNDERSCORE test_123.com → 123.COM takes everything right of the first underscore, capitalized
DomainrightUnderscore test_abc.com → Abc.com takes everything right of the first underscore, first char capitalized
DomainReplaceFirst_X-x EXAMPLE-attack.com → EXAMPLE-@ttack.com (ex: %DomainReplaceFirst_a-@%) replaces the first occurrence of X with x in the domain (needle and replacement can be more than 1 char)
DomainReplaceFirstI_X-x EXAMPLE-attack.com → EX@MPLE-attack.com (ex: %DomainReplaceFirstI_a-@%) case insensitively replaces the first occurrence of X with x in the domain (needle and replacement can be more than 1 char)
DomainReplaceLast_X-x EXAMPLE-attack.com → EXAMPLE-att@ck.com (ex: %DomainReplaceLast_a-@%) replaces the last occurrence of X with x in the domain (needle and replacement can be more than 1 char)
DomainReplaceLastI_X-x EXAMPLE-attack.com → EXAMPLE-att@ck.com (ex: %DomainReplaceLastI_a-@%) case insensitively replaces the last occurrence of X with x in the domain (needle and replacement can be more than 1 char)
DomainReplaceAll_X-x EXAMPLE-attack.com → EXAMPLE-@tt@ck.com (ex: %DomainReplaceAll_a-@%) replaces all occurrences of X with x in the domain (needle and replacement can be more than 1 char)
DomainReplaceAllI_X-x EXAMPLE-attack.com → EX@MPLE-@tt@ck.com (ex: %DomainReplaceAllI_a-@%) case insensitively replaces all occurrences of X with x in the domain (needle and replacement can be more than 1 char)
niamod test-123.com → moc.321-tset reverses the domain name
Niamod test-123.com → Moc.321-tset reverses the domain name, first char capitalized
domainleft TEST-123.com → test-123 everything left of the first dot, lowercased
DOMAINLEFT Test-123.com → TEST-123 everything left of the first dor, capitalized
Domainleft test-123.com → Test-123 everything left of the first dot, lowercased but first char capitalized
domainright TEST-123.com → com everything right of the first dot, lowercased
DOMAINRIGHT Test-123.com → COM everything right of the first dor, capitalized
Domainright test-123.com → Com everything right of the first dot, lowercased but first char capitalized
domain TEST-123.com → test-123.com domain name, lowercase
Domain TEST-123.com domain name lowercased, first char capitalized
DoMaIn test-123.com → TeSt-123.cOm domain name in alternating case, starting with uppercase
dOmAiN test-123.com → tEsT-123.CoM domain name in alternating case, starting with lowercase
DOMAIN test-123.com → TEST-123.COM domain name capitalized
NIAMOD test-123.com → MOC.321-TSET domain name reversed and capitalized

Emotet drops ZeuS Panda targeting German and Austrian online banking users

Emotet is currently one of the prevalent threats on the Internet. The former banking trojan is now known to steal passwords and to drop other malware like Dridex on its infected machines. We recently found Emotet spreading Zeus Panda, which presented us with an opportunity to link some of our research on Emotet with our analysis of ZeuS Panda.  The Zeus Panda sample used in this wave is rolled out through Emotet in german-speaking countries and targets online banking users in Germany and Austria.

The Emotet C2 server drops additional malware to infected system. Whether a system receives such a package seems to be based on the geographical location of the infected system in question. After the additional malware is downloaded from the C2 server, it is written to a file in %ALLUSERSPROFILE% (C:\ProgramData in recent Windows versions) with a random name of 4 to 19 characters length and the file extension “.exe”. Emotet is capable of executing this binary in two different ways, either of which is chosen by the C2 server. The first mode executes the malware in the same context that Emotet is running in, the second mode executes the malware in the context of the currently logged-on user.

As stated above, the current wave downloads and executes the well-known ZeuS Panda banking trojan. To know which banking sites it should attack and how to modify the site’s content, the trojan needs so-called webinjects. From the URL masks of the webinjects this sample uses, we can tell that it currently targets online banking customers in Germany and Austria. All injects write a single script reference into the targeted websites. When the targeted site is loaded, the browser loads the referenced script, which is then executed in the context of the banking website. The only difference between the webinjects is the last number in the URL of the script source. This number seems to define the targeted website, which allows the server to deliver a target-specific script. The script actually downloaded is obfuscated by a simple string encryption. The actual script is part of an Automated Transfer System (ATS) which tries to persuade the user into transferring money to an account the attacker specifies.

scriptSchutzanalageRetoureThe above screenshots show an exemplary representation on the modification of the banking websites. They show two different attack scenarios: The first script tries to trick the user into performing an transaction in the guise of a security check. The attackers “inform” the customer of newly installed security measures on the banking website, coercing the user to complete a training using a demo account, before they are able to access their account again. During this training, a real transaction is made in the background to an account that the attacker specifies. The phrasing in the text is lousy and should raise suspicion with most customers.

 

The second script tries to persuade the user that an erroneous transfer was made to their account. It suggests to go to a bank branch or make the return transfer online. Additionally, the script blocks access to the banking account until the return transfer has been completed. The phrasing in the text is better than in the first script and may not raise suspicion at first glance.

The first script resembles word by word the webinject Kaspersky identified during their analysis of Emotet in 2015. At this time Emotet contained its own banking trojan capability and delivered the webinjects directly into the browser. As ZeuS Panda uses the same webinject format as the old Emotet, we can speculate about the reasons:

  • The webinject is acquired from the same creator
  • The group behind Emotet has dropped developing their own banking trojan and acquires such trojans from other malware authors
  • The group behind Emotet developed multiple banking trojans for its own use and for sale

It seems Emotet is not only used to sell distribution of malware, but also used by its owners. It is also possible that the group behind Emotet uses the slim downloader as an entry point for targeted attacks. In this case the group can spread Emotet worldwide and distribute specific malware to each target. As the real malicious payload is only downloaded after some time and only to specific targets, analysts can not directly draw conclusions on the real intention of an infection.

IOCs

Emotet:

C2:

5.9.195.154
45.73.17.164
60.32.214.242
85.25.33.71
194.88.246.242
213.192.1.170
217.13.106.16
217.13.106.246
217.13.106.249

SHA256:

0d25cde8d49e1bcf6a967c0df6ac76992ff129ea5c30a1492a5bedd313e6fb51
c287a9aa25ed6afc54bc5ebe4b098675f3fa4b7cb51fbdcfb50591b4b8fa3b90

ZeuS Panda:

C2:

uamanshe.gdn
ugjeptpyour.top

SHA256:

4fe20a9cf5e5c28ec55aa529179f7fe6df3cda8ae43340b04b2402f43dfefd5f
fbd9e31cc5cbfce2b8135234fdcfdac7fa48a127aa6f3644d05c6ba77bd6d903

Zeus Panda: Down To The Roots

Some time ago, we analyzed Panda’s webinjects to get an insight in how they actually work and to understand their communication with the ATS servers (read it here: part 1, part 2).

In the last few weeks, we drilled down on the binary itself and had a closer look on this side of the Zeus.Panda malware. In the resulting whitepaper, we present a more in-depth analysis of the malware executable, detailing the malware’s actions on the victim’s PC beyond and in addition to infecting browsers to enable fraudulent banking transactions.

Find the whitepaper here (pdf).