HNHuangJingYU 发表于 2021-9-29 19:29

《攻防世界》MOBILE--easy-apk

本帖最后由 HNHuangJingYU 于 2021-9-29 23:53 编辑

1. 照常将easy-apk.apk文件拉进jeb进行分析,这题看起来挺简单的,突破口就在MainActivity如图1:

2. 解题流程就是将输入的字符串获取byte集放入Base64New().Base64Encode()进行加密,再对比”5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=”嗯,那么这题主要就是逆向算法了进入到Base64New类进行分析,熟悉Base64的应该就知道这就是一个换了码表的Base64加密.
3. 对于我一个刚接触ctf人来说这种解密确实挺难的,但是呢没办法硬着头皮来,励志要当一名全能CTF的选手这些必备,我将加密操作拉进AS中加上动态分析发现并不难流程如下://因为Base64是二进制编码,二进制无非就是常规的算术、逻辑运算,所以编码转化都是可逆的
public String Base64Encode(byte[] bytes) {//字符串转化为byte数组,其实就是对字符串逐个ASCLL码组成的数列,然后对其二进制进行运算
    StringBuilder res = new StringBuilder();
    for (int i = 0; i <= bytes.length - 1; i += 3) {    //循环输入字符串个数循环lenght/3次 ,i%3==0,
      byte[] enBytes = new byte;       // 用于填充4个字节数据的寄存器,以4个字节为一组
      byte tmp = 0;                   //临时保存单个数据的寄存器
      for (int k = 0; k <= 2; k++) {//恒定循环3次     ,根据上面得出每次都会遍历,,
            if (i + k <= bytes.length - 1) {// 任何数 |0等于本身
                enBytes = (byte) (((bytes & 255) >>> ((k * 2) + 2)) | tmp);   //先与运算、右移零运算、或运算
                tmp = (byte) ((((bytes & 255) << (((2 - k) * 2) + 2)) & 255) >>> 2); //字符&255就是它的ASCLL码值
            } else {            //这里进来的情况是当输入的字符串长度不能被3整除 ,如果取余数为1则进来2次,如果取余数为2则进来1次
                enBytes = tmp;
                tmp = 64;
            }
      }
      enBytes = tmp;       //前面的循环只填充了4个字节的前3个,故这里填充最后一位
      for (int k2 = 0; k2 <= 3; k2++) {
            System.out.print(enBytes + ",");
            if (enBytes <= 63) {    //遍历每组数逐个判断是否小于64(这里用的是十进制) ,这里就和上面fork循环里面的else对应(tmp=64)
                res.append(Base64ByteToStr]);//按值取对应码表中的索引,,所以码表必须为64个字符
            } else {      //
                res.append('=');//这里就可以解释如果加密长度可以被整除则末尾0个=号,取余为1则末尾2个==号,取余为2则末尾1个=号;
            }
      }
    }       //总体思路就是将字符串以3个长度字节为一组进行或、位移运算,不足3个长度的一组用=代替
    return res.toString();
}
4. 这里引用下大神的逆向算法,实在没算出来
public void Base64Decode() {
    String enflag = "5rFf7E2K6rqN7Hpiyush7E6S5fJg6rsi5NBf6NGT5rs=";
    StringBuilder flag = new StringBuilder();
    String flag_temp = "";
    for (int i = 0; i < enflag.length(); i += 4) {
      String enf = enflag.substring(i, i + 4);
      byte flag1 = (byte) (((getIndex(enf.charAt(0)) & 255) << 2 | ((getIndex(enf.charAt(1)) & 255) >>> 4)));
      byte flag2 = (byte) (((getIndex(enf.charAt(1)) & 255) << 4 | ((getIndex(enf.charAt(2)) & 255) >>> 2)));
      byte flag3 = (byte) (((getIndex(enf.charAt(2)) & 255) << 6 | ((getIndex(enf.charAt(3)) & 255))));

      flag_temp = "" + (char) flag1 + (char) flag2 + (char) flag3;
      flag.append(flag_temp);
    }
    System.out.println(flag);
}

public byte getIndex(char x) {
    byte index = -1;
    String talbe = new String(Base64New.Base64ByteToStr);
    if (x != '=') {
      index = (byte) talbe.indexOf(x);
    } else {
      index = 0;
    }
    return index;
}

//输出最终flag:05397c42f9b6da593a3644162d36eb01

咔c君 发表于 2021-9-29 20:38

不错学习了

HNHuangJingYU 发表于 2021-9-29 22:11

咔c君 发表于 2021-9-29 20:38
不错学习了

很高兴可以帮助到大家

州哥在江湖 发表于 2021-9-30 12:54

感谢楼主分享,学习学习,现在好像吾爱教程贴很少了。

fireandfire 发表于 2021-10-2 14:31

感谢楼主分享,学习学习
页: [1]
查看完整版本: 《攻防世界》MOBILE--easy-apk