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

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

2018-6-29 19:23
6317

程序中的结构体

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秒就出结果了。

#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;
}

运行结果


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2018-6-29 23:03 被mratlatsn编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 279
活跃值: (181)
能力值: ( 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
活跃值: (181)
能力值: ( 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
游客
登录 | 注册 方可回帖
返回
//