开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 16492|回复: 41
收起左侧

[技术专题] 起点中文网安卓APP超详细算法分析过程

[复制链接]
结帖率:75% (3/4)
发表于 2017-8-8 05:26:44 | 显示全部楼层 |阅读模式   山东省聊城市
本帖最后由 小七烤地瓜 于 2017-8-8 05:31 编辑

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

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

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 进行分析 等待处理完成
2.png

搜索signnature  定位到下图
3.png
代码为:
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() 函数  我们来理解下这个是什么意思  不懂英文怎么办?凉拌呗 因为我英语也不好  不过我们有翻译啊.....  有翻译啊.....  有翻译啊... 哈哈
4.png

翻译后  我们发现这个函数 是当前时间,那么我们就要充分发挥我们的想象了 他加入了一个数据  点用了这个函数  这个函数呢 我们知道他是获取当前时间   那么他就是获取当秦时间并加入,至于那个/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方法进入 继续分析......

5.png

以上为代码;  以下也是代码:
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;
    }
}



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


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


6.png

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


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

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


10.png

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


11.png

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

代码为:

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:其实我也想讲  无奈我不会啊.............
好  我们找到最终加密就下断点调试
9.png

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


12.png

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


14.png


密文出现 我们再来解密一下  
13.png


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


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

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


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


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


就到这吧   大家再见
























                                             

点评

分析的很详细,但是作为精华帖,我想指出,加密是在cipher类中完成的,这是java常用的加密解密类。加密完成之后的东西是字节流,这个时候需要编码到字符串。e.a负责完成这个编码过程   日本  发表于 2017-8-13 21:49
视频版地址:https://bbs.125.la/thread-14054073-1-1.html   山东省聊城市  发表于 2017-8-10 10:46

评分

参与人数 8好评 +5 精币 +141 收起 理由
aixnhc + 1 新技能已get√
wkf + 1 + 2 新技能已get√
兔子君 + 1 + 120 感谢分享,很给力!~
雪山凌狐 + 1 + 2 新技能已get√
雅蠛蝶~ + 1 + 2 感谢分享,很给力!~
银河世纪 + 3 感谢发布原创作品,精易因你更精彩!
冯古屋 + 10 感谢发布原创作品,精易因你更精彩!
已注销330572 + 1 + 1 感谢分享,很给力!~

查看全部评分


本帖被以下淘专辑推荐:

签到天数: 7 天

发表于 2022-9-27 19:42:15 | 显示全部楼层   重庆市重庆市
厉害,支持
回复 支持 反对

使用道具 举报

签到天数: 6 天

发表于 2020-10-20 23:02:50 | 显示全部楼层   四川省泸州市
学习,学习一下
回复 支持 反对

使用道具 举报

发表于 2019-12-4 01:02:52 高大上手机用户 | 显示全部楼层   江苏省苏州市
厉害,支持
回复 支持 反对

使用道具 举报

发表于 2018-7-31 10:59:41 | 显示全部楼层   广东省深圳市
很厉害,我特别佩服那些会写脚本的人,真的很厉害
回复 支持 反对

使用道具 举报

发表于 2018-7-30 21:21:29 | 显示全部楼层   浙江省杭州市
分析的不错,很详细...楼主还很细心的将java代码每一行注释都写出来了
回复 支持 反对

使用道具 举报

结帖率:50% (1/2)
发表于 2018-7-29 13:47:31 | 显示全部楼层   河南省郑州市
支持支持,作者厉害
回复 支持 反对

使用道具 举报

发表于 2018-6-28 14:05:30 | 显示全部楼层   河南省郑州市

不服不行,这个的确水平不一般
回复 支持 反对

使用道具 举报

结帖率:68% (15/22)
发表于 2018-6-11 23:43:01 | 显示全部楼层   黑龙江省牡丹江市
太有用了,谢谢版主
回复 支持 反对

使用道具 举报

结帖率:100% (23/23)

签到天数: 18 天

发表于 2018-4-15 02:12:18 | 显示全部楼层   安徽省淮北市
看界面和功能就很牛了,支持楼主
回复 支持 反对

使用道具 举报

发表于 2018-4-8 19:38:21 | 显示全部楼层   江西省抚州市
不服不行,这个的确水平不一般
回复 支持 反对

使用道具 举报

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

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 诚聘英才| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 800073686,邮箱:800073686@b.qq.com
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

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