首页
论坛
课程
招聘
[原创]KCTF2020秋季赛 第三题 重返地球
2020-11-22 01:32 664

[原创]KCTF2020秋季赛 第三题 重返地球

2020-11-22 01:32
664

直接把程序丢IDA里F5

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
//...省略大量的变量声明
  sub_401080(aInputYourFlag);
  dword_409518 = (int)input();
  dword_4094F4 = dword_409518;
  listip = (int (__cdecl *)(_DWORD))GetLinkListLen;
  ExecuteList();
//flag长度
  if ( CmpListLen(*(int *)LinkList, 37) )
  {
    v1448 = LinkListStart_0();
    v3 = LinkListStart();
    v4 = LinkListPushIntNode(25998, (int)v3);
    v5 = LinkListPushIntNode(25043, (int)v4);
    v6 = LinkListPushIntNode(13626, (int)v5);
    v7 = LinkListPushIntNode(24155, (int)v6);
    v8 = LinkListPushIntNode(6283, (int)v7);
//...省略掉
    v1440 = LinkListPushIntNode(22145, (int)v1439);
    v1441 = LinkListPushIntNode(23914, (int)v1440);
    v1442 = LinkListPushIntNode(4893, (int)v1441);
    v1443 = LinkListPushIntNode(12668, (int)v1442);
    v1444 = LinkListPushIntNode(13603, (int)v1443);
    v1445 = LinkListPushIntNode(18694, (int)v1444);
    v1446 = LinkListPushIntNode(12586, (int)v1445);
    if ( CmpLinkList(*(_DWORD **)LinkList, v1446) )
      sub_401080(aFlagCorrect);
    else
      sub_401080(aFlagWrong);
  }
  else
  {
    sub_401080(aFlagWrong_0);
  }
  return 0;
}

代码太长,这里就放一部分,从伪代码中能看出要求flag长度位37,而且每个链表也是37个成员,main函数一共初始化了38个链表,最后一个是结果。可以大胆猜想,这些链表应该能弄成方程组。
跟踪分析代码,最后定位到0x406BA0,程序这里解析并执行链表指令

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
_DWORD *LinkCodeParse()
{
  _DWORD *result; // eax
  FILE *v1; // eax
  int v2; // [esp+4h] [ebp-58h]
  int v3; // [esp+8h] [ebp-54h]
  int v4; // [esp+10h] [ebp-4Ch]
  int v5; // [esp+1Ch] [ebp-40h]
  int v6; // [esp+20h] [ebp-3Ch]
  int v7; // [esp+28h] [ebp-34h]
  int v8; // [esp+30h] [ebp-2Ch]
  _DWORD *v9; // [esp+34h] [ebp-28h]
  int v10; // [esp+38h] [ebp-24h]
  int v11; // [esp+40h] [ebp-1Ch]
 
  result = *(_DWORD **)LinkListCode;
  switch ( *(_DWORD *)LinkListCode )
  {
    case 0:                                     // 计算链表长度
      LinkListCode = *(_DWORD *)(LinkListCode + 4);
      result = (_DWORD *)++*(_DWORD *)LinkList;
      listip = (int (__cdecl *)(_DWORD))LinkCodeParse;
      break;
    case 1:
      v11 = *(_DWORD *)(LinkListCode + 8);
      constnum = *(_DWORD *)(LinkListCode + 4);
      result = *(_DWORD **)LinkList;
      dword_409500 = *(_DWORD *)LinkList;
      dword_4094DC = v11;
      listip = (int (__cdecl *)(_DWORD))add;
      break;
    case 2:
      result = *(_DWORD **)(LinkListCode + 4);
      LinkListCode = (int)result;
      --*(_DWORD *)LinkList;
      listip = (int (__cdecl *)(_DWORD))LinkCodeParse;
      break;
    case 3:
      v10 = *(_DWORD *)(LinkListCode + 4);      // 相减
      v9 = *(_DWORD **)(LinkListCode + 8);
      dword_409514 = *(_DWORD *)LinkList;
      *(_DWORD *)dword_40950C = v10;
      result = v9;
      dword_40951C = (int)v9;
      listip = (int (__cdecl *)(_DWORD))sub;
      break;
    case 4:                                     // 减去29527
      v8 = *(_DWORD *)(LinkListCode + 4);
      result = *(_DWORD **)LinkList;
      dword_409514 = *(_DWORD *)LinkList;
      *(_DWORD *)dword_40950C = 29527;
      dword_40951C = v8;
      listip = (int (__cdecl *)(_DWORD))sub;
      break;
    case 5:                                     // 相加
      v7 = *(_DWORD *)(LinkListCode + 8);
      constnum = *(_DWORD *)(LinkListCode + 4);
      dword_409500 = *(_DWORD *)LinkList;
      result = LinkListPushCode4(v7);
      dword_4094DC = (int)result;
      listip = (int (__cdecl *)(_DWORD))add;
      break;
    case 6:
      v6 = *(_DWORD *)(LinkListCode + 8);
      v5 = *(_DWORD *)(LinkListCode + 12);
      dword_40952C = *(_DWORD *)(LinkListCode + 4);
      *(_DWORD *)dword_409528 = v6;
      result = LinkListPushCode5(*(int *)LinkList, v5);
      *(_DWORD *)dword_409534 = result;
      listip = (int (__cdecl *)(_DWORD))sub_4068E0;
      break;
    case 7:
      if ( *(_DWORD *)LinkList )
      {
        v1 = _acrt_iob_func(2u);
        sub_401040(v1, aError_0);
        exit(1);
      }
      result = *(_DWORD **)(LinkListCode + 4);
      LinkListCode = (int)result;
      *(_DWORD *)LinkList = 0;
      listip = (int (__cdecl *)(_DWORD))LinkCodeParse;
      break;
    case 8:
      v4 = *(_DWORD *)(LinkListCode + 8);
      LinkListCode = *(_DWORD *)(LinkListCode + 4);
      result = LinkListPushIntNode(v4, *(int *)LinkList);
      *(_DWORD *)LinkList = result;
      listip = (int (__cdecl *)(_DWORD))LinkCodeParse;
      break;
    case 9:
      v3 = *(_DWORD *)(LinkListCode + 8);
      v2 = *(_DWORD *)(LinkListCode + 12);
      dword_4094E4 = *(_DWORD *)(LinkListCode + 4);
      *(_DWORD *)dword_409520 = v3;
      result = LinkListPushCode8(v2, *(int *)LinkList);
      dword_409530 = (int)result;
      listip = (int (__cdecl *)(_DWORD))sub_406840;
      break;
    case 0xA:                                   // 计算链表长度
      LinkListCode = *(_DWORD *)(LinkListCode + 4);
      result = (_DWORD *)++*(_DWORD *)LinkList;
      listip = (int (__cdecl *)(_DWORD))LinkCodeParse;
      break;
    case 0xB:                                   // exit
      longjmp(**(int ***)(LinkListCode + 4), 1);
    default:
      return result;
  }
  return result;
}

这里面只有加和减两种计算,动态调试后可以得知是在做如下计算

1
2
3
4
result = 0
for i in range(37):
    result += constv[r][i] * user_input[i]
result %= 29527

constv 是main函数初始化的37个链表,r则是表示第几个链表
直接抠出所有链表的值(注意是“先进后出”,把它当成堆栈也可以),输出方程组给wolfram解,不要忘记写模数,不然解不出来
图片描述
整理得到flag:KCTF{r4Ck3t_M4tr|X_W1tH_CP5_YqBHxjWX}
附上wolfram方程组


[看雪官方]走出瓶颈,《安卓高级研修班(网课)》月薪三万[秋季班],12月1日开班,仅剩2位名额!

最后于 2020-11-22 01:34 被梦游枪手编辑 ,原因:
上传的附件:
收藏
点赞0
打赏
分享
最新回复 (1)
雪    币: 5
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
wrong-123 活跃值 2020-11-22 18:44
2
0
tql,我一直再看高阶矩阵的模逆怎么搞。。。原来wolfram是可以解的,是因为我不是wolfram会员吗
游客
登录 | 注册 方可回帖
返回