Friday, 5 December 2014

Snippet : DeathRing Android Malware AES URL Decryption

In this blog post we'll be looking at a new malware named DeathRing that discovered recently by Lookout. Main focus of this post will be to describe briefly the decryption process (through source code re-construction) of the AES encrypted base URL that malware uses to communicate with the server.

The source code that will be provided here works only in Android environment.  Main parts of the code below taken from the de-compilation of the malicious package. Then reconstructed a bit to work properly and give us the decrypted URL.

Sample: 9fef935d65b4c159ee09c7af1692105d5242feef0a7b4e10f683770ed5c972ea
Download: Contagio

Re-constructing the code

First step is to create in Eclipse a new Android Application Project. Make sure that the target version / number of Android is bigger or equal 20. The Activity will be initialized with the source code below. The source code will be copy/pasted inside the onCreate of the Activity.

Key points of the snippet below are:
  • Seed. The string 123smart321 can be found inside the UrlGenerator class of the malicious package. A seed "is an array of bytes used to bootstrap random number generation" (via).
  • Base URL. The BASEURL is the encrypted AES String that can be found in the Constant class of the package.

   protected void onCreate(Bundle savedInstanceState) {

   String seedStr = "123smart321"; //The seed
   // The AES encrypted string 
   String BASEURL = "8CC5ECF18E1E2AAEF413535D4F3CFBF3CC99E6DE4E5840637F09A68931DB28EC4E9A121E3611F97B881776470CCB90E1";

   try {
    System.out.println(new String(decrypt(getRawKey(seedStr.getBytes()), toByte(BASEURL))));
   } catch (Exception e) {
    // TODO Auto-generated catch block


In the source code snippet below there are three static methods:

  • byte[] decrypt
    This method take two inputs: the raw key that will be created from the getRawKey method and  the byte array of the String BASEURL hex representation.
  • byte[] getRawkey
    This method  using the Seed, it will generate a predictable random key that  will be used for the decryption of the BASEURL by the decrypt method. 
  • byte[] toByte
    This method will return the byte array of the String hex representation that BASEURL contains. 
The three methods below can be inserted after the onCreate method.

 private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
  SecretKeySpec v2 = new SecretKeySpec(raw, "AES");
  Cipher v0 = Cipher.getInstance("AES");
  v0.init(2, ((Key) v2));
  return v0.doFinal(encrypted);
 private static byte[] getRawKey(byte[] seed) throws Exception {
  KeyGenerator v0 = KeyGenerator.getInstance("AES");
  SecureRandom v3 = SecureRandom.getInstance("SHA1PRNG", "Crypto");
  v0.init(128, v3);
  return v0.generateKey().getEncoded();
 private static byte[] toByte(String hexString) {
  int v1 = (hexString.length() / 2);
  byte[] v2 = new byte[v1];
  int v0;
  for (v0 = 0; v0 < v1; ++v0) {
   v2[v0] = Integer.valueOf(hexString.substring(v0 * 2, v0 * 2 + 2), 16).byteValue();

  return v2;


Running the current Android project from Eclipse will return the following output (image reversed):

Update (8 Dec 14):

Decrypting data from a GET request

Requesting data from the URL above we GET an encrypted DES string ("stext") and the "jabc" string that contains the key for decrypting it. The following source code (Java 7/Win7) can be used to decrypt the data that the URL above give us back. On each GET request the "jabc" and the "stext" Strings are different. You can simply copy-paste those Strings in the source code bellow.

 public static void main(String[] args) throws Exception {

  String stext = "ZaM/+TjPCnO/VoGcx7Ya7LOADDZRmBOHjCaVKSyOQXNmEh58Lob02sr1w47N wR21d+vWSSvtdxL8QFxJlm06asN4zTwcYPuEgfLPdqei6NeLQWyY0VWK1FXt B++gZlPZRS/kxjnMgTXxkOlGCDATwtjpCRUjVzmYXnrSugMb0MCB9COoHvFe K8lYW7/Lxt1bWf9JpDiWbU+KodaBp6QFrPOyi5RRPSUwS5a8BRzq6OJ5JpLz hyuXkDjavo50c+Cn0xLGUKcHxCCaj4IfJ64tEDAfSAPn0+O3L2beF9XuYuDY R4HAawSU040wjyZkFCSC1hRGrpfHDEiDqnRHQ/iMAdOO5/St7hlV88ack+0v wzCkoCtEuaqAnbnK22o9rTmZ9/szrLnGCGIg/NQOailBRf0jrWNQcKUyYMHb k149xzHXGvFXeGW7YEfP+hIJTItNiXyQUOwVk7Fj2a/GU5Zn9DaRz4MWtVaY NWe/4R2M/iPrTk1b1JNlvTUo0wR0QVAa";
  String jabc = "Yr9l5F1ZXQbwQFeB";

  System.out.println(decryptDES(content, keyDes.substring(3, 11)));

 public static String decryptDES(String decryptString, String decryptKey) throws Exception {

  byte[] iv = new byte[] {
   1, 2, 3, 4, 5, 6, 7, 8
  byte[] v0 = DatatypeConverter.parseBase64Binary(decryptString);

  IvParameterSpec v4 = new IvParameterSpec(iv);
  SecretKeySpec v3 = new SecretKeySpec(decryptKey.getBytes(), "DES");
  Cipher v1 = Cipher.getInstance("DES/CBC/PKCS5Padding");
  v1.init(2, ((Key) v3), ((AlgorithmParameterSpec) v4));
  return new String(v1.doFinal(v0));

In this case the decrypted data are the following:

p.s. Feel free to comment corrections or new suggestions that can improve this blog post.

No comments:

Post a Comment