A forum for reverse engineering, OS internals and malware analysis 

Forum for analysis and discussion about malware.
 #12672  by Fabian Wosar
 Fri Apr 13, 2012 10:28 am
People looking for information may want to take a look here:
http://blog.emsisoft.com/2012/04/11/the ... s-servers/
Blaze wrote:Anyone knows why it's called ACCDFISA ?
It is named differently by different vendors. We decided to call it ACCDFISA because that is the name of the fake government agency the malware used to scare the user into paying. It consequently became the term people used most to find information about it via Google. Later variants dropped the ACCDFISA name, but it stuck since those variants clearly are related.
Blaze wrote:Is it AES encryption or is the RSA encryption algorithm being used ? (like the GPcode ransom)
It uses AES-256 through WinRAR. So it doesn't implement any encryption itself but uses the command line version of RAR to move files into encrypted archives. The password generation changed from variant to variant. The first variant used a static password/unlock code. The second variant generated a password based on the boot drive's volume id. The volume id is therefore interpreted as a signed 4 byte integer and converted into a string. Any leading minus signs are then removed from the string and the static string "001" is prepended. The resulting id (it's the same that is displayed in the ransom notice) is then passed through a primitive substitution "cipher" (twice for the screen locker unlock code). The resulting "password" is then usually prepended or appended with static strings. The exact routines for the second variant look something like this in Delphi:
Code: Select all
function GetPassword(id : string) : string;
var
  i : Integer;
begin
  for i := 1 to Length(id) do
    case id[i] of
      '1' : Result := Result + 'w';
      '2' : Result := Result + 'N';
      '3' : Result := Result + 'x';
      '4' : Result := Result + 'Z';
      '5' : Result := Result + 'u';
      '6' : Result := Result + 'S';
      '7' : Result := Result + 't';
      '8' : Result := Result + 'Y';
      '9' : Result := Result + 'm';
      '0' : Result := Result + 'a';
    end;
end;

function GetRarDecryptionPassword(id : string) : string;
const
  passwordPrefix = 'aes987156';
  passwordPostfix = 'tH2z4s872qw6sPsXz871ldv5Zt3Fk';
begin
  Result := Format('%s%s%s', [passwordPrefix, GetPassword(id), passwordPostfix]);
end;

function GetScreenUnlockPassword(id : string) : string;
const
  passwordPrefix = '7655715214';
var
  i : Integer;
  variablePart : string;
  password : string;
begin
  variablePart := '';
  password := GetPassword(id);

  for i := 1 to Length(password) do
    case password[i] of
      'w' : variablePart := variablePart + '7';
      'N' : variablePart := variablePart + '1';
      'x' : variablePart := variablePart + '9';
      'Z' : variablePart := variablePart + '8';
      'u' : variablePart := variablePart + '3';
      'S' : variablePart := variablePart + '7';
      't' : variablePart := variablePart + '5';
      'Y' : variablePart := variablePart + '3';
      'm' : variablePart := variablePart + '2';
      'a' : variablePart := variablePart + '0';
    end;
  Result := Format('%s%s', [passwordPrefix, variablePart]);
end;
The third variant uses randomly generated passwords. To generate such a password it will essentially generate a large numeric string. The numeric string is generated like this (pseudo code):
Code: Select all
NumericString = Str(Int64(Random(1000000) * Random(100000) * Random(10000))) + Str(Int64(Random(1000000) * Random(100000) * Random(10000))) + Str(Int64(Random(1000000) * Random(100000) * Random(10000)));
The pseudo random number generator is seeded once with the current thread id and the current tick count (RandSeed = GetCurrentThreadId() ^GetCurrentTickCount() to be more precise). The resulting numeric string is then passed to a substitution cipher that is similar to the one used in variant 2. The substitution matrix changed and looks something like this now: 1 -> A, 2 -> n, 3 -> F, 4 -> r, 5 -> V, 6 -> t, 7 -> L, 8 -> q, w -> 9 and 0 -> u. To get the final password the static string xcqT100 is prepended. The large numeric string is also saved to two different files (msdadiags.dll as well as rvid1000.txt) so the malware uses the same numeric string in consecutive runs. You may ask why victims can't just use the numeric string from there to generate their passwords. The problem is that the attackers will use two different numeric strings. After the initial infect and the first "encryption" run the attackers will remove both files from the system and move them to their systems. This will cause the malware to generate a new numeric string used for password generation for all encryptions after this. The result is that all files that existed at the time of the infection are encrypted with the password based on the first numeric string, that was later deleted and all files encrypted after the initial infection are encrypted with a second password based on a second numeric string that stays on the system. It is possible to get the second password, but impossible to get the first unless you manage to restore the deleted files restoring the numeric strings.

The fourth (and newest) variant uses randomly generated as well as a computed passwords . Again two passwords are used to encrypt the files that existed at the time of infection and to encrypt files since then. The first password is generated without the substitution cipher this time. Its generation essentially looks something like this (pseudo code):
Code: Select all
char characterTable[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*&*()-+_=";
string password = "aesT322";
for (int i = 0; i < 50; i++)
{
    password += characterTable[Random(Length(characterTable))];
}
The second password is generated similar to the one in variant 2. A numeric string based on the boot drive's volume id is generated and run through a substitution cipher. I haven't looked into how the volume id is converted into the numeric string yet since I haven't had time. If one of you wants to knock himself out: It is located at address 0x00403C3B. The substitution matrix used in the substitution cipher is: 1 -> A, 2 -> $, 3 -> F, 4 -> r, 5-> V, 6-> *, 7 -> L, 8 -> q, 9 -> w and 0 -> u. The resulting string is then prepended with "aesT322" to get the final second password. Unlike in variant 3 there is no chance to undelete the deleted first password as the files storing the first passwords are overwritten multiple times before they are deleted (using Sysinternals' sdelete). But yeah, that's pretty much it.
Blaze wrote:Looks more indeed like a skiddie job, but as Fabian stated, if it's effective enough ...
It indeed does. Even the routines look like copy and paste code. The malware is written in Pure Basic and when you look through the Pure Basic communities you find quite a bit of code for installing a service or creating a new desktop that looks exactly like the code used in the malware.
 #12676  by Flamef
 Fri Apr 13, 2012 11:36 am
Fabian Wosar wrote:People looking for information may want to take a look here:
http://blog.emsisoft.com/2012/04/11/the ... s-servers/
Blaze wrote:Anyone knows why it's called ACCDFISA ?
It is named differently by different vendors. We decided to call it ACCDFISA because that is the name of the fake government agency the malware used to scare the user into paying. It consequently became the term people used most to find information about it via Google. Later variants dropped the ACCDFISA name, but it stuck since those variants clearly are related.
Blaze wrote:Is it AES encryption or is the RSA encryption algorithm being used ? (like the GPcode ransom)
It uses AES-256 through WinRAR. So it doesn't implement any encryption itself but uses the command line version of RAR to move files into encrypted archives. The password generation changed from variant to variant. The first variant used a static password/unlock code. The second variant generated a password based on the boot drive's volume id. The volume id is therefore interpreted as a signed 4 byte integer and converted into a string. Any leading minus signs are then removed from the string and the static string "001" is prepended. The resulting id (it's the same that is displayed in the ransom notice) is then passed through a primitive substitution "cipher" (twice for the screen locker unlock code). The resulting "password" is then usually prepended or appended with static strings. The exact routines for the second variant look something like this in Delphi:
Code: Select all
function GetPassword(id : string) : string;
var
  i : Integer;
begin
  for i := 1 to Length(id) do
    case id[i] of
      '1' : Result := Result + 'w';
      '2' : Result := Result + 'N';
      '3' : Result := Result + 'x';
      '4' : Result := Result + 'Z';
      '5' : Result := Result + 'u';
      '6' : Result := Result + 'S';
      '7' : Result := Result + 't';
      '8' : Result := Result + 'Y';
      '9' : Result := Result + 'm';
      '0' : Result := Result + 'a';
    end;
end;

function GetRarDecryptionPassword(id : string) : string;
const
  passwordPrefix = 'aes987156';
  passwordPostfix = 'tH2z4s872qw6sPsXz871ldv5Zt3Fk';
begin
  Result := Format('%s%s%s', [passwordPrefix, GetPassword(id), passwordPostfix]);
end;

function GetScreenUnlockPassword(id : string) : string;
const
  passwordPrefix = '7655715214';
var
  i : Integer;
  variablePart : string;
  password : string;
begin
  variablePart := '';
  password := GetPassword(id);

  for i := 1 to Length(password) do
    case password[i] of
      'w' : variablePart := variablePart + '7';
      'N' : variablePart := variablePart + '1';
      'x' : variablePart := variablePart + '9';
      'Z' : variablePart := variablePart + '8';
      'u' : variablePart := variablePart + '3';
      'S' : variablePart := variablePart + '7';
      't' : variablePart := variablePart + '5';
      'Y' : variablePart := variablePart + '3';
      'm' : variablePart := variablePart + '2';
      'a' : variablePart := variablePart + '0';
    end;
  Result := Format('%s%s', [passwordPrefix, variablePart]);
end;
The third variant uses randomly generated passwords. To generate such a password it will essentially generate a large numeric string. The numeric string is generated like this (pseudo code):
Code: Select all
NumericString = Str(Int64(Random(1000000) * Random(100000) * Random(10000))) + Str(Int64(Random(1000000) * Random(100000) * Random(10000))) + Str(Int64(Random(1000000) * Random(100000) * Random(10000)));
The pseudo random number generator is seeded once with the current thread id and the current tick count (RandSeed = GetCurrentThreadId() ^GetCurrentTickCount() to be more precise). The resulting numeric string is then passed to a substitution cipher that is similar to the one used in variant 2. The substitution matrix changed and looks something like this now: 1 -> A, 2 -> n, 3 -> F, 4 -> r, 5 -> V, 6 -> t, 7 -> L, 8 -> q, w -> 9 and 0 -> u. To get the final password the static string xcqT100 is prepended. The large numeric string is also saved to two different files (msdadiags.dll as well as rvid1000.txt) so the malware uses the same numeric string in consecutive runs. You may ask why victims can't just use the numeric string from there to generate their passwords. The problem is that the attackers will use two different numeric strings. After the initial infect and the first "encryption" run the attackers will remove both files from the system and move them to their systems. This will cause the malware to generate a new numeric string used for password generation for all encryptions after this. The result is that all files that existed at the time of the infection are encrypted with the password based on the first numeric string, that was later deleted and all files encrypted after the initial infection are encrypted with a second password based on a second numeric string that stays on the system. It is possible to get the second password, but impossible to get the first unless you manage to restore the deleted files restoring the numeric strings.

The fourth (and newest) variant uses randomly generated as well as a computed passwords . Again two passwords are used to encrypt the files that existed at the time of infection and to encrypt files since then. The first password is generated without the substitution cipher this time. Its generation essentially looks something like this (pseudo code):
Code: Select all
char characterTable[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*&*()-+_=";
string password = "aesT322";
for (int i = 0; i < 50; i++)
{
    password += characterTable[Random(Length(characterTable))];
}
The second password is generated similar to the one in variant 2. A numeric string based on the boot drive's volume id is generated and run through a substitution cipher. I haven't looked into how the volume id is converted into the numeric string yet since I haven't had time. If one of you wants to knock himself out: It is located at address 0x00403C3B. The substitution matrix used in the substitution cipher is: 1 -> A, 2 -> $, 3 -> F, 4 -> r, 5-> V, 6-> *, 7 -> L, 8 -> q, 9 -> w and 0 -> u. The resulting string is then prepended with "aesT322" to get the final second password. Unlike in variant 3 there is no chance to undelete the deleted first password as the files storing the first passwords are overwritten multiple times before they are deleted (using Sysinternals' sdelete). But yeah, that's pretty much it.
Blaze wrote:Looks more indeed like a skiddie job, but as Fabian stated, if it's effective enough ...
It indeed does. Even the routines look like copy and paste code. The malware is written in Pure Basic and when you look through the Pure Basic communities you find quite a bit of code for installing a service or creating a new desktop that looks exactly like the code used in the malware.
Is there any chance to find a possible solution?
 #12679  by Quads
 Fri Apr 13, 2012 12:49 pm
By using the ACCDFISA ID in the unlocker to generate,

a) The program unlock code
b) The archive (RAR) password to get your files back.

Or there is a way by using the Volume ID to create the ACCDFISA ID and go from there.

Quads
 #12681  by Fabian Wosar
 Fri Apr 13, 2012 12:56 pm
Flamef wrote:Is there any chance to find a possible solution?
For the first two variants as well as the second password of the other two variants it is easy to reconstruct the password. The first password though can't be reconstructed unless you get lucky and are able to recover the files the random numeric id/password was stored in. The best approach would be trying brute force. You do know when your system was turned on (event log) and you do know as well when the first encrypted archives were created on your system. This way you can estimate the tick count. Thread ids are reasonable deterministic as well. So the amount of passwords possibilities can be reduced to a reasonable amount of maybe a few millions which should be possible to check in a reasonable amount of time. I haven't tried such an attack though. So I have no idea how practical such an attack would actually be.
 #12689  by Flamef
 Fri Apr 13, 2012 2:35 pm
Fabian Wosar wrote:
Flamef wrote:Is there any chance to find a possible solution?
For the first two variants as well as the second password of the other two variants it is easy to reconstruct the password. The first password though can't be reconstructed unless you get lucky and are able to recover the files the random numeric id/password was stored in. The best approach would be trying brute force. You do know when your system was turned on (event log) and you do know as well when the first encrypted archives were created on your system. This way you can estimate the tick count. Thread ids are reasonable deterministic as well. So the amount of passwords possibilities can be reduced to a reasonable amount of maybe a few millions which should be possible to check in a reasonable amount of time. I haven't tried such an attack though. So I have no idea how practical such an attack would actually be.
I am talking about the latest variant,as mentioned before,the author claims that,after considering his old mistakes,he made a variant(the latest one)for which there isn't any solution,and there won't be.
 #12690  by Fabian Wosar
 Fri Apr 13, 2012 2:38 pm
I already explained how the newest (fourth) variant could potentially be attacked even when you can't recover the files the malware uses to store the password.
 #12704  by thisisu
 Sat Apr 14, 2012 5:57 am
This is all way over my head but I am confident you guys will be able to figure this out. ;)
 #12735  by Blaze
 Mon Apr 16, 2012 7:45 am
Xylitol wrote:Because the ransom claim to be from the "Anti Cyber Crime Department of Federal Internet Security Agency"
Thanks !

Fabian Wosar wrote: After the initial infect and the first "encryption" run the attackers will remove both files from the system and move them to their systems. This will cause the malware to generate a new numeric string used for password generation for all encryptions after this. The result is that all files that existed at the time of the infection are encrypted with the password based on the first numeric string, that was later deleted and all files encrypted after the initial infection are encrypted with a second password based on a second numeric string that stays on the system. It is possible to get the second password, but impossible to get the first unless you manage to restore the deleted files restoring the numeric strings.
Thanks ! Your blogpost is very clear, as well as your post here.

I suppose the move of files is done manually by the attacker, there is nothing that indicates files are sent automatically ?

If there's being worked with 2 passwords to encrypt the files, and the 1st numeric string is deleted, will those file encrypted with the 1st password be recoverable ? Maybe I missed that point, but if my thinking is incorrect, and the user pays the ransom to decrypt files, where will it get its 1st string from (assuming it actually decrypts the file after paying) ?

So far yet I haven't encountered one myself. Are only servers affected ? I suppose there's a high chance the attacker exploits the latest RDP vulnerability.
 #12738  by Fabian Wosar
 Mon Apr 16, 2012 10:38 am
Blaze wrote:I suppose the move of files is done manually by the attacker, there is nothing that indicates files are sent automatically ?
No. The file is moved from the infected to the attacker's system manually. That is one of the reasons why the files containing the IDs or passwords is created on the Desktop: For convenience ;).
Blaze wrote:If there's being worked with 2 passwords to encrypt the files, and the 1st numeric string is deleted, will those file encrypted with the 1st password be recoverable ?
They are. The malware will display a specific "ID". This ID is essentially the boot drive's volume id converted to a signed integer and stripped the minus sign. The attackers have a database that essentially links that system ID to the generated passwords.
Blaze wrote:Maybe I missed that point, but if my thinking is incorrect, and the user pays the ransom to decrypt files, where will it get its 1st string from (assuming it actually decrypts the file after paying) ?
They simply saved the numeric ID :).
Blaze wrote:So far yet I haven't encountered one myself. Are only servers affected ? I suppose there's a high chance the attacker exploits the latest RDP vulnerability.
It doesn't target servers specifically. Remote Desktop or Terminal Services are usually run on servers only though. So I haven't seen any infected consumer Windows installations. The RDP vulnerability hasn't been used yet. I had the chance to look at about a dozen infected machines. All of them were broken into through dictionary based brute force attacks. On some machines the attacker left a brute force tool called "DUBrute". Most likely to use the hijacked system for further brute force attacks.