首页
论坛
课程
招聘
[原创] KCTF2020 秋季赛 第三题 重返地球
2020-12-15 00:14 4744

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

2020-12-15 00:14
4744

程序比较长,翻着看看操作,感觉像是一个指令是链表的虚拟机。先建个结构体。

1
2
3
4
5
6
struct Node {
    int opcode;
    int arg0;
    int arg1;
    int arg2;
};

程序流程感觉大概是

1.设置数据节点(相当于设置内存)(set_val..)

2.设置寄存器的值(一些输入) (Regxxx = )

3.设置指令入口 (Code_entry = ...)

4.进入虚拟机 (flow_dispatcher)

5.把算出来的vm_output拿出来看一看,比一比

 

嗯,看看程序。

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
  sub_3E1080(aInputYourFlag);                   // 提示
  Input_Node = sub_3E11D0();                    // 输入
  Input_Node2 = Input_Node;                     // 当前节点
  Code_entry = strlen_func;                     // 一个关键的跳转变量
  flow_dispatcher();                            // 每次dispatcher一次就可以得到一个vm_output
  if ( sub_3E11A0(vm_output, 37) ) // 验证长度
  {
    // ... 省略非常长的设置节点的操作
 
    v1408 = set_one();
    v1409 = set_zero_arg0_arg1(17163, v1408);
    // .. 省略一堆节点设置
    Reg7 = set_zero_arg0_arg1_(v1445, v1407);  
    Reg8 = Input_Node;
    Code_entry = transform_input_func;
    flow_dispatcher_2();                        // 这个VM来对输入进行变换
 
    v1446 = set_one();                          // 这是最终要比较相等的值
    v1447 = set_zero_arg0_arg1(7821, v1446);
     // ... 省略一堆节点设置
    v1483 = set_zero_arg0_arg1(0x312A, v1482);
 
    if ( sub_3E12C0(vm_output, v1483) )         // 比较变换后的输出
      sub_3E1080(aFlagCorrect);
    else
      sub_3E1080(aFlagWrong);
  }
  else
  {
    sub_3E1080(aFlagWrong_0);
  }
  return 0;
}

前面strlen_func不分析了,后面的transform_input_func 分析一下,因为指令比较少,就直接边调试边看看。

 

发现先是几轮加法操作

output1 = inp[0] * 8868

output2 = inp[1] * 27507

.....

 

然后得到一个链表新的 [output1,output2...]

 

然后就是上演了操作 output = output1 % 29527 + output2 % 29527 + ....

 

所以看到这里,就知道是

 

flag 乘上 已知矩阵 = 一个已知的值,然后是取模意义下的。

 

拿神仙工具sage解一下,百度个脚本改改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# d0, d1, d2...是提取出来的数据,就不往wp上抄了。
 
res = [ 7821 , 8110 , 28701 , 2882 , 4374 , 11830 , 22009 , 376 , 7691 , 2176 , 662 , 13481 , 16812 , 7204 , 10762 , 6282 , 6660 , 2410 , 21411 , 28102 , 22854 , 5466 , 24919 , 22382 , 875 , 25566 , 8859 , 9908 , 11941 , 1555 , 22145 , 23914 , 4893 , 12668 , 13603 , 18694 , 0x312A]
 
 
 
d = [d0,  d1,  d2,  d3,  d4,  d5,  d6,  d7,  d8,  d9,  d10,  d11,  d12,  d13,  d14,  d15,  d16,  d17,  d18,  d19,  d20,  d21,  d22,  d23,  d24,  d25,  d26,  d27,  d28,  d29,  d30,  d31,  d32,  d33,  d34,  d35,  d36]
 
A = [k[::-1] for k in d]
 
# mod 29527
F=GF(29527)
# 构造矩阵
A=matrix(F, A)
# 构造向量
b=matrix(F, res).transpose()
# 解方程
x=A.solve_right(b)
 
flag = bytes(vector(x)).decode()
print(flag)
 
# KCTF{r4Ck3t_M4tr|X_W1tH_CP5_YqBHxjWX}
# https://sagecell.sagemath.org/

恭喜ID[飞翔的猫咪]获看雪安卓应用安全能力认证高级安全工程师!!

收藏
点赞0
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回