首页
社区
课程
招聘
[原创]2018看雪CTF第七题WP
发表于: 2018-6-29 19:23 6480

[原创]2018看雪CTF第七题WP

2018-6-29 19:23
6480

程序中的结构体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
00000000 maze            struc ; (sizeof=0x140, mappedto_54)
00000000                                         ; XREF: cm_main/r
00000000 floor           floor 20 dup(?)         ; XREF: cm_main:loc_12B123A/w
00000000                                         ; cm_main+206/o ...
00000140 maze            ends
00000140
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 floor           struc ; (sizeof=0x10, mappedto_55)
00000000                                         ; XREF: maze/r
00000000 key             db 16 dup(?)            ; XREF: cm_main:loc_12B123A/w
00000000                                         ; cm_main+206/o ... ; string(C)
00000010 floor           ends
00000010
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 combination     struc ; (sizeof=0x10, mappedto_53)
00000000                                         ; XREF: cm_main+33/w
00000000                                         ; cm_main/r
00000000 combination     db 16 dup(?)            ; XREF: cm_main+17/w
00000000                                         ; cm_main+21/w ... ; string(C)
00000010 combination     ends

在栈上初始化每每3个人的组合表

生成的组合表

flag编码

key变换

64x64x64 拉丁立方体

穷举代码

开始用python写的,实际测试发现速度太慢,就改用c了。
30秒就出结果了。

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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
typedef unsigned char u8;
int check(u8 *p);
 
u8 mission[20][16] = {0x14,0x22,0x1E,0x10,0x38,0x30,0x18,0x10,4,0x1A,0x24,8,2,0x26,0x38,0x2A};
u8 *expected = (u8*)mission;
 
u8 cube[64][64][64];
 
u8 M[16][3] = {
    {2,1,0},    //0
    {0,4,3},    //1
    {0,6,5},    //2
    {1,7,5},    //3
    {1,6,4},    //4
    {3,2,8},    //5
    {4,2,9},    //6
    {3,10,7},    //7
    {5,12,8},    //8
    {6,13,11},     //9
    {7,13,12},    //10
    {9,14,11},    //11
    {10,8,14},    //12
    {10,9,15},    //13
    {12,11,15},    //14
    {14,13,15}    //15
};
 
int main() {
    u8 candidate[16];
    u8 T[16][4096][3];
    u8 x,y,z;
    int c;
 
    FILE *f = fopen("Escape.exe","rb");
    fseek(f,0xe4f0,0);
    fread(cube,64*64*64,1,f);
    fclose(f);
 
    for(int floor=1;floor<20;floor++) {
 
        u8 t1[7] = {0,1,2,5,6,9,13};
        for(int k=0;k<7;k++) {
            c = 0;
            for(x=0;x<64;x++) {
                for(y=0;y<64;y++) {
                    for(z=0;z<64;z++) {
                        if(cube[z][y][x]==expected[t1[k]]) {
                            T[t1[k]][c][0] = x;
                            T[t1[k]][c][1] = y;
                            T[t1[k]][c][2] = z;
                            c++;
                        }
                    }
                }
            }
        }
 
        u8 t2[5] = {3,7,8,10,11};
        for(int k=0;k<5;k++) {
            c = 0;
            for(x=0;x<64;x++) {
                for(z=0;z<64;z++) {
                    for(y=0;y<64;y++) {
                        if(cube[z][y][x]==expected[t2[k]]) {
                            T[t2[k]][c][0] = x;
                            T[t2[k]][c][1] = y;
                            T[t2[k]][c][2] = z;
                            c++;
                        }
                    }
                }
            }
        }
 
        for(int i=0;i<4096;i++) {
            for(int j=0;j<64;j++) {
                for(int k=0;k<64;k++) {
                    candidate[0] = T[0][i][2];
                    candidate[1] = T[0][i][1];
                    candidate[2] = T[0][i][0];
                    candidate[3] = T[1][candidate[0]*64+j][2];
                    candidate[4] = T[1][candidate[0]*64+j][1];
                    candidate[5] = T[2][candidate[0]*64+k][2];
                    candidate[6] = T[2][candidate[0]*64+k][1];
                    candidate[7] = T[3][candidate[1]*64+candidate[5]][1];
                    candidate[8] = T[5][candidate[3]*64+candidate[2]][2];
                    candidate[9] = T[6][candidate[4]*64+candidate[2]][2];
                    candidate[10] = T[7][candidate[3]*64+candidate[7]][1];
                    candidate[12] = T[8][candidate[5]*64+candidate[8]][1];
                    candidate[13] = T[10][candidate[7]*64+candidate[12]][1];
                    candidate[11] = T[9][candidate[6]*64+candidate[13]][2];
                    candidate[14] = T[11][candidate[9]*64+candidate[11]][1];
                    candidate[15] = T[13][candidate[10]*64+candidate[9]][2];
 
                    if (check(candidate)) {
                        printf("floor:%d|  \t",20-floor);
                        for(int i=0;i<16;i++){
                            printf("%02X ",candidate[i]);
                        }
                        printf("\n");
                        memcpy(mission[floor],candidate,16);
                        expected += 16;
                    }
                }
            }
 
        }
    }
 
    char *sz = "abcdefghijklmnopqrstuvwxyz+-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    printf("flag:");
    for(int i=0;i<16;i++)
        printf("%c",sz[mission[19][i]]);
    printf("\n");
    system("pause");
    return 0;
}
 
int check(u8 *p) {
    u8 t[16];
    u8 x,y,z;
    for(int i=0;i<16;i++) {
        x = p[M[i][0]];
        y = p[M[i][1]];
        z = p[M[i][2]];
        t[i] = cube[z][y][x];
        if(t[i]!=expected[i])
            return 0;
    }
    return 1;
}

运行结果


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

最后于 2018-6-29 23:03 被mratlatsn编辑 ,原因:
收藏
免费
支持
分享
最新回复 (4)
雪    币: 279
活跃值: (196)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
请问下,这里的 t1 和 t2 数组是怎么来的?分别表示什么意思,这样爆破出来速度好快啊
2018-7-30 23:45
0
雪    币: 204
活跃值: (911)
能力值: (RANK:1324 )
在线值:
发帖
回帖
粉丝
3
pangpwn 请问下,这里的 t1 和 t2 数组是怎么来的?分别表示什么意思,这样爆破出来速度好快啊
x,y,z坐标遍历的顺序不一样,t1中的是x->y->z,t2中的是x->z->y。
这里利用了拉丁立方体的性质:每行每列每竖列都是1-64的组合。
即对于任意的e属于[1,64],满足cube(x,y,z)=e的坐标(x,y,z)都有4096个。T[4096]就保存了这个结果。
而确定了任意两个坐标(比如x,z),使得cube(x,y,z)=e的y值也是唯一的。这样x->z->y的遍历顺序就可以直接从T[4096]中提取这个唯一的结果T[64*x+z],而不用遍历4096次去一一比对了。
2018-7-31 19:00
0
雪    币: 1
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
gcc编译执行报错:
Segmentation fault (core dumped)
2018-9-9 11:03
0
雪    币: 279
活跃值: (196)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
jackandkx x,y,z坐标遍历的顺序不一样,t1中的是x->y->z,t2中的是x->z->y。 这里利用了拉丁立方体的性质:每行每列每竖列都是1-64的组合。 即对于任意的e属于[1 ...
刚看到回复。不好意思。
可以理解为有个函数 f(a,b,c,d) = 0,该函数知3求1。对吧?
再次谢谢回复与分享。
2019-7-13 21:24
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

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