易语言实地培训长期招生 QQ1615457736

乐易论坛

 找回密码
 立即注册

微信登录

微信扫码,快速开始

QQ登录

用QQ账号登陆

导航
导航
培训
培训
产品
产品
易歪歪客服聊天助手——永久免费程序员熬夜必备神器阿里云服务器最高¥1888云产品通用代金券我要租广告
易歪歪客服聊天助手——永久免费全新E3,E5机器远程出租阿里云服务器低至10元/月我要租广告
易歪歪客服聊天助手——永久免费阿里云虚拟机主机 低至350元/1年 最高2000云产品通用代金券我要租广告
TQApiEc---专为PCQQ/TIM 开发的API接口模块,让你直接调用内部功能TQApiEc---专为PCQQ/TIM 开发的API接口模块,让你直接调用内部功能TQApiEc---专为PCQQ/TIM 开发的API接口模块,让你直接调用内部功能TQApiEc---专为PCQQ/TIM 开发的API接口模块,让你直接调用内部功能
WxApiEc-专为PCWx开发的API接口模块,让你快速调用内部功能WxApiEc-专为PCWx开发的API接口模块,让你快速调用内部功能WxApiEc-专为PCWx开发的API接口模块,让你快速调用内部功能WxApiEc-专为PCWx开发的API接口模块,让你快速调用内部功能
查看: 7649|回复: 4
收起左侧

[Android 交流] 起点中文网安卓APP超详细算法分析过程

[复制链接]
  • TA的每日心情
    慵懒
    6 天前
  • 签到天数: 87 天

    [LV.6]常住居民II

    发表于 2017-8-8 05:26:26 | 显示全部楼层 |阅读模式
    本帖最后由 小七烤地瓜 于 2017-8-8 05:41 编辑

                          起点中文网安卓App详细算法分析

    玩APP跟网页一样都是先抓包看什么参数加密 再能继续下一步 所以说我们也先来抓包


    post https://ptlogin.qidian.com/sdk/staticlogin HTTP/1.1
    referer: http://android.qidian.com
    QDSign: P3YzdKsAdLU62B1HLWHyOOOAZgQDaUIEQyASCPcdXaq45PThysJV7CjIyqWT du4He78qzIaoavX8uHDqvYHe5ZjibsSNjt9rsIu8fybrLLnFo7eHeAQIvw==
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 349
    Host: ptlogin.qidian.com
    Connection: Keep-Alive
    Accept-Encoding: gzip
    User-Agent: okhttp/3.4.1

    password=123456789&source=1000060&signature=LKKa%2BlLqSTmIQ54L%2BJKYjLixyOppZPkoXNuzXxPRBA1UQ9vK0h5rnPCwubEZimOj&appid=12&referer=http%3A%2F%2Fandroid.qidian.com&ticket=0&auto=1&devicetype=samsung_sm%20-%20j710f&format=Json&osversion=Android5.1.1_6.8.0_286&username=15845454545&autotime=30&version=286&returnurl=http%3A%2F%2Fwww.qidian.com&areaid=30


    以上为登录抓到的数据,我们发现账号和密码都没有加密 但是有一个signature  这个是变化的 加密的 找到了加密参数我们就开始分析APP


    拖入JEB 进行分析 等待处理完成


    搜索signnature  定位到下图

    代码为:
    public String c() {
            String v0;
            try {
                StringBuffer v1_1 = new StringBuffer();
                v1_1.append(this.f);
                v1_1.append("|");
                v1_1.append(this.g);
                v1_1.append("|");
                v1_1.append(String.valueOf(System.currentTimeMillis() / 1000));
                String v1_2 = com.yuewen.ywlogin.g.a(v1_1.toString());
                Log.d("YWLoginSDK", "signature :" + v1_2);
                v0 = "&appid=" + this.c + "&areaid=" + this.d + "&source=" + URLEncoder.encode(this.e, "utf-8") + "&signature=" + Uri.encode(v1_2) + "&version=" + this.j + "&returnurl=" + URLEncoder.encode("http://www.qidian.com", "utf-8") + "&format=json&ticket=" + this.m;
            }


    我们来分析一下代码
    new StringBuffer();  创建一个空的 StringBuffer();对象用来存储与控制字符串;
    append(this.f);  append  附加 增加的意思  this.f  this  当前 f 参数,变量  也就是说  把f这个变量的数据 添加进去 f是什么? 不知道继续分析
                v1_1.append("|");
                v1_1.append(this.g);
                v1_1.append("|");

    以上同理 不 过多解释
    v1_1.append(String.valueOf(System.currentTimeMillis() / 1000));  这个也是加入一段数据  不过 有个 currentTimeMillis() 函数  我们来理解下这个是什么意思  不懂英文怎么办?凉拌呗 因为我英语也不好  不过我们有翻译啊.....  有翻译啊.....  有翻译啊... 哈哈


    翻译后  我们发现这个函数 是当前时间,那么我们就要充分发挥我们的想象了 他加入了一个数据  点用了这个函数  这个函数呢 我们知道他是获取当前时间   那么他就是获取当秦时间并加入,至于那个/1000 被屏蔽了 我们不用管 下一步......
    String v1_2 = com.yuewen.ywlogin.g.a(v1_1.toString());

    String v1_2  String 在java中是字符串的意思 按易语言理解 就是一个文本型的变量 变量名为 v1_2;  com.yuewen.ywlogin.g.a(v1_1.toString());  这就是调用方法了 调用了com.yuewen.ywlogin.g.a  重点在最后 a方法 里面传递了一个参数 v1_1  还有个 .toString()   v1_1就是我们前面加入的数据  存放到这里面   .toString()  到文本的意思 他就是调用了a方法 传递了一个v1_1参数进行加密   

    Log.d("YWLoginSDK", "signature :" + v1_2);   Log 日志 输出意思  "YWLoginSDK" 这就是个字符串   "signature :" + v1_2  这就是输出了signature 字符串 +  v1_2  这个变量里面的数据  可能是作者调试写的吧

    v0 = "&appid=" + this.c + "&areaid=" + this.d + "&source=" + URLEncoder.encode(this.e, "utf-8") + "&signature=" + Uri.encode(v1_2) + "&version=" + this.j + "&returnurl=" + URLEncoder.encode("http://www.qidian.com", "utf-8") + "&format=json&ticket=" + this.m;
    这就是个数据拼接  不用管 加密就是a方法  我们已经找到了 点击a方法进入 继续分析......



    以上为代码;  以下也是代码:
    public class g {
        public static String a(String arg4) {
            String v0_2;
            try {
                SecretKey v0_1 = SecretKeyFactory.getInstance("desede").generateSecret(new DESedeKeySpec("bMyzJ1D7Kl7zt9mwjegtJGMoF53msSfP".getBytes()));
                Cipher v1 = Cipher.getInstance("desede/CBC/PKCS5Padding");
                v1.init(1, ((Key)v0_1), new IvParameterSpec("W9F1bXrz".getBytes()));
                v0_2 = e.a(v1.doFinal(arg4.getBytes("utf-8")));
            }
            catch(Exception v0) {
                v0.printStackTrace();
                v0_2 = null;
            }


            return v0_2;
        }
    }



    看到这里 是不是有点激动?是不是乐了?是不是硬了?undefined   别急  继续分析 高潮马上到......


    public static String a(String arg4)      
    public   声明; static 静态方法   声明了一个方法为a的静态方法 并传递了一个参数
    SecretKey v0_1 = SecretKeyFactory.getInstance("desede").generateSecret(new DESedeKeySpec("bMyzJ1D7Kl7zt9mwjegtJGMoF53msSfP".getBytes()));
    SecretKey  秘钥 其实 从这句代码我们可以看出来什么意思了就是调用 DESedeKeySpec  声明了一个秘钥  秘钥为:bMyzJ1D7Kl7zt9mwjegtJGMoF53msSfP




    Cipher v1 = Cipher.getInstance("desede/CBC/PKCS5Padding");  设置加密方式 模式 填充方式  加密方式


    new IvParameterSpec("W9F1bXrz".getBytes()));  设置加密IV


    v0_2 = e.a(v1.doFinal(arg4.getBytes("utf-8")));   这就是最终的加密了 加密后 并进行utf-8编码  arg4.getBytes("utf-8")  获取 arg4的utf-8文本
    先暂定为DES  模式 CBC  填充方式 PKCS5Padding  好 我们知道了 密文  加密方式   key   iv   那么我们可以先测试一下 看看我们分析的对不对




    DES  加密  没解出来 ........  懵逼...失落  难受...想哭.... RNMLGB的 不对?  这咋回事?




    那么 是不是加密方式不对呢 既然不是DES 那是不是3DES呢?  
    结果让我们..............
    OMG   兴奋   高兴  开心   想笑 ........
    明文为: 865166028019332|865166028019332|1502136058
    好 抽根烟  冷静一下继续分析.......
    点击a进入


    代码为:

    package com.yuewen.ywlogin;

    public class e {
        private static char[] a;
        private static byte[] b;

        static {
            e.a = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
            e.b = new byte[]{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1};
        }

        public static String a(byte[] arg8) {
            StringBuffer v1 = new StringBuffer();
            int v2 = arg8.length;
            int v0 = 0;
            while(v0 < v2) {
                int v3 = v0 + 1;
                int v4 = arg8[v0] & 255;
                if(v3 == v2) {
                    v1.append(e.a[v4 >>> 2]);
                    v1.append(e.a[(v4 & 3) << 4]);
                    v1.append("==");
                }
                else {
                    int v5 = v3 + 1;
                    v3 = arg8[v3] & 255;
                    if(v5 == v2) {
                        v1.append(e.a[v4 >>> 2]);
                        v1.append(e.a[(v4 & 3) << 4 | (v3 & 240) >>> 4]);
                        v1.append(e.a[(v3 & 15) << 2]);
                        v1.append("=");
                    }
                    else {
                        v0 = v5 + 1;
                        v5 = arg8[v5] & 255;
                        v1.append(e.a[v4 >>> 2]);
                        v1.append(e.a[(v4 & 3) << 4 | (v3 & 240) >>> 4]);
                        v1.append(e.a[(v3 & 15) << 2 | (v5 & 192) >>> 6]);
                        v1.append(e.a[v5 & 63]);
                        continue;
                    }
                }

                break;
            }

            return v1.toString();
        }
    }


    这段就是des的算法   这我就不讲了   ps:其实我也想讲  无奈我不会啊.............
    好  我们找到最终加密就下断点调试


    点击登录 断在这里  查看传递的参数是什么




    ok  传递的参数 就是我们解密出来的数据   明文已确定.......
    继续单步往下运行 知道出现加密结果





    密文出现 我们再来解密一下  



    我们发现 明文几乎没有变 以|分割 前两个固定不变 最后那个变化了 865166028019332|865166028019332|1502139437
    也就是  1502139437  这个参数我们回想一下 他在进行明文拼接的时候  分别添加了三个  一个f变量 一个g变量 最后一个是调用了一个获取当前时间的函数  那么在看这个参数值 是不是很像时间戳? 没错!! 他就是一个时间戳  ps:现在时间戳已经是150开头了哦....


    那么前两个又是什么东西呢?经常玩APP的应该一眼就看出来了 他就是模拟器的设备串号 IMEI  到底是不是 我们查看下喽


    865166028019332  对比  865166028019332  OMG 是不是一样的  ps:这不是废话么.......


    ok 至此  加密我们已经分析完了  
    这时候可以总结一句话  加密就是  3DES加密方式 CBC模式   PKCS5Padding  填充方式


    ok   至于代码我就不写了  key  iv  明文都找出来了 有兴趣的童鞋可以试试看


    最后   感谢乐易编程网..........


    就到这吧   大家再见                                       


    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2019-5-13 17:12
  • 签到天数: 37 天

    [LV.5]常住居民I

    发表于 2017-8-8 08:09:27 | 显示全部楼层
    666
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复

    使用道具 举报

  • TA的每日心情

    2018-7-15 17:24
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2017-8-8 17:55:55 | 显示全部楼层
    学习了  大佬!!!!
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2019-10-10 17:42
  • 签到天数: 26 天

    [LV.4]偶尔看看III

    发表于 2017-8-10 01:13:42 | 显示全部楼层
    厉害了,大佬
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-12-1 15:56
  • 签到天数: 36 天

    [LV.5]常住居民I

    发表于 2018-10-24 15:23:42 | 显示全部楼层
    6666666
    易语言实地培训,报名联系QQ 1615457736
    [超强]《易语言软件加密(防破解)技术特训》
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    关闭

    乐易推荐上一条 /6 下一条

    QQ|网站地图|Archiver|手机版|小黑屋|乐易论坛 ( 湘ICP备19007035号-2 )

    GMT+8, 2020-4-9 05:37 , Processed in 0.116197 second(s), 100 queries .

    Powered by Discuz! X3.4 Licensed

    © 2001-2017 Comsenz Inc.

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