|
本帖最后由 小七烤地瓜 于 2017-8-8 05:31 编辑
起点中文网安卓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;
}
}
看到这里 是不是有点激动?是不是乐了?是不是硬了? 别急 继续分析 高潮马上到......
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 明文都找出来了 有兴趣的童鞋可以试试看
就到这吧 大家再见
|
评分
-
参与人数 8 | 好评 +5 |
精币 +141 |
收起
理由
|
aixnhc
| |
+ 1 |
新技能已get√ |
wkf
| + 1 |
+ 2 |
新技能已get√ |
兔子君
| + 1 |
+ 120 |
感谢分享,很给力!~ |
雪山凌狐
| + 1 |
+ 2 |
新技能已get√ |
雅蠛蝶~
| + 1 |
+ 2 |
感谢分享,很给力!~ |
银河世纪
| |
+ 3 |
感谢发布原创作品,精易因你更精彩! |
冯古屋
| |
+ 10 |
感谢发布原创作品,精易因你更精彩! |
已注销330572
| + 1 |
+ 1 |
感谢分享,很给力!~ |
查看全部评分
|