一、目标

一、目标

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

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

main
1:main

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

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

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

二、步骤

编辑加编译

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

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

base64
1:base64

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

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

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

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

然后在 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
  位置: 类 ModifiedBase64
2 个错误

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

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

导入了 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 ModifiedBase64
6a891a530cd69899

可以解密出来了。

打包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
// 打包jar
jar cvfe ModifiedBase64.jar ModifiedBase64 ModifiedBase64.class

打包要注意两点:

1、 e参数,来指定Main类

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

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

java -jar ModifiedBase64.jar DwO4EJPrDJCmY2G2EJq5EG==
6a891a530cd69899

完美收工。

三、总结

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

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

年轻人,学点java吧。

ffshow
1:ffshow

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

100

关注微信公众号,最新技术干货实时推送

100