静态分析综合题目

2017 ISCC Crackone

利用 jadx 进行反编译,可以得到程序的基本逻辑如下

  • 对用户输入的内容进行 base64 编码,然后在指定长度位置处插入\r ,这个似乎并没有什么乱用。

  • 之后程序将编码后的内容传递给 so 中的 check 函数。这个函数的逻辑如下

  env = a1;
  len = plen;
  str = pstr;
  v7 = malloc(plen);
  ((*env)->GetByteArrayRegion)(env, str, 0, len, v7);
  v8 = malloc(len + 1);
  memset(v8, 0, len + 1);
  memcpy(v8, v7, len);
  v9 = 0;
  for ( i = 0; ; ++i )
  {
    --v9;
    if ( i >= len / 2 )
      break;
    v11 = v8[i] - 5;
    v8[i] = v8[len + v9];
    v8[len + v9] = v11;
  }
  v8[len] = 0;
  v12 = strcmp(v8, "=0HWYl1SE5UQWFfN?I+PEo.UcshU");
  free(v8);
  free(v7);
  return v12 <= 0;

不难看出,程序就是直接将 base64 之后的字符串的两半分别进行适当的操作,这里我们很容易写出 python 对应的恢复代码,如下

对应的结果如下

2017 NJCTF easycrack

通过简单逆向,可以发现程序的基本逻辑如下

  1. 监控界面文本框,如果文本框内容改变则调用 native parseText 函数。

  2. parseText 的主要功能如下 1. 首先调用 java 层的函数 messageMe 获取一个字符串 mestr。这个函数的逻辑基本是

    1. 依次将 packagename 的最后一个 . 后面的字符串的每一个与 51进行异或,将结果拼接起来。 2. 然后以 mestr 长度为周期,将两者进行异或,核心逻辑 str[i + j] = mestr[j] ^ iinput[i + j]; 3. 继而下面以 I_am_the_key 为密钥,使用 RC4 加密对该部分进行加密,然后将结果与最后的 compare 比较。这里猜测的依据如下

    2. 在 init 函数中有 256 这个关键字,而且基本就是 RC4 密钥的初始化过程。

    3. crypt 函数显然就是一个 RC4 加密函数,明显就是 RC4 的加密逻辑。

解密脚本如下

结果如下

2018 强网杯 picture lock

简单分析之后发现这是一个图片加密程序:java 层为 native 层传入 image/ 下的第一个文件名,以及希望加密后的图片文件名,包括对应的 apk 的签名的 md5。

下面我们就可以分析 native 层代码,由于程序很明显说是一个加密程序,我们可以使用IDA 的 findcrypto 插件来进行识别,结果却是发现了 S 盒,而且基本上就是符合 AES 的加密流程的,所以可以基本确定程序的主体是一个 AES 加密,经过细致分析可以发现 native 层程序的基本流程如下

  1. 将传入的签名的 md5 字符串分为两半,生成两组密钥。

  2. 每次读入md5sig[i%32]大小的内容

  3. 根据读入的大小决定使用哪一组密钥

    1. 奇数使用第二组密钥

    2. 偶数使用第一组密钥

  4. 如果读入的大小不够 16 的话,就将后面填充为不够的大小(比如大小为12时,填充 4 个0x4)

  5. 这时修改后的内容必然够16个字节,对前16个字节进行 AES 加密。对于后面的字节,将其与 md5sig[i%32]依次进行异或。

既然知道加密算法后,那就很容易逆了,我们首先可以获取签名的 md5,如下

继而,我们可以直接使用已有的 AES 库来进行解密

最后可以得到一个图片解密后的结果,其中就包含 flag 了。

Last updated