写点什么

手把手教你从 Apk 中取出算法

作者:奋飞安全
  • 2022 年 3 月 25 日
  • 本文字数:2129 字

    阅读完需:约 7 分钟

一、目标

李老板: 奋飞呀,我最近从 Apk 里面跟踪到一个算法,代码清晰,但是我不会 java,把他翻译成 python 貌似挺费劲的,有没有轻松省力的方法呀?


奋飞: 有的呀,给我加工资,我来翻译。



某电商 App v10.4.5, 升级之后老有小伙伴说他的 sign 算法变了,其实他就是做了点小动作。sign 参数没有动,uuid 是明文去做签名,但是抓包请求里面找不到明文 uuid,而是藏在 ep 参数里面,做了一次加密。


今天我们就来手把手教大家扣出这个加密算法。


java 老艺术家就不用往下看了,你们都会。

二、步骤

编辑加编译

大家也跟了这么多期了,如何找到 ep,如何定位 uuid 的加密算法这个步骤,可以自行完成,需要提醒一下的就是,这个 uuid 加密还有缓存,同样的数据被加密一次之后就会记入一个 map 里面。下次优先找这个 map,所以很多时候都不会触发你 hook 的加密函数。


但是不要怀疑,你找的就是对的。



今天的大 boss 就是它,从名称上看貌似是个魔改的 Base64 算法。


有理想的同学可以试着翻译成别的语言,当然我们今天要做的不是翻译,而是把他扣出来,直接利用。


首先创建一个 ModifiedBase64.java 文件,把 jadx 反编译的结果拷贝进去。


把文件第一行的 包名 删掉,就是那个 package xxx;


TIP: 有包名的话,后面运行的时候需要带上包名,为了简单起见,直接把他删除了吧


然后在 ModifiedBase64 类里面增加一个 Main 函数


public static void main(String[] args) throws Exception{    ModifiedBase64 zObj = new ModifiedBase64();    String strIn = "DwO4EJPrDJCmY2G2EJq5EG==";            String strOut = new String(zObj.m23209eC(strIn));    System.out.println(strOut);
}
复制代码


这就 ok 了,然后开始编译


javac ModifiedBase64.java
ModifiedBase64.java:1: 错误: 程序包com.google.common.primitives不存在import com.google.common.primitives.SignedBytes; ^ModifiedBase64.java:63: 错误: 找不到符号 b = SignedBytes.MAX_POWER_OF_TWO; ^ 符号: 变量 SignedBytes 位置: 类 ModifiedBase642 个错误
复制代码


报错了,有个包名找不到,常规做法是引入这个包名。


不过我们仔细观察下,发现这个包就干了一件事。


导入了 SignedBytes.MAX_POWER_OF_TWO; 常量。


光吃饭,不干活,那就别怪我们不客气了,问问谷哥。


哥说了


public static final byte MAX_POWER_OF_TWO = 1 << 6;
复制代码


掐指一算,这不就是 0x40 嘛 ,毫不犹豫删掉这个包,然后把 b 的赋值直接改成 0x40


重新编译


javac ModifiedBase64.java
ModifiedBase64.java:41: 错误: 无法访问的语句 while (true) { ^1 个错误
复制代码


还有错, 这不科学呀。


仔细看看这个 pf 函数 ,确实不科学


public static void m23208pf() throws Exception {    int i = 0;    int i2 = 0;    while (true) {        byte[] bArr = aaf;        if (i2 <= bArr.length - 1) {            bArr[i2] = -1;            i2++;        }        }
while (true) { char[] cArr = aae; if (i <= cArr.length - 1) { aaf[cArr[i]] = (byte) i; i++; } else { return; } }}
复制代码


第一个 while 成死循环了,根本不会往下跑。


应该是 jadx 不乖了, 结合下 jeb 的翻译结果,我们给他加上个退出机制


public static void m23208pf() throws Exception {    int i = 0;    int i2 = 0;    while (true) {        byte[] bArr = aaf;        if (i2 <= bArr.length - 1) {            bArr[i2] = -1;            i2++;        }else{        break;       }    }
while (true) { char[] cArr = aae; if (i <= cArr.length - 1) { aaf[cArr[i]] = (byte) i; i++; } else { return; } }}
复制代码


完美,这下编译成功,跑一下


javac ModifiedBase64.java java ModifiedBase646a891a530cd69899
复制代码


可以解密出来了。

打包 jar

这还没完,我们总不能每次都去改代码,最好可以传个参数进去调用。


先改改代码


public static void main(String[] args) throws Exception{    ModifiedBase64 zObj = new ModifiedBase64();    String strIn = args[0];            String strOut = new String(zObj.m23209eC(strIn));    System.out.println(strOut);
}
复制代码


密文不再写死,而是传参进去。


// 编译javac ModifiedBase64.java// 打包jarjar cvfe ModifiedBase64.jar ModifiedBase64 ModifiedBase64.class
复制代码


打包要注意两点:


1、 e 参数,来指定 Main 类


2、 打包文件是编译之后的 .class 而不是 .java


成功之后生成 ModifiedBase64.jar ,就可以命令行调用了


java -jar ModifiedBase64.jar DwO4EJPrDJCmY2G2EJq5EG==6a891a530cd69899
复制代码


完美收工。

三、总结

要练就火眼金睛,hook 是不会骗人的,参数没变,算法没变,只是多套了一层做了加密而已。


手工编译 java 和打包,了解原理即可,简单的算法这么搞,复杂一点的还是上 IDEA 吧。


年轻人,学点 java 吧。



人们曾经不只是为了某个具体的目的去研究一个个具体的问题,而是追求深层次的真理,又怎样由此而造出美好的世界,这就是创造。

发布于: 刚刚阅读数: 2
用户头像

奋飞安全

关注

独立安全研究员。 公众号: 奋飞安全 2022.02.21 加入

少习文,经史子集略有涉猎;北上学艺,A-Z语言敢说略懂;初入江湖,混入外企,乐不思蜀;后为人父,发愤图强,略有建树;而今重新出发,万事随缘。

评论

发布
暂无评论
手把手教你从Apk中取出算法_android_奋飞安全_InfoQ写作平台