首页
社区
课程
招聘
1
[原创]看雪CTF.TSRC 2018 团队赛第五题交响曲WP
发表于: 2018-12-11 10:03 4683

[原创]看雪CTF.TSRC 2018 团队赛第五题交响曲WP

2018-12-11 10:03
4683

本题是一个android apk文件。

1、解压缩apk文件,发现没有lib文件夹。只有java层代码,相对简单些了。

2、使用jeb和android killer分别打开apk文件,找到入口类:<activity android:name="cn.kwaiching.crackme.CrackMe">
从onCreate开始分析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  protected void onCreate(Bundle arg2) {
        super.onCreate(arg2);
        this.setContentView(2131296284);
        this.b();                                      //初始化字串,最终的正确结果显示
        this.n = this.findViewById(2131165242);
        this.findViewById(2131165273).setOnClickListener(new View$OnClickListener() {
            public void onClick(View arg3) {
                try {
                    CrackMe.a(this.a);                  //检测函数
                }
                catch(Exception ) {
                    this.a.n.setText(this.a.getString(2131427370));
                }
            }
        });
    }
}
1)b()函数
1
2
3
4
5
6
 private void b() {
        int v0;
        for(v0 = 0; v0 <= 72; ++v0) {
            this.l[v0] = v0 != 34 ? this.getResources().getString(2131427374) : this.getResources().getString(2131427375);
        }
    }
success00:I = 0x7f0b002e
success34:I = 0x7f0b002f
初始化的字串
2) CrackMe.a()函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    this.a = new int[]{16, 6, 7, 10, 9, 16, 10, 8, 8, 9, 6, 6};
    this.b = new int[]{5, 10, 8, 15, 16, 15, 8, 16, 8, 16, 9, 17, 8, 17, 10, 8, 9, 18, 5, 15, 10, 9, 8, 9, 15, 18, 7, 8, 16, 6};
    this.c = new int[]{6, 7, 18, 9, 5, 16, 9, 15, 18, 8, 9, 5};
    this.d = new int[]{7, 7, 9, 12, 8, 7, 13, 5, 14, 5, 9, 17, 5, 7, 12, 8, 8, 6, 19, 6, 8, 16, 10, 6, 12, 9, 6, 7, 12, 5, 9, 8, 7, 8, 15, 9, 16, 8, 8, 19, 12, 6, 8, 7, 5, 15, 6, 16, 15, 7, 9, 12, 10, 7, 15, 6, 5, 14, 14, 9};
    this.l = new String[73];
    this.m = new String[]{"23to01""01to03""03to05""05to07""07to09""09to11""11to13""13to15""15to17""17to19""19to21""21to23"};
 
 private void a() {
        int v0 = 2131427370;
        try {
            this.c();
            if(this.j != 0 && this.i != 0 && this.h != 0) {
                this.d();
                this.a(this.e() + this.f() + this.g() + this.h());
                return;
            }
 
            this.n.setText(this.getString(v0));
        }
        catch(Exception ) {
            this.n.setText(this.getString(v0));
        }
    }
此函数中的c(),d()函数分别对输入进行限制,转换。输入应该是年月日的字串(yyyy--mm-dd),并对年有限制((this.j <= 1983 || this.j >= 2007))可以考虑穷举爆破,继续分析。程序比较明了,code不贴了。
e(),f(),g(),h()函数分别从数组取值,如下:
1
2
3
4
return this.d[(this.g - 1900) % 60];            ---e()函数从数组d中取值
return this.c[this.f - 1];                      ---f()函数从数组c中取值
return this.b[this.e - 1];                      ---g()函数从数组b中取值
this.k = this.a[v4];                            ---h()根据输入的字串与数组m中比对得到的索引,从数组a中取出相应的值
从以上分析可知,输入字串的格式年月日+数组m中的某个字串。yyyy--mm-dd+str
3、判定结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    private void a(int arg8) {
        int v0 = 2131427370;
        int v1 = 34;
        if(arg8 <= v1)
         {
            if(arg8 < v1)
             {
            }
            else {
                try {
                    this.n.setText(String.format("%s%s"this.getString(2131427369), this.l[arg8]));
                    this.findViewById(2131165273).setEnabled(false);
                    return;
                label_23:
                    this.n.setText(this.getString(v0));
                }
                catch(Exception ) {
                    this.n.setText(this.getString(v0));
                }
 
                return;
            }
        }
 
        goto label_23;
    }
arg8 = this.e() + this.f() + this.g() + this.h()
从程序可以看出arg8 = 34返回正确结果。
4、暴力破解,根据上面的分析,模拟程序逻辑,爆破
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
void ctf5(void)
{
    int a[12] = { 16, 6, 7, 10, 9, 16, 10, 8, 8, 9, 6, 6 };
    int b[30] = { 5, 10, 8, 15, 16, 15, 8, 16, 8, 16, 9, 17, 8, 17, 10, 8, 9, 18, 5, 15, 10, 9, 8, 9, 15, 18, 7, 8, 16, 6 };
    int c[12] = { 6, 7, 18, 9, 5, 16, 9, 15, 18, 8, 9, 5 };
    int d[60] = { 7, 7, 9, 12, 8, 7, 13, 5, 14, 5, 9, 17, 5, 7, 12, 8, 8, 6, 19, 6, 8, 16, 10, 6, 12, 9, 6, 7, 12, 5, 9, 8, 7, 8, 15, 9, 16, 8, 8, 19, 12, 6, 8, 7, 5, 15, 6, 16, 15, 7, 9, 12, 10, 7, 15, 6, 5, 14, 14, 9 };
     
    int j = 0;  //1983 <  j< 2007 
    int i = 0        // i = 1 - 12
    int h = 0;   // h 1 - 31
    int k = 0;   //k不等于6
         
    int jj;
    int ii, hh;
    for (jj = 1984; jj < 2007; jj++)
    for (ii = 1; ii < 12; ii++)
    for (hh = 1; hh <= 31; hh++)
    for (k = 0; k < 12; k++)
    {
        j = jj;
        i = ii;
        h = hh;
        if (j == 1989 || j == 2004) 
        {
            h = 31;
        }
        if (i == 1 || i == 4 || i == 5 || i == 7 || i == 10 || i == 11 || i == 12) 
        {
            j = 1999;
        }
        int v2 = 8;
        int v3 = 6;
        int v4 = 2;
        if (j <= 1994 && (i == v4 || i == v3 || i == v2)) 
        {
            i = 3;
        }
        if (j >= 1996 && (i == v4 || i == v3 || i == v2)) 
        {
            i = 9;
        }
        if (j == 1995 && (h > i + v4 || i == h)) 
        {
            i = v3;
        }
        int g = j;
        int f = i;
        int e = h;
        int dd = d[(g - 1900) % 60];
        int cc = c[f - 1];
        int bb = b[e - 1];
        int kk = a[k];
        OutputDebugPrintf("j =%d\n", jj);
        int value =dd + cc+bb+kk;
        OutputDebugPrintf("value=%d\n", value);
        if (value == 34)
        {
            OutputDebugPrintf("ii = %d, jj= %d,h=%d,k=%d\n", ii, jj, hh, k);        //找到了
        }
    }
}<font color="#000000" face=""><span style="font-size:15px;">
</span></font>
flag:1995020305to07



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  protected void onCreate(Bundle arg2) {
        super.onCreate(arg2);
        this.setContentView(2131296284);
        this.b();                                      //初始化字串,最终的正确结果显示
        this.n = this.findViewById(2131165242);
        this.findViewById(2131165273).setOnClickListener(new View$OnClickListener() {
            public void onClick(View arg3) {
                try {
                    CrackMe.a(this.a);                  //检测函数
                }
                catch(Exception ) {
                    this.a.n.setText(this.a.getString(2131427370));
                }
            }
        });
    }
}
1)b()函数
1
2
3
4
5
6
 private void b() {
        int v0;
        for(v0 = 0; v0 <= 72; ++v0) {
            this.l[v0] = v0 != 34 ? this.getResources().getString(2131427374) : this.getResources().getString(2131427375);
        }
    }
success00:I = 0x7f0b002e
success34:I = 0x7f0b002f
1
2
3
4
5
6
 private void b() {
        int v0;
        for(v0 = 0; v0 <= 72; ++v0) {
            this.l[v0] = v0 != 34 ? this.getResources().getString(2131427374) : this.getResources().getString(2131427375);
        }
    }
success00:I = 0x7f0b002e
success34:I = 0x7f0b002f
success00:I = 0x7f0b002e
success34:I = 0x7f0b002f
初始化的字串
2) CrackMe.a()函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    this.a = new int[]{16, 6, 7, 10, 9, 16, 10, 8, 8, 9, 6, 6};
    this.b = new int[]{5, 10, 8, 15, 16, 15, 8, 16, 8, 16, 9, 17, 8, 17, 10, 8, 9, 18, 5, 15, 10, 9, 8, 9, 15, 18, 7, 8, 16, 6};
    this.c = new int[]{6, 7, 18, 9, 5, 16, 9, 15, 18, 8, 9, 5};
    this.d = new int[]{7, 7, 9, 12, 8, 7, 13, 5, 14, 5, 9, 17, 5, 7, 12, 8, 8, 6, 19, 6, 8, 16, 10, 6, 12, 9, 6, 7, 12, 5, 9, 8, 7, 8, 15, 9, 16, 8, 8, 19, 12, 6, 8, 7, 5, 15, 6, 16, 15, 7, 9, 12, 10, 7, 15, 6, 5, 14, 14, 9};
    this.l = new String[73];
    this.m = new String[]{"23to01""01to03""03to05""05to07""07to09""09to11""11to13""13to15""15to17""17to19""19to21""21to23"};
 
 private void a() {
        int v0 = 2131427370;
        try {
            this.c();
            if(this.j != 0 && this.i != 0 && this.h != 0) {
                this.d();
                this.a(this.e() + this.f() + this.g() + this.h());
                return;
            }
 
            this.n.setText(this.getString(v0));
        }
        catch(Exception ) {
            this.n.setText(this.getString(v0));
        }
    }
此函数中的c(),d()函数分别对输入进行限制,转换。输入应该是年月日的字串(yyyy--mm-dd),并对年有限制((this.j <= 1983 || this.j >= 2007))可以考虑穷举爆破,继续分析。程序比较明了,code不贴了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    this.a = new int[]{16, 6, 7, 10, 9, 16, 10, 8, 8, 9, 6, 6};
    this.b = new int[]{5, 10, 8, 15, 16, 15, 8, 16, 8, 16, 9, 17, 8, 17, 10, 8, 9, 18, 5, 15, 10, 9, 8, 9, 15, 18, 7, 8, 16, 6};
    this.c = new int[]{6, 7, 18, 9, 5, 16, 9, 15, 18, 8, 9, 5};
    this.d = new int[]{7, 7, 9, 12, 8, 7, 13, 5, 14, 5, 9, 17, 5, 7, 12, 8, 8, 6, 19, 6, 8, 16, 10, 6, 12, 9, 6, 7, 12, 5, 9, 8, 7, 8, 15, 9, 16, 8, 8, 19, 12, 6, 8, 7, 5, 15, 6, 16, 15, 7, 9, 12, 10, 7, 15, 6, 5, 14, 14, 9};
    this.l = new String[73];
    this.m = new String[]{"23to01""01to03""03to05""05to07""07to09""09to11""11to13""13to15""15to17""17to19""19to21""21to23"};
 
 private void a() {
        int v0 = 2131427370;
        try {
            this.c();
            if(this.j != 0 && this.i != 0 && this.h != 0) {
                this.d();
                this.a(this.e() + this.f() + this.g() + this.h());
                return;
            }
 
            this.n.setText(this.getString(v0));
        }
        catch(Exception ) {
            this.n.setText(this.getString(v0));
        }
    }
此函数中的c(),d()函数分别对输入进行限制,转换。输入应该是年月日的字串(yyyy--mm-dd),并对年有限制((this.j <= 1983 || this.j >= 2007))可以考虑穷举爆破,继续分析。程序比较明了,code不贴了。
e(),f(),g(),h()函数分别从数组取值,如下:
1
2
3
4
return this.d[(this.g - 1900) % 60];            ---e()函数从数组d中取值
return this.c[this.f - 1];                      ---f()函数从数组c中取值
return this.b[this.e - 1];                      ---g()函数从数组b中取值
this.k = this.a[v4];                            ---h()根据输入的字串与数组m中比对得到的索引,从数组a中取出相应的值
1
2
3
4
return this.d[(this.g - 1900) % 60];            ---e()函数从数组d中取值
return this.c[this.f - 1];                      ---f()函数从数组c中取值
return this.b[this.e - 1];                      ---g()函数从数组b中取值
this.k = this.a[v4];                            ---h()根据输入的字串与数组m中比对得到的索引,从数组a中取出相应的值

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
PLEBFE
为你点赞~
2023-2-1 00:34
最新回复 (4)
雪    币: 486
活跃值: (583)
能力值: ( LV12,RANK:238 )
在线值:
发帖
回帖
粉丝
2
请教下,为啥我的  jadx 0.8.0  反不了h函数?需要自己分析。其他的正常。
2018-12-11 14:18
0
雪    币: 486
活跃值: (583)
能力值: ( LV12,RANK:238 )
在线值:
发帖
回帖
粉丝
3
h函数反出来这效果。还需要自己分析 

private int m171h() {
        /*
        r6 = this;
        r0 = 2131165227; // 0x7f07002b float:1.7944665E38 double:1.0529355243E-314;
        r1 = 2131427370; // 0x7f0b002a float:1.8476354E38 double:1.05306504E-314;
        r2 = 0;
        r0 = r6.findViewById(r0);         Catch:{ Exception -> 0x005c }
        r0 = (android.widget.EditText) r0;         Catch:{ Exception -> 0x005c }
        r0 = r0.getText();         Catch:{ Exception -> 0x005c }
        r0 = r0.toString();         Catch:{ Exception -> 0x005c }
        r3 = 8;
        r4 = r0.length();         Catch:{ Exception -> 0x005c }
        r0 = r0.substring(r3, r4);         Catch:{ Exception -> 0x005c }
        r3 = r6.f117f;         Catch:{ Exception -> 0x005c }
        r4 = 0;
    L_0x0022:
        r5 = r6.f124m;         Catch:{ Exception -> 0x005c }
        r5 = r5.length;         Catch:{ Exception -> 0x005c }
        if (r4 >= r5) goto L_0x004d;
    L_0x0027:
        r5 = r6.f124m;         Catch:{ Exception -> 0x005c }
        r5 = r5[r4];         Catch:{ Exception -> 0x005c }
        r5 = r0.equals(r5);         Catch:{ Exception -> 0x005c }
        if (r5 == 0) goto L_0x004a;
    L_0x0031:
        r5 = 2;
        if (r3 != r5) goto L_0x0042;
    L_0x0034:
        r3 = r6.f124m;         Catch:{ Exception -> 0x005c }
        r5 = 6;
        r3 = r3[r5];         Catch:{ Exception -> 0x005c }
        r0 = r0.equals(r3);         Catch:{ Exception -> 0x005c }
        if (r0 == 0) goto L_0x0042;
    L_0x003f:
        r0 = 63;
        return r0;
    L_0x0042:
        r0 = r6.f112a;         Catch:{ Exception -> 0x005c }
        r0 = r0[r4];         Catch:{ Exception -> 0x005c }
        r6.f122k = r0;         Catch:{ Exception -> 0x005c }
        r0 = 1;
        goto L_0x004e;
    L_0x004a:
        r4 = r4 + 1;
        goto L_0x0022;
    L_0x004d:
        r0 = 0;
    L_0x004e:
        if (r0 != 0) goto L_0x0059;
    L_0x0050:
        r0 = r6.f125n;         Catch:{ Exception -> 0x005c }
        r3 = r6.getString(r1);         Catch:{ Exception -> 0x005c }
        r0.setText(r3);         Catch:{ Exception -> 0x005c }
    L_0x0059:
        r0 = r6.f122k;         Catch:{ Exception -> 0x005c }
        return r0;
    L_0x005c:
        r0 = r6.f125n;
        r1 = r6.getString(r1);
        r0.setText(r1);
        return r2;
        */
        throw new UnsupportedOperationException("Method not decompiled: cn.kwaiching.crackme.CrackMe.h():int");
    }
2018-12-11 14:20
0
雪    币: 6779
活跃值: (1324)
能力值: ( LV12,RANK:782 )
在线值:
发帖
回帖
粉丝
4
scpczc 请教下,为啥我的 jadx 0.8.0 反不了h函数?需要自己分析。其他的正常。
我用的是 jeb v2.0.6
2018-12-14 08:55
0
雪    币: 486
活跃值: (583)
能力值: ( LV12,RANK:238 )
在线值:
发帖
回帖
粉丝
5
3QkS
2018-12-14 15:30
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册