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

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

2018-12-10 11:31
3460

因为这个apk文件没有so文件,所以仅仅是静态分析也可以做出来。首先通过dex2jar工具转换到jar文件,在通过jd-gui打开这个jar文件就可以查看这个程序的java源码。不过这个程序使用了proguard保护机制,对变量名和函数名进行了混淆,不过这并不妨碍对这个程序验证逻辑的分析。反编译效果如下:

当点击按钮进行验证时会执行onClick函数,然后通过a函数进行判断,验证逻辑如下:
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
  private void a()
  {
    try
    {
      c();
      if ((this.j != 0) && (this.i != 0) && (this.h != 0))
      {
        d();
        a(e() + f() + g() + h());
        return;
      }
      this.n.setText(getString(2131427370));
    }
    catch (Exception localException)
    {
      this.n.setText(getString(2131427370));
    }
  }
   
  private void a(int paramInt)
  {
    if ((paramInt <= 34) && (paramInt >= 34)) {}
    try
    {
      this.n.setText(String.format("%s%s"new Object[] { getString(2131427369), this.l[paramInt] }));
      ((Button)findViewById(2131165273)).setEnabled(false);
    }
    catch (Exception localException)
    {
      this.n.setText(getString(2131427370));
    }
    this.n.setText(getString(2131427370));
  }
可以清晰的看出这个程序的验证逻辑,this.l是个String类型的数组,在b函数中初始化。b函数的代码如下:
1
2
3
4
5
6
7
8
9
10
  private void b()
  {
    for (int i1 = 0; i1 <= 72; i1++) {
      if (i1 != 34) {
        this.l[i1] = getResources().getString(2131427374);
      else {
        this.l[i1] = getResources().getString(2131427375);
      }
    }
  }
通过jadx可以查看到资源文件中的字符串id对应的信息
1
2
3
<public type="string" name="success00" id="2131427374" />
<public type="string" name="success34" id="2131427375" />
<string name="success34">\10財穀有餘主得內助富貴之命\10\10\10此命福氣果如何,僧道門中衣祿多;\10離祖出家方為妙,朝晚拜佛念彌陀。\10\10\10\10此命推來為人性躁;\10與人做事反為不美;\10離祖成家;\10三番四次自成自立安享福;\10直自三十六至四十六;\10財不謀而自至;\10福不求而自得;\10有貴人助;\10家庭安寧;\10妻宮若要無刑;\10猴、豬、羊、蛇不可配;\10龍、虎、馬、牛方得安;\10雖有二子;\10終生帶暗方可.\10兄弟六親如冰碳;\10在家不得安然;\10初限駁雜多端;\10勞碌奔波不能聚錢;\10常有憂愁.\10壽元七十八歲;\10死於三月中.</string>
所以这个带参数的a函数是最终的验证 ,接下来就可以重点分析c,d,e,f,g,h这几个函数。通过c函数判断出sn的长度要大于8个字符,1983<int(sn[0:4])<2007,1<=int(sn[4:6])<=12,1<= int(sn[6:8])<=31 。我把这几个函数的运算逻辑转换到如下python代码:
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
= 1667109161088966 ]
= 510815161581681691781710891851510989151878166 ]
= 6718951691518895 ]
= 7791287135145917571288619681610612967125987815916881912687515616157912107156514149 ]
e=0
f=0
g=0
h=0
i=0
j=0
k=0
= "23to01""01to03""03to05""05to07""07to09""09to11""11to13""13to15""15to17""17to19""19to21""21to23" ]
 
def calc(sn):
    = int(sn[0:4])  # 1983<j<2007
    = int(sn[4:6])  # 1 <= i <= 12
    = int(sn[6:8])  # 1 <= h <= 31
     
    if ((j == 1989or (j == 2004)):
        = 31
    if ((i == 1or (i == 4or (i == 5or (i == 7or (i == 10or (i == 11or (i == 12)):
        = 1999
    if ((j <= 1994and ((i == 2or (i == 6or (i == 8))):
        = 3
    if ((j >= 1996and ((i == 2or (i == 6or (i == 8))):
        = 9
    if ((j == 1995and ((h > i + 2or (i == h))):
        = 6
    = j
    = i
    = h
     
    t1 = d[(g-1900)%60]
    t2 = c[f-1]
    t3 = b[e-1]
    t4 = 0
     
    t_str = sn[8::]
    for i2 in range(len(m)):
        if(t_str == m[i2]):
            if(f==2 and t_str==m[6]):
                t4 = 63
                break
            = a[i2]
            t4=k
             
    return t1+t2+t3+t4
calc(sn)的返回值要为34才能通过验证,所以可以直接采用穷举来解这个题。穷举脚本如下:
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
def calc2(j,i,h,t_str):
    if ((j == 1989or (j == 2004)):
        = 31
    if ((i == 1or (i == 4or (i == 5or (i == 7or (i == 10or (i == 11or (i == 12)):
        = 1999
    if ((j <= 1994and ((i == 2or (i == 6or (i == 8))):
        = 3
    if ((j >= 1996and ((i == 2or (i == 6or (i == 8))):
        = 9
    if ((j == 1995and ((h > i + 2or (i == h))):
        = 6
    g1 = j
    f1 = i
    e1 = h
     
    t1 = d[(g1-1900)%60]
    t2 = c[f1-1]
    t3 = b[e1-1]
    t4 = 0
     
    for i2 in range(len(m)):
        if(t_str == m[i2]):
            if(f==2 and t_str==m[6]):
                t4 = 63
                break
            k1 = a[i2]
            t4=k1
             
    return t1+t2+t3+t4
     
for in range(1984,2007):
    for in range(1,13):
        for in range(1,32):
            for t_str in m:
                try:
                    if(calc2(j,i,h,t_str) == 34):
                        print(("%04d%02d%02d%s")%(j,i,h,t_str))
                except:
                    continue
穷举出两个值 1995020305to07 ,1995020311to13。正确的sn为1995020305to07

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
  private void a()
  {
    try
    {
      c();
      if ((this.j != 0) && (this.i != 0) && (this.h != 0))
      {
        d();
        a(e() + f() + g() + h());
        return;
      }
      this.n.setText(getString(2131427370));
    }
    catch (Exception localException)
    {
      this.n.setText(getString(2131427370));
    }
  }
   
  private void a(int paramInt)
  {
    if ((paramInt <= 34) && (paramInt >= 34)) {}
    try
    {
      this.n.setText(String.format("%s%s"new Object[] { getString(2131427369), this.l[paramInt] }));
      ((Button)findViewById(2131165273)).setEnabled(false);
    }
    catch (Exception localException)
    {
      this.n.setText(getString(2131427370));
    }
    this.n.setText(getString(2131427370));
  }
可以清晰的看出这个程序的验证逻辑,this.l是个String类型的数组,在b函数中初始化。b函数的代码如下:
1
2
3
4
5
6
7
8
9
10
  private void b()
  {
    for (int i1 = 0; i1 <= 72; i1++) {
      if (i1 != 34) {
        this.l[i1] = getResources().getString(2131427374);
      else {
        this.l[i1] = getResources().getString(2131427375);
      }
    }
  }
通过jadx可以查看到资源文件中的字符串id对应的信息
1
2
3
<public type="string" name="success00" id="2131427374" />
<public type="string" name="success34" id="2131427375" />
<string name="success34">\10財穀有餘主得內助富貴之命\10\10\10此命福氣果如何,僧道門中衣祿多;\10離祖出家方為妙,朝晚拜佛念彌陀。\10\10\10\10此命推來為人性躁;\10與人做事反為不美;\10離祖成家;\10三番四次自成自立安享福;\10直自三十六至四十六;\10財不謀而自至;\10福不求而自得;\10有貴人助;\10家庭安寧;\10妻宮若要無刑;\10猴、豬、羊、蛇不可配;\10龍、虎、馬、牛方得安;\10雖有二子;\10終生帶暗方可.\10兄弟六親如冰碳;\10在家不得安然;\10初限駁雜多端;\10勞碌奔波不能聚錢;\10常有憂愁.\10壽元七十八歲;\10死於三月中.</string>
所以这个带参数的a函数是最终的验证 ,接下来就可以重点分析c,d,e,f,g,h这几个函数。通过c函数判断出sn的长度要大于8个字符,1983<int(sn[0:4])<2007,1<=int(sn[4:6])<=12,1<= int(sn[6:8])<=31 。我把这几个函数的运算逻辑转换到如下python代码:
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
= 1667109161088966 ]
= 510815161581681691781710891851510989151878166 ]
= 6718951691518895 ]
= 7791287135145917571288619681610612967125987815916881912687515616157912107156514149 ]
e=0
f=0
g=0
h=0
i=0
j=0
k=0
= "23to01""01to03""03to05""05to07""07to09""09to11""11to13""13to15""15to17""17to19""19to21""21to23" ]
 
def calc(sn):
    = int(sn[0:4])  # 1983<j<2007
    = int(sn[4:6])  # 1 <= i <= 12
    = int(sn[6:8])  # 1 <= h <= 31
     
    if ((j == 1989or (j == 2004)):
        = 31
    if ((i == 1or (i == 4or (i == 5or (i == 7or (i == 10or (i == 11or (i == 12)):
        = 1999
    if ((j <= 1994and ((i == 2or (i == 6or (i == 8))):
        = 3
    if ((j >= 1996and ((i == 2or (i == 6or (i == 8))):
        = 9
    if ((j == 1995and ((h > i + 2or (i == h))):
        = 6
    = j
    = i
    = h
     
    t1 = d[(g-1900)%60]
    t2 = c[f-1]
    t3 = b[e-1]
    t4 = 0
     
    t_str = sn[8::]
    for i2 in range(len(m)):
        if(t_str == m[i2]):
            if(f==2 and t_str==m[6]):
                t4 = 63
                break
            = a[i2]
            t4=k
             
    return t1+t2+t3+t4
calc(sn)的返回值要为34才能通过验证,所以可以直接采用穷举来解这个题。穷举脚本如下:
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
def calc2(j,i,h,t_str):
    if ((j == 1989or (j == 2004)):
        = 31
    if ((i == 1or (i == 4or (i == 5or (i == 7or (i == 10or (i == 11or (i == 12)):
        = 1999
    if ((j <= 1994and ((i == 2or (i == 6or (i == 8))):
        = 3
    if ((j >= 1996and ((i == 2or (i == 6or (i == 8))):
        = 9
    if ((j == 1995and ((h > i + 2or (i == h))):
        = 6
    g1 = j
    f1 = i
    e1 = h
     
    t1 = d[(g1-1900)%60]
    t2 = c[f1-1]
    t3 = b[e1-1]
    t4 = 0
     
    for i2 in range(len(m)):
        if(t_str == m[i2]):
            if(f==2 and t_str==m[6]):
                t4 = 63
                break
            k1 = a[i2]
            t4=k1
             
    return t1+t2+t3+t4
     
for in range(1984,2007):
    for in range(1,13):
        for in range(1,32):
            for t_str in m:
                try:
                    if(calc2(j,i,h,t_str) == 34):
                        print(("%04d%02d%02d%s")%(j,i,h,t_str))
                except:
                    continue
穷举出两个值 1995020305to07 ,1995020311to13。正确的sn为1995020305to07

1
2
3
4
5
6
7
8
9
10
  private void b()
  {
    for (int i1 = 0; i1 <= 72; i1++) {
      if (i1 != 34) {
        this.l[i1] = getResources().getString(2131427374);
      else {
        this.l[i1] = getResources().getString(2131427375);
      }
    }
  }
通过jadx可以查看到资源文件中的字符串id对应的信息
1
2
3
<public type="string" name="success00" id="2131427374" />
<public type="string" name="success34" id="2131427375" />
<string name="success34">\10財穀有餘主得內助富貴之命\10\10\10此命福氣果如何,僧道門中衣祿多;\10離祖出家方為妙,朝晚拜佛念彌陀。\10\10\10\10此命推來為人性躁;\10與人做事反為不美;\10離祖成家;\10三番四次自成自立安享福;\10直自三十六至四十六;\10財不謀而自至;\10福不求而自得;\10有貴人助;\10家庭安寧;\10妻宮若要無刑;\10猴、豬、羊、蛇不可配;\10龍、虎、馬、牛方得安;\10雖有二子;\10終生帶暗方可.\10兄弟六親如冰碳;\10在家不得安然;\10初限駁雜多端;\10勞碌奔波不能聚錢;\10常有憂愁.\10壽元七十八歲;\10死於三月中.</string>
所以这个带参数的a函数是最终的验证 ,接下来就可以重点分析c,d,e,f,g,h这几个函数。通过c函数判断出sn的长度要大于8个字符,1983<int(sn[0:4])<2007,1<=int(sn[4:6])<=12,1<= int(sn[6:8])<=31 。我把这几个函数的运算逻辑转换到如下python代码:
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
= 1667109161088966 ]
= 510815161581681691781710891851510989151878166 ]
= 6718951691518895 ]
= 7791287135145917571288619681610612967125987815916881912687515616157912107156514149 ]
e=0
f=0
g=0
h=0
i=0
j=0
k=0
= "23to01""01to03""03to05""05to07""07to09""09to11""11to13""13to15""15to17""17to19""19to21""21to23" ]
 
def calc(sn):
    = int(sn[0:4])  # 1983<j<2007
    = int(sn[4:6])  # 1 <= i <= 12
    = int(sn[6:8])  # 1 <= h <= 31
     
    if ((j == 1989or (j == 2004)):
        = 31
    if ((i == 1or (i == 4or (i == 5or (i == 7or (i == 10or (i == 11or (i == 12)):
        = 1999
    if ((j <= 1994and ((i == 2or (i == 6or (i == 8))):
        = 3
    if ((j >= 1996and ((i == 2or (i == 6or (i == 8))):
        = 9
    if ((j == 1995and ((h > i + 2or (i == h))):
        = 6
    = j
    = i
    = h
     
    t1 = d[(g-1900)%60]
    t2 = c[f-1]
    t3 = b[e-1]
    t4 = 0
     
    t_str = sn[8::]
    for i2 in range(len(m)):
        if(t_str == m[i2]):
            if(f==2 and t_str==m[6]):
                t4 = 63
                break
            = a[i2]
            t4=k
             
    return t1+t2+t3+t4
calc(sn)的返回值要为34才能通过验证,所以可以直接采用穷举来解这个题。穷举脚本如下:
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
def calc2(j,i,h,t_str):
    if ((j == 1989or (j == 2004)):
        = 31
    if ((i == 1or (i == 4or (i == 5or (i == 7or (i == 10or (i == 11or (i == 12)):
        = 1999
    if ((j <= 1994and ((i == 2or (i == 6or (i == 8))):
        = 3
    if ((j >= 1996and ((i == 2or (i == 6or (i == 8))):
        = 9
    if ((j == 1995and ((h > i + 2or (i == h))):
        = 6
    g1 = j
    f1 = i
    e1 = h
     
    t1 = d[(g1-1900)%60]
    t2 = c[f1-1]
    t3 = b[e1-1]
    t4 = 0
     
    for i2 in range(len(m)):
        if(t_str == m[i2]):
            if(f==2 and t_str==m[6]):
                t4 = 63
                break
            k1 = a[i2]
            t4=k1
             
    return t1+t2+t3+t4
     
for in range(1984,2007):
    for in range(1,13):
        for in range(1,32):
            for t_str in m:
                try:
                    if(calc2(j,i,h,t_str) == 34):
                        print(("%04d%02d%02d%s")%(j,i,h,t_str))
                except:
                    continue
穷举出两个值 1995020305to07 ,1995020311to13。正确的sn为1995020305to07

1
2
3
<public type="string" name="success00" id="2131427374" />
<public type="string" name="success34" id="2131427375" />
<string name="success34">\10財穀有餘主得內助富貴之命\10\10\10此命福氣果如何,僧道門中衣祿多;\10離祖出家方為妙,朝晚拜佛念彌陀。\10\10\10\10此命推來為人性躁;\10與人做事反為不美;\10離祖成家;\10三番四次自成自立安享福;\10直自三十六至四十六;\10財不謀而自至;\10福不求而自得;\10有貴人助;\10家庭安寧;\10妻宮若要無刑;\10猴、豬、羊、蛇不可配;\10龍、虎、馬、牛方得安;\10雖有二子;\10終生帶暗方可.\10兄弟六親如冰碳;\10在家不得安然;\10初限駁雜多端;\10勞碌奔波不能聚錢;\10常有憂愁.\10壽元七十八歲;\10死於三月中.</string>
所以这个带参数的a函数是最终的验证 ,接下来就可以重点分析c,d,e,f,g,h这几个函数。通过c函数判断出sn的长度要大于8个字符,1983<int(sn[0:4])<2007,1<=int(sn[4:6])<=12,1<= int(sn[6:8])<=31 。我把这几个函数的运算逻辑转换到如下python代码:

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2018-12-10 11:36 被会飞的鱼油编辑 ,原因:
收藏
免费 1
支持
分享
赞赏记录
参与人
雪币
留言
时间
PLEBFE
为你点赞~
2023-2-1 00:56
最新回复 (0)
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

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