0x01前言
本来不想发的,但是最近状态有点迷,理理思路,以后会过来再看看应该还是蛮有感觉的,仅供学习研究,不可非法使用。
0x02登录抓包
1.首先用fd抓包工具抓到登录的包,发现有两个,没关系,我们一个一个看
2.首先看第一个的数据流,是个POST提交,提交数据是xml格式的,所以我们来到XML文本
3.提交了三个参数,这里的passWord没有加密,这就减轻了我们的工作负担,但是有一个strKey的数据,留心一下。
4.现在分析第二个包的数据流,同样是POST提交,直接来到XML文本,发现提交了四个参数,而且都是加密的,但是userName在上一个包还是明文,到这里就变成密文了,而且多了两个参数,moduletype和apptoke,这下事情有点复杂,但是理一理,上一个包我我们还没看返回response的结果,是不是有线索呢?
5.分析第一个POST包的response结果发现在倒数第二行有app_token字样,说明,这个值是有返回的,但是好乱,整理一下,于是我百度查了一下,发现">"是">","<"是"<",是HTML的转义字符。于是我用记事本操作替换了一下,见6
6.用了精益网页分析工具,很轻松的看到了格式化后的XML解析。而return后的参数app_token正是我们需要的
7.第二个包的response就是登录成功后返回的正文部分了,这里就不复制粘贴了,内容是登录后的九个图标界面。
0x03深入apk
一、第一个POST包参数的寻找
1.打开APK改之理,搜索关键字符strKey,发现结果太多了,找了login里面的类,仍然没看出苗头。于是换个思路,上面第二个包不是有一个叫做moduletype的参数吗,那么搜索它。来到jw教务这个类里。
2.这里明显看到WYNn2rNOtkuMGGlPrFSaMB0rQoBUmssS,和上面抓到的包参数对比一下,发现匹配上了,这里几乎可以认定这strKey是一个常量,于是我又去搜索了这个常量。
但是先等一下,这里通过add方法添加的四个参数正是上面post包中的四个加密参数。
这里的f构造函数传递了两个参数,是键值对的形式,然而第二个值的参数又调用了com.zfsoft.core.d.b.a类用的a方法,这个a方法传入的两个参数,第一个是明文,第二个称为paramString3的参数应该是某个加密参数,可能是key之类的,于是我在这里猜测,这应该是加密我们明文的地方。等会我用HOOK进入a方法劫持再看看,稍后作详解。
3.搜索了上面的常量strKey,在login的页面发现了这个参数,那应该就验证了上面的猜想了
进入内部看看
正好是传入的三个参数,但是a()方法的url有点不一样,先不管。反正第一个包的提交参数我们找齐了。
二、第二个POST包参数的加密分析
1.进入加密函数部分
这里我们进入com.zfsoft.core.d.b类用的a方法
我通过百度查得:
DESedeKeySpec是一个类 |
此类指定一个 DES-EDE ("triple-DES") 密钥 |
于是乎我明白了,这是3DES加密的过程,最后用Base64编码传回一个String类型的加密后的参数。
<strong>2.利用Xposed框架劫持这个a函数的传参和返回值</strong>
findAndHookMethod("com.zfsoft.core.d.b", loadPackageParam.classLoader, "a", String.class, String.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("传入参数1:"+param.args[0]+"传入参数2:"+param.args[1]);
XposedBridge.log("返回参数:"+param.getResult());
}
});
写完hook模块在模拟器上安装运行
通过app的login界面的输入完正确的帐号密码以后进入Center界面后,来到Xposed的日志查看劫持到的信息,发现参数参数2都是一样的,但是经过我测试,每次登录都是不一样的,在这里我猜测是第一次POST提交后返回的参数apptoken,对比一下前面的token长度很像,于是我copy代码到Eclipse中调试,看能否执行出正确的结果
e89fae90eb4e971134e077650f063118
211339b779db80ed9dc9ae495ec3d5fe
0x04模拟算法
1.直接复制转化过来的java代码
首先在Elipse中新建类主方法的类命名为jiami,自带主方法
再新建一个类命名为Base64.class,里面拷贝app中转换过来的Base64类中的全部代码
然后在jiami这个类中写加密的a方法:
public static String a(String paramString1, String paramString2) throws InvalidKeyException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
DESedeKeySpec deSedeKeySpec = null;
deSedeKeySpec = new DESedeKeySpec(paramString2.getBytes());
Key convertSecretKey = null;
convertSecretKey = SecretKeyFactory.getInstance("desede").generateSecret(deSedeKeySpec);
Cipher localCipher = null;
localCipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
localCipher.init(1, convertSecretKey, new IvParameterSpec("76543210".getBytes()));
return Base64.encode(localCipher.doFinal(paramString1.getBytes("utf-8")));
}
再在主方法中调用a方法:
public static void main(String[] args) {
try {
System.out.println(a("jw","e89fae90eb4e971134e077650f063118"));
System.out.println(a("WYNn2rNOtkuMGGlPrFSaMB0rQoBUmssS","e89fae90eb4e971134e077650f063118"));
} catch (InvalidKeyException | InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException
| InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException
| UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
执行java程序,在控制台我们可以看到计算出了正确的加密后的密文
至此,整个加密参数的流程我们已经全部了解。接下来我就用易语言把整个登录发包过程模拟一遍。
0x05模拟发包
因为里面有数据,这里我全部贴图了,不贴源文件了。
1.命名全局变量
2.写主方法
3.四个封装函数
Ⅰ
Ⅱ
Ⅲ
Ⅳ
4.执行结果
0x06总结
流程梳理:
抓包-分析参数-分析apk-java模拟加密-E语言实现
安卓逆向,我在路上~
2018年3月3日 18:36:49