短信拦截马之加密号码分析第二弹

0x00 前言

新年快要到了,提前祝大家新年快乐!
在 2015年的最后一个下午,有很多话想说,却又不知道从何说起,突然想起了自己早上脑子里忽然蹦出的一个念头:人们常说:“一叶障目,不见泰山”,想必是 登高才能望远,多数时候环境确实没有给我们提供登高望远的机会,使得很多事情难以尽兴!但是,突然发现,有的时候,我们看的不远是因为我们处在一个不能让 自己看远的道路上,比如在狭窄的山路上行车,人的视线最多也就是20米、甚至10米,这个时候你就不能望远;而在高速公路上,人的视线必须在50米开外, 此时你要是只看近处则比较危险!是啊,很多时候,不是你先近就近,你想远就远的,得看你在什么路上!而路,是一个永远也讲不完的话题。。。。。。
扯远了,进入正题。

0x01 变化

书接上回,上次说到MM作者将号码以DES加密的形式隐藏在configure文件中,我们通过逆向其写入configure文件的过程,进而找到其解密过程,获取真正的控制手机号码。
前 几天,又获取一个样本,这个样本的基本功能和前一个差不多,区别就是在于加密的方式不同了,而且还呈现了一些新的特性,比如更重要的控制手机号码不再写入 configure文件中了,只存在于内存中,这个确实给我们分析带来了巨大不便,看来此次也是煞费苦心啊!不多说,下面直接开始分析,样本在附件,密码 52pojie。

0x02 来看看MM的百宝箱

JxB打开样本,依然是从strings列表中找出好多加密后的字符串,以此双击进去,发现在com.phone.stop.db包中有大量的解密写入shared_prefs过程
    public String p() {
       this.b.getString("send_email_account","587676AA1B91FA679F7EE717D56D6EAE42C4667D5D21F62B");
        returnC.decrypt("6219472174F9AB559585F776E78FA0FF5012D9884F775E16C24270CC152225F1",C.k);
    }
 
    public boolean q() {
        returnthis.b.getBoolean("has_set_send_email_account", false);
    }
 
    public String r() {
        this.b.getString("receive_email_account","A609DC08DE9D6D0DF062B0B68028EE05");
        returnC.decrypt("6219472174F9AB559585F776E78FA0FF5012D9884F775E16C24270CC152225F1",C.k);
    }
 
    public boolean s() {
        returnthis.b.getBoolean("has_set_receive_email_account", false);
    }
 
    public String t() {
       this.b.getString("send_email_pwd","A609DC08DE9D6D0DF062B0B68028EE05");
        returnC.decrypt("A609DC08DE9D6D0DF062B0B68028EE05", C.k);
    }
[align=left]

深入到C.decrypt函数,发现是AES加密算法,而且密钥是明文,大喜过望!

private static final String CipherMode = "AES/ECB/PKCS5Padding";
    public staticString k;
 
    static final{
        C.k = "sdtyffdftesfyfdw";
然而,用AES解密工具试了一下不行。

0x03换一个方向

通过对AES加密算法进行深入研究,发现AES密钥有128、192、256三种长度,但是这个apk用的是哪一种呢?继续分析,发现C类中有一个Createkey函数比较可疑,深入分析一下。
private static SecretKeySpec createKey(String arg11) {[/align]        byte[] v2;
        byte[] v6_2;
        String v0 = arg11;
        String v6 = v0;
        if(v6 == null) {
            v6 = "";
            v0 = v6;
        }
        super(32);
        String v3 = v6;
        v3.append(v0);
        while(v3.length() < 32){
            v3.append("0");
        }
 
        if(v3.length() > 32){
            v3.setLength(32);
        }
 
        v6 = v3;
        try {
            v6_2 = ((StringBuffer)v6).toString().getBytes("UTF-8");
            v2 = v6_2;
        }
        catch(UnsupportedEncodingExceptionv6_1) {
            v6_1 = v6_1;
            v6_1.printStackTrace();
        }
 
        super(v2, "AES");
        return v6_2;
    }
仔细分析发现,该函数是生成密钥的主要过程,而且对于长度小于32字节的密钥,尾部加上一些0使得长度为32字节,由此,大胆输入解密密钥,果然如此。

 

熟悉ASCII码的朋友,一看就知道怎么回事了,而且最后添加的5个05正是AES/ECB/PKCS5Padding的特征,只是这样的解密还看的不爽!那就自己写个解密函数。

0x04解密函数

其 实对C类进行仔细的分析,自己写个解密函数还是比较靠谱的,但是本菜实现比较懒(直说编程比较弱就行了,我听见了好多声音!哈哈!),建一个java工 程,将反编译的C类拷过去,调试修改一下,注意其中要下载oracle的关于AES密钥长度的补丁,详细请看 http://www.cnblogs.com/AloneSword/p/3487809.html。为了安全起见,就不放出源码了,防止有心的朋友进 行恶意利用,这里声明,本渣只进行技术讨论,其他种种,本渣概不参与和负责!
看雪有个朋友直接写了个python脚本,佩服!这就不剽窃了!

0x05后记

首先感谢提供AES加解密工具的网友,虽然我们未曾谋面,谢意一定送出!有需要的网友搜索一下去下载,某不敢剽窃产权!
多的也不说啥了,祝大家新的一年工作顺利,步步高升!