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.
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); 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 e.printStackTrace(); } }
In the source code snippet below there are three static methods:
- byte[] decryptThis 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[] getRawkeyThis 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[] toByteThis method will return the byte array of the String hex representation that BASEURL contains.
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"); v3.setSeed(seed); 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; }
Results
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:
{"undel":"","delcount":0,"link":3,"fopen":"2,0","adver":[],"baseapk":"","quiet":[],"game":{"advend":"","advkey":"","advtent":"","advtip":"","comtent":"","createBy":"","createTime":"","customids":"","delkey":"","id":0,"keytent":"","lastModifyBy":"","lastModifyTime":"","sessCode":0,"tipend":[]},"pause":"","gopen":"0,0","arg":1,"padv":[],"apn":"","smem":"","urlquiet":[],"linktype":0}
No comments:
Post a Comment