FTCODE – HOW RECOVER INFECTED FILES

Share on FacebookTweet about this on TwitterPin on PinterestShare on Google+Share on LinkedIn

Public Administrations and companies are undergoing heavy attacks by viruses. They are more often sent through pec, which everyone believes to be safe for being the vehicle of “official” documents.

The story of my company, Aram, is closely linked to a virus and, for this reason, I always welcome with a bit of nostalgia the challenges that they launch to developers. Aram was the first antivirus we created around 30 years ago; the antivirus has also given the name to the company.

These days, to repair this new virus, I faced the “challenge” imposed by a virus again, trying to understand how it works and to find a solution for an infected PC or server.

My aim was to recover the files corrupted by the virus.

HOW TO RECOVER THE INFECTED FILES

The FTCODE ransomware virus – who is it and how it works

The virus I’m talking about is a variant of the FTCODE, a ransomware that started circulating a few years ago. This kind of virus is called ransomware because it contains a file in which is required a “ransom” payment in bitcoin to receive the decryption key. I will not argue on this, as it has already been addressed in another article. Here I want to show you how I came to the solution. From now on the article is technical and therefore it is for developers or IT experts.

If you need to recover the files corrupted by the virus and you are not a technician, please contact us.

HOW TO RECOVER THE INFECTED FILES

How the FTCODE works

At first I tried to understand how this virus works. The pec (or email) received contains an attachment in zip format, with an Office document inside which, if started, runs a macro. This macro launches a downloader saving locally the malware. It generates a password of 50 characters; each character can be a number between 0 and 9 or an uppercase or lowercase character for a total of 62 characters. The password is obviously not saved in the system to prevent a technician (like us) from using it to decrypt the files. Then it generates a unique GUID in the system. The GUID is then sent, together with the newly created password, to the hacker site. This site takes care of storing the GUID / Password pair. This external password storage system allows you to easily retrieve corrupt files if your proxy or gateway manages to store all POST calls. Unfortunately, this is not always the case since most of the time calls are simply stored without the fields sent, where our password would be. I refer, for example, to Squid, in a standard configuration. The malware “works” using the Powershell  of the attacked computer. So certainly from Windows 7 onwards the attack is assured if you open and launch the attachment. 

 

Our technical solution

I read the Powershell code and I see the instruction to generate the password:

$Password = (get-random -count 50 -input (48..57 + 65..90 + 97..122) | foreach-object -begin { $pass = $null } -process {$pass += [char]$_} -end {$pass});

The Get-random statement generates a password of 50 characters long from the three sets:

  • 48..57 (numbers 0-9)
  • 65..90 e 97..122 (characters a-z uppercase and lowercase)


The forced approach would require the use of combinations of a 50-character password with 62 combinations for each character. Recovery would require a few millennium with a normal home computer!

We would have 62^50 combinations, equivalent to

416.470.721.148.178.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000.000

If you know how the “random” function works on any computer, the idea comes to you almost immediately.
Let me explain. The Random function always requires a seed to be initialized. The random function produces sequences of random numbers. Each sequence is different from the other depending on the initial seed.
This is because the computer does not know randomization. It simulates randomization through the random function.

How does it generate a random sequence?

It uses an “automatic” seed, each time different from the previous one. For example, if I ask the system to give me two random numbers they will be 100% two different numbers.
However, if I initialize the random function in both requests with the same seed I’ll get the same sequence of numbers in both cases.
But which number could be defined automatically?
Until PowerShell version 2.0, the number is taken from the TickCount system variable, which is nothing more than the number of milliseconds elapsed since the PC was turned on at the time the request was made.
For later versions this number is generated differently and this recovery model is not applicable. I could analyze this case in the future, if necessary.

HOW TO RECOVER THE INFECTED FILES
Well, Do you want to do a test?
Ok. We open a PowerShell 2 ISE console and type the following instructions:

$Ticks=[Environment]::TickCount

$Password = (get-random -count 50 -input (48..57 + 65..90 + 97..122) | foreach-object -begin { $pass = $null } -process {$pass += [char]$_} -end {$pass});

Write-Output $Ticks

Write-Output $Password

The result will be (on our pc):

23913892

Wa67YJXxidovOrE8stGTbpLzSwghB2MRum1FkZyIPKc40jUHV5

Now we can see what we have obtained.

Throught the first instruction:

$Ticks=[Environment]::TickCount

So we have obtained the milliseconds from the moment we have turned on the pc: 23913892

Subsequently and, most likely, in the same millesimal fraction of a second we calculated the password by calling the Get-Random function.

The result Wa67YJXxidovOrE8stGTbpLzSwghB2MRum1FkZyIPKc40jUHV5 is our password.

Now let’s try re-requesting the password “seeding” the get-random with the value of 23913892.

The returned value will be: Wa67YJXxidovOrE8stGTbpLzSwghB2MRum1FkZyIPKc40jUHV5

See to believe. I remember you that the entire sequence will always be the same, not just the first number.

For example, let’s transcribe the following instructions into a PowerShell script:

$xx=get-random -minimum 100 -maximum 999999 -SetSeed 1950

Write-Output $xx

$xx=get-random -minimum 100 -maximum 999999

Write-Output $xx

The first line initializes the seed with the value 1950 and requests a number between 100 and 999999.

I bet that your PC with PowerShell 2.0 will return the value of 455659!
Then the third line asks for a second random number without initializing the seed.
Even here I bet that the value returned to you is 983630.
So the sequence, with the same number of seeds, is always the same.
Returning to the malware, I notice that the get-random call to generate the password is not the first one but the second one. At the beginning the script downloads from the web the script to infect the computer. The script is temporarily named with a random number.
So the password call is the second one. Good.
Following this logic the main problem is to define which value (TickCount) to use as the initial seed.
The hacker made a second mistake.
In the script it saves some files in the infected PC file system. It stores them precisely in the folder: C:UsersPublicOracleKit.

The file, always the same, is called w00log03.tmp. It contains, just for your information, the GUID code used by the hacker to link the password generated in your PC. But this content is not necessary for the recovery of lost files.
The date and time of creation of this file is our keystone.
Now you have to try to remember the time your computer was turned on or you can read the actual switch-on time from the system events. Then we can roughly define the TickCount value at the activation of the malware.
Let’s move towards a fairly valid range, let’s say about half an hour.
We are talking about around 1,800,000 milliseconds. Much less likely to force the 50-character password.
Then you can write the decryption procedure by taking a corrupt file of which you have also an uncorrupted copy.
If you don’t have this possibility, you should use another technique, a little more complex, but which would surely guarantee the success of recovering the infected files. For example a zip file where the first 4 bytes are always the same.
In our tests we distributed the decryption work on four machines, all more or less with the same CPU performance. We have highlighted a recovery time of about 20/30 seconds every 1000 tests. So the result was 1,800 tests for 30 seconds, divided the four machines.
We calculate 54,000 seconds, 900 minutes: 15 hours in whole. If we divide the total time by the 4 machines we are in the order of 3 hours and a half for each one.
In our case the solution arrives after about 2 hours. The password found, of 50 characters, has therefore also been verified on other files with the same positive result.
From here the following is normal routine: we have recovered all the files on the computer, fortunately for the server we had the backup.
For your information this is the part of PowerShell code, you have to run only in environment 2.0, to perform the file decryption:

function DecryptFile($bytebuffer, $password){

$salt=”BXCODE hack your system”
$init=”BXCODE INIT”
$RijndaelObject = New-Object System.Security.Cryptography.RijndaelManaged
$bytepassword = [Text.Encoding]::UTF8.GetBytes($password)
$salt = [Text.Encoding]::UTF8.GetBytes($salt)
$RijndaelObject.Key = (New-Object Security.Cryptography.PasswordDeriveBytes $bytepassword, $salt, “SHA1”, 5).GetBytes(32)
$RijndaelObject.IV = (New-Object Security.Cryptography.SHA1Managed).ComputeHash( [Text.Encoding]::UTF8.GetBytes($init) )[0..15]

$RijndaelObject.Padding=”Zeros”
$RijndaelObject.Mode=”CBC”
$dy = $RijndaelObject.CreateDecryptor()
$ms = New-Object IO.MemoryStream
$cs = New-Object Security.Cryptography.CryptoStream $ms,$dy,”Write”
$cs.Write($bytebuffer, 0,$bytebuffer.Length)
$cs.Close()
$ms.Close()
$RijndaelObject.Clear()
return $ms.ToArray()
}

$bytebuffer contains either the initial 40960 characters of the file or, in case of  files smaller than 40960, all the characters in the file.
$password is the 50-character password.


If you found that the article about how to recover files corrupted by the virus was useful for you, please share it on your social networks.
If you have any questions or suggestions, enter them in the comments and I’ll answer to you.