2016武汉 Hurry Up Writeup

2017-09-30  本文已影响0人  hyrathon

Overview

题目给的APK包含Java和Android层代码, 代码结构清晰没有太多混淆, 反调试等.

Analysis

程序的入口MainActivity有问题, 无任何实际代码, 分析发现实际有效的是GetActivity, 调用了Encryption类和native的一些方法. 尝试改包或者am start强行启动GetActivity均告失败.分析so库发现, 代码的第一次验证函数getsign对整包签名做了native层校验, 且结果加入了后续flag计算.

写了一个小工程GetSign, 通过PackageManager获取了程序的签名, 很长一千多个字节, 将其传给第二个native函数getAnswer以期绕过完整性检验.

PackageManager  pm = getPackageManager();
        try {
            PackageInfo pi =  pm.getPackageInfo("com.example.root.crack_me2", PackageManager.GET_SIGNATURES);
            for (Signature s : pi.signatures){
                ssss += s.toCharsString() + "!!!!!!!!!!!!";
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            ssss += "error";
        }

结果程序无限卡死, 无法通过建立Activity的onCreate函数, 分析native函数发现其中计算返回值的算法时间复杂度极高, 有限时间内根本运算不完(下面列了出来), 但是, 其中有mod 45454的运算, 猜测结果不会超过这个范围, 因此, 可以暴力破解.

signed int __fastcall Java_com_example_root_crack_1me2_GetActivity_getAnswer(JNIEnv *env, jobject jobj, int int_50213)
{
  signed int result; // r0@1
  int v4; // r1@1
  int v5; // r7@1
  signed int v6; // r5@1
  signed int v7; // r4@2
  signed int v8; // r6@3
  signed int v9; // r1@4

  j_j___aeabi_idivmod(int_50213, 45454);
  result = 1;
  v5 = v4;
  v6 = 2110101010;
  do
  {
    v7 = 2110101010;
    do
    {
      v8 = 2110101010;
      do
      {
        j_j___aeabi_idivmod(result * v5, 45454);
        --v8;
        result = v9;
      }
      while ( v8 );
      --v7;
    }
    while ( v7 );
    --v6;
  }
  while ( v6 );
  return result;
}

Solution

写出来的暴力程序如下, 由于理论上有45454种结果, 而结果参与了后续运算, 不是所有的结果参与Encryption的运算都能返回结果, 另外, flag等字样很有可能出现在最终结果中, 因此可以进一步筛选.

        String v3 = null;
        String v1 = "tQJWYl+8C4cO2jwq782P5qc/9FXVF6cedVTtozSnyFk=";
        for (int i = 0; i < 45454; ++i) {
            try {
                v3 = Encryption.decrypt(Integer.toString(i), v1);
            } catch (Exception e) {

            }
            if (v3 == null)
                continue;
            if (v3.contains("flag")) {
                textView.setText(v3);
                v3 = null;
            }
        }

结果是getAnswer函数返回9953, 对应flag为flag{Y0u_need_t0_hu55y_up}.

上一篇下一篇

猜你喜欢

热点阅读