AVALON 强网杯2018 2018强网杯simplecheck write_up

2018强网杯simplecheck write_up

环境配置

系统 : Linux kali 4.15.0-kali2-amd64 \ win10 64bit
程序 : simplecheck_1982yrejnxy2189236t4c7816025789346dx1h782635789cb12653
要求 : 输入口令
使用工具 :ApkToolBox Studio(APK反编译工具集) v1.6.4免费版 include(jadx and dex2jar)

开始分析

拿信息

使用file命令拿信息:

➜  playground file simplecheck_1982yrejnxy2189236t4c7816025789346dx1h782635789cb12653 
simplecheck_1982yrejnxy2189236t4c7816025789346dx1h782635789cb12653: Zip archive data, at least v2.0 to extract

发现是一个zip文件,那么直接解压看看:

➜  playground unzip ./simplecheck_1982yrejnxy2189236t4c7816025789346dx1h782635789cb12653 
Archive:  ./simplecheck_1982yrejnxy2189236t4c7816025789346dx1h782635789cb12653
  inflating: AndroidManifest.xml     
  inflating: META-INF/CERT.RSA       
  inflating: META-INF/CERT.SF        
  inflating: META-INF/MANIFEST.MF    
  inflating: classes.dex             
# 忽略其他文件

看到解压出了dex文件,这里直接使用反编译工具集将dex转换成jar,再拖入jadx进行分析。

静态分析

代码修饰

这里,在jadx的菜单中点击文件->设置->启用反混淆,接着选择
显示不一致的代码。这时,可以发现代码漂亮了不少。

主函数

我们直接查看MainActivity的代码:

package com.p022a.simplecheck;

import android.os.Bundle;
import android.support.p014v7.app.C0333c;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.Toast;

/* renamed from: com.a.simplecheck.MainActivity */
public class MainActivity extends C0333c {
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(2130968603);
        final EditText editText = (EditText) findViewById(2131427422);
        findViewById(2131427423).setOnClickListener(new OnClickListener(this) {
            /* renamed from: c */
            final /* synthetic */ MainActivity f1762c;

            public void onClick(View view) {
                if (C0565a.m2542a(editText.getText().toString())) {
                    Toast.makeText(this, "You get it~", 1).show();
                } else {
                    Toast.makeText(this, "Sorry its wrong", 1).show();
                }
            }
        });
    }
}

关键流程

一个很简单的流程,我们接着查看C0565a.m2542a这个函数:

package com.p022a.simplecheck;

/* renamed from: com.a.simplecheck.a */
public class C0565a {
    /* renamed from: a */
    private static int[] f1763a = new int[]{0, 146527998, 205327308, 94243885, 138810487, 408218567, 77866117, 71548549, 563255818, 559010506, 449018203, 576200653, 307283021, 467607947, 314806739, 341420795, 341420795, 469998524, 417733494, 342206934, 392460324, 382290309, 185532945, 364788505, 210058699, 198137551, 360748557, 440064477, 319861317, 676258995, 389214123, 829768461, 534844356, 427514172, 864054312};
    /* renamed from: b */
    private static int[] f1764b = new int[]{13710, 46393, 49151, 36900, 59564, 35883, 3517, 52957, 1509, 61207, 63274, 27694, 20932, 37997, 22069, 8438, 33995, 53298, 16908, 30902, 64602, 64028, 29629, 26537, 12026, 31610, 48639, 19968, 45654, 51972, 64956, 45293, 64752, 37108};
    /* renamed from: c */
    private static int[] f1765c = new int[]{38129, 57355, 22538, 47767, 8940, 4975, 27050, 56102, 21796, 41174, 63445, 53454, 28762, 59215, 16407, 64340, 37644, 59896, 41276, 25896, 27501, 38944, 37039, 38213, 61842, 43497, 9221, 9879, 14436, 60468, 19926, 47198, 8406, 64666};
    /* renamed from: d */
    private static int[] f1766d = new int[]{0, -341994984, -370404060, -257581614, -494024809, -135267265, 54930974, -155841406, 540422378, -107286502, -128056922, 265261633, 275964257, 119059597, 202392013, 283676377, 126284124, -68971076, 261217574, 197555158, -12893337, -10293675, 93868075, 121661845, 167461231, 123220255, 221507, 258914772, 180963987, 107841171, 41609001, 276531381, 169983906, 276158562};

    /* renamed from: a */
    public static boolean m2542a(String str) {
        if (str.length() != f1764b.length) {
            return false;
        }
        int[] iArr = new int[f1763a.length];
        iArr[0] = 0;
        int i = 1;
        for (byte b : str.getBytes()) {
            iArr[i] = b;
            i++;
        }
        i = 0;
        while (i < f1765c.length) {
            if (f1763a[i] != (((f1764b[i] * iArr[i]) * iArr[i]) + (f1765c[i] * iArr[i])) + f1766d[i] || f1763a[i + 1] != (((f1764b[i] * iArr[i + 1]) * iArr[i + 1]) + (f1765c[i] * iArr[i + 1])) + f1766d[i]) {
                return false;
            }
            i++;
        }
        return true;
    }
}

程序提前将前一个字节的值0告诉读者,让读者自己推导iArr[i+1]可能的值。

逻辑推理

我们发现byte的取值范围不大,所以可以穷举[0,127]这个范围的值,来爆破出满足程序要求的flag。

编写程序

按照以上逻辑,编写python程序如下:

f1763a = [0, 146527998, 205327308, 94243885, 138810487, 408218567, 77866117, 71548549, 563255818, 559010506, 449018203, 576200653, 307283021, 467607947, 314806739, 341420795, 341420795, 469998524, 417733494, 342206934, 392460324, 382290309, 185532945, 364788505, 210058699, 198137551, 360748557, 440064477, 319861317, 676258995, 389214123, 829768461, 534844356, 427514172, 864054312]
f1764b = [13710, 46393, 49151, 36900, 59564, 35883, 3517, 52957, 1509, 61207, 63274, 27694, 20932, 37997, 22069, 8438, 33995, 53298, 16908, 30902, 64602, 64028, 29629, 26537, 12026, 31610, 48639, 19968, 45654, 51972, 64956, 45293, 64752, 37108]
f1765c = [38129, 57355, 22538, 47767, 8940, 4975, 27050, 56102, 21796, 41174, 63445, 53454, 28762, 59215, 16407, 64340, 37644, 59896, 41276, 25896, 27501, 38944, 37039, 38213, 61842, 43497, 9221, 9879, 14436, 60468, 19926, 47198, 8406, 64666]
f1766d = [0, -341994984, -370404060, -257581614, -494024809, -135267265, 54930974, -155841406, 540422378, -107286502, -128056922, 265261633, 275964257, 119059597, 202392013, 283676377, 126284124, -68971076, 261217574, 197555158, -12893337, -10293675, 93868075, 121661845, 167461231, 123220255, 221507, 258914772, 180963987, 107841171, 41609001, 276531381, 169983906, 276158562]

def m2542a(first,second,i):
    if f1763a[i] != (((f1764b[i] * first) * first) + (f1765c[i] * first)) + f1766d[i] or f1763a[i + 1] != (((f1764b[i] * second) * second) + (f1765c[i] * second)) + f1766d[i]:
        return False
    return True

flag = ""
first = 0
for index in range(0,len(f1764b)):
    for tmp in range(0,128):
        if m2542a(first,tmp,index):
            flag += chr(tmp)
            first = tmp

print flag
assert flag == "flag{MAth_i&_GOOd_DON7_90V_7hInK?}"

参考链接

  1. [原创]看雪CTF_2018 团队赛 第五题 write up(吃我十六字阴阳风水秘术) https://bbs.pediy.com/thread-248308.htm
  2. 强网杯qwb 2018 reverse writeup http://www.leadroyal.cn/?p=471