首页
社区
课程
招聘
KCTF 迷失丛林
2021-11-19 12:57 17508

KCTF 迷失丛林

2021-11-19 12:57
17508

第零一重校验

flag长度为32且必须为0-9A-F,调用sub_401580进行校验
图片描述

第一重校验

第一重校验,不知道啥算法。需要对统计数据0x00 0x0e 0x28 0x4f偏移处进行统计。猜测256的矩阵的前8字节为缺少的0x1e 0x28 0x4b 0x6d 0x8c 0xa3 0xd2 0xfb。可以对这8个字节进行排列组合大概4w种可能性。
爆破得到前16个4B 6D 28 8C FB D2 1E A3
图片描述

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
#include<stdio.h>
#define NUM 8
unsigned char matrix[256]={
0x8C,0xFB,0x4B,0x1E,0x28,0xA3,0xD2,0x6D,0xA2,0x9B,0xF4,0xDF,0xAC,0x7C,0xA1,0xC6,
0x16,0xD0,0x0F,0xDD,0xDC,0x73,0xC5,0x6B,0xD1,0x96,0x47,0xC2,0x26,0x67,0x4E,0x41,
0x82,0x20,0x56,0x9A,0x6E,0x33,0x92,0x88,0x29,0xB5,0xB4,0x71,0xA9,0xCE,0xC3,0x34,
0x50,0x59,0xBF,0x2D,0x57,0x22,0xA6,0x30,0x04,0xB2,0xCD,0x36,0xD5,0x68,0x4D,0x5B,
0x45,0x9E,0x85,0xCF,0x9D,0xCC,0x61,0x78,0x32,0x76,0x31,0xE3,0x80,0xAD,0x39,0x4F,
0xFA,0x72,0x83,0x4C,0x86,0x60,0xB7,0xD7,0x63,0x0C,0x44,0x35,0xB3,0x7B,0x19,0xD4,
0x69,0x08,0x0B,0x1F,0x3D,0x11,0x79,0xD3,0xEE,0x93,0x42,0xDE,0x23,0x3B,0x5D,0x8D,
0xA5,0x77,0x5F,0x58,0xDB,0x97,0xF6,0x7A,0x18,0x52,0x15,0x74,0x25,0x62,0x2C,0x05,
0xE8,0x0D,0x98,0x2A,0x43,0xE2,0xEF,0x48,0x87,0x49,0x1C,0xCA,0x2B,0xA7,0x8A,0x09,
0x81,0xE7,0x53,0xAA,0xFF,0x6F,0x8E,0x91,0xF1,0xF0,0xA4,0x46,0x3A,0x7D,0x54,0xEB,
0x2F,0xC1,0xC0,0x0E,0xBD,0xE1,0x6C,0x64,0xBE,0xE4,0x02,0x3C,0x5A,0xA8,0x9F,0x37,
0xAF,0xA0,0x13,0xED,0x1B,0xEC,0x8B,0x3E,0x7E,0x27,0x99,0x75,0xAB,0xFE,0xD9,0x3F,
0xF3,0xEA,0x70,0xF7,0x95,0xBA,0x1D,0x40,0xB0,0xF9,0xE5,0xF8,0x06,0xBC,0xB6,0x03,
0xC9,0x10,0x9C,0x2E,0x89,0x5C,0x7F,0xB1,0x1A,0xD6,0x90,0xAE,0xDA,0xE6,0x5E,0xB9,
0x84,0xE9,0x55,0xBB,0xC7,0x0A,0xE0,0x66,0xF2,0xD8,0xCB,0x00,0x12,0xB8,0x17,0x94,
0x6A,0x4A,0x01,0x24,0x14,0x51,0x07,0x65,0x21,0xC8,0x38,0xFD,0x8F,0xC4,0xF5,0xFC
};
unsigned char key[8] = {0x1E,0x28,0x4B,0x6D,0x8C,0xA3,0xD2,0xFB};
 
void check()
{
    int c1=0,c2=0,c3=0,c4=0;
    for(int i=0;i<8;i++)
    {
        matrix[i]=key[i];
    }
    for(int i=0;i<256;i++)
    {
        unsigned char table[512]={0};
        int count[256]={0};
        table[0]=matrix[i];
        table[1]=(unsigned char)i+1;
        for(int j=0;j<0xfe;j++)
        {
            table[j*2+2]=matrix[table[j]];
            table[j*2+3]=table[j]+1;
        }
 
        for(int j=0;j<256;j++)
        {
            count[table[j+0xfe]] += 1;
        }
        if(count[0]!=0)
            c1++;
        if(count[0x0e]!=0)
            c2++;
        if(count[0x28]!=0)
            c3++;
        if(count[0x4f]!=0)
            c4++;
    }
    if(c1==0xA9&&c2==0xAC&&c3==0xA7&&c4>0xc8)
    {
        for(int i=0;i<8;i++)
        {
            printf("%.2X ",key[i]);
        }
        printf("\n");
    }
}
void do_range(int low, int high)
{
    if(low == high)
    {
        check();
    }
    else
    {
        do_range(low+1, high);
 
        for(int i=low+1; i<=high; i++)
        {
            //递归前交换
            int t = key[low]; key[low] = key[i]; key[i] = t;
            do_range(low+1, high);
            //递归后复位
            t = key[low]; key[low] = key[i]; key[i] = t;
        }
    }
}
 
 
int main()
{  
    do_range(0, NUM-1);
}

第二重校验

矩阵交换,提取运行后的矩阵用于最后计算。
图片描述
按字节进行加密,所以只需要按位爆破得到"GoodJob~"即可
图片描述

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
#include<stdio.h>
unsigned char table[256] = {
0xC1,0x9B,0x7F,0x58,0x64,0xD5,0x77,0x21,0x74,0xEB,0x14,0xBF,0xDF,0x25,0x5A,0x37,
0x85,0x2C,0xAF,0x8C,0xDA,0x26,0xE2,0x7A,0x87,0x4C,0x60,0x99,0x54,0x3C,0x95,0xC0,
0xB9,0x0C,0xBC,0x0E,0xE7,0x2D,0x86,0xBE,0x67,0xD3,0xD8,0xFC,0x30,0xB6,0xC8,0x57,
0x1E,0x62,0x3E,0xCE,0xA0,0xCD,0xF5,0xEE,0xA7,0xCF,0x45,0xFE,0xD0,0x80,0x05,0xAD,
0x13,0xF3,0xB7,0x6B,0x22,0x2B,0xBD,0x69,0x42,0x4B,0xA5,0xEA,0xA6,0xD2,0x6F,0x4F,
0x4E,0x07,0xE1,0x36,0x01,0xB5,0xAA,0xB1,0x94,0x0B,0x35,0x3A,0xC7,0x49,0x53,0x82,
0xC3,0x7B,0x32,0xFF,0x19,0xC4,0xF1,0xC9,0xE8,0xF7,0x56,0x15,0xA3,0x46,0x89,0x43,
0x9D,0x8F,0x20,0xEF,0xBB,0x2A,0xCB,0x09,0x93,0x4A,0x1C,0xE3,0x33,0xD1,0xE0,0x1D,
0x72,0x7C,0x27,0xE9,0x17,0x28,0x6D,0x6A,0xD9,0x00,0x9A,0xE5,0x63,0xDE,0x23,0x9F,
0x0D,0x47,0x3B,0x65,0x08,0x84,0x6C,0x1A,0x88,0x12,0xA1,0xA4,0xB3,0x18,0x24,0x1B,
0xD7,0x44,0xDB,0xAC,0x6E,0x7D,0x51,0x5E,0xED,0x50,0xD6,0x11,0x5B,0x9C,0xB4,0x68,
0x3D,0x2F,0x03,0x40,0xBA,0x2E,0xCA,0x02,0xE6,0xA8,0xEC,0x83,0x06,0x5D,0xB8,0x4D,
0x97,0x66,0xF0,0xFB,0x8A,0x55,0xAB,0xB2,0x04,0xFA,0x0A,0x31,0x71,0xCC,0x8B,0x73,
0xA9,0x48,0x5C,0xF9,0x98,0xE4,0xC6,0x34,0xC5,0x7E,0x81,0x75,0x90,0x1F,0x92,0x3F,
0x9E,0x10,0x29,0x52,0x39,0xF4,0x41,0x78,0x5F,0x16,0x79,0xC2,0xB0,0xDD,0xF2,0x61,
0x0F,0x70,0xD4,0x91,0xDC,0xF6,0xF8,0xFD,0x59,0x38,0x8D,0x96,0xAE,0x8E,0x76,0xA2
};
 
int main()
{  
    unsigned char v19;
    for(int k=0;k<256;k++)
    {
        unsigned char dword_414420[8] = {0xC1,0x9B ,0x7F ,0x58 ,0x64 ,0xD5 ,0x77 ,0x21};
        unsigned char tmp=k;
        int v17=0;
        do
        {
            for(int i=0;i<8;i++)
            {
                if(v17>=8)
                {
                    if(!i || i==7)
                        --dword_414420[i];
                }
                else
                {
                    if((tmp&1) !=0)
                        v19=dword_414420[i]+1;
                    else
                        v19=table[dword_414420[i]];
                    dword_414420[i]=v19;
 
                }
            }
            tmp>>=1;
            v17++;
        }while(v17<9);
        if(dword_414420[0]=='G')
            printf("[0]:%X\n",k);
        if(dword_414420[1]=='o')
            printf("[1]:%X\n",k);
        if(dword_414420[2]=='o')
            printf("[2]:%X\n",k);
        if(dword_414420[3]=='d')
            printf("[3]:%X\n",k);
        if(dword_414420[4]=='J')
            printf("[4]:%X\n",k);
        if(dword_414420[5]=='o')
            printf("[5]:%X\n",k);
        if(dword_414420[6]=='b')
            printf("[6]:%X\n",k);
        if(dword_414420[7]=='~')
            printf("[7]:%X\n",k);
    }
 
}

得到最后的验证:B4D682C8BF2DE13AD9B6AEF24A80CB22

总结

还原代码来分析太累了,也许用unicorn运行提取的字节码可能会更方便


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

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