首页
社区
课程
招聘
[原创]KCTF2021 签到题-拜师学艺分析
发表于: 2021-5-10 18:04 3119

[原创]KCTF2021 签到题-拜师学艺分析

2021-5-10 18:04
3119

头一次参加CTF,还好入门题目简单,试着写写吧。
控制台运行,任意输入后,直接try again!
图片描述
OD载入直接运行,搜索ASCII字符。定位到如下位置:
图片描述
发现0x401200出push了一个%s,猜测为接收输入函数,直接在返回处下断,断下后继续跟踪,在0x040125c步入。
图片描述
在这里发现一块内存与1异或,实际为解密对比flag处的代码,在0x040125c这个call直接F8可以看到下面的乱码变为可读代码。从这个call出来后继续向下走。
图片描述
这部分就是刚才解密的代码。这里主要两个比较,一是比较flag的长度是否为0xC。
004012BD |. 83BD D8FDFFFF>cmp [local.138],0xC
二是比较6个明文字符是否为0x66,0x6c,0x61,0x61,0x7b,0x7d ,其中0x7d是最后一个字符,也就是判断flag是否为flag{??????} 这种格式。
重新运行输入flag: flag{}12345}在下面的call步入。
图片描述
下面的代码就是比较中间6个字符的代码了
图片描述
大概逻辑就是每三个字符为一组,进行xor,and的操作最后得到一个索引,根据索引从dict中取到一个字符。
图片描述,最终形成一个16字节的字符串,直接在函数结尾F4,返回后发现有一串字符。
004013A8 |. C785 DCFDFFFF>mov [local.137],KCTF_Cra.00403160 ; mxhZ3trYW54dWV9

 

图片描述
继续向下走,这段字符会根据刚才函数生成的16字节字符作比较,相等则成功。
根据上面的分析,可以把符合条件的组合排列出来。
以可见字符为输入,0x20 ~ 0x7e 每三个为一组。大概80万中排列。
然后根据输出的结果,可知ZmxhZ3trYW54dWV9是由那些字符生成的。以4个字符为一组搜索结果:

 

Zmxh:fla
Z3tr:g{k
YW54:anx
dWV9:ue}

 

c代码如下:

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
插入代码
 
int _tmain(int argc, _TCHAR* argv[])
{
    char dict[] = { 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','0','1','2','3','4','5','6','7','8','9' ,'+','/' };
    cout.setf(ios::hex, ios::basefield);//设置十六进制显示数值
    cout.setf(ios::showbase | ios::uppercase);//设置0x头和大写
 
    DWORD aa = 0x00666C61;
    aa = aa >> 0x12;
    DWORD all = 0;
    for (int i = 0x20; i < 0x7e; i++)
    {
        for (int j = 0x20; j < 0x7e; j++)
        {
            for (int k = 0x20; k < 0x7e; k++)
            {
 
                cout << "三个字符是:" <<i<<j<<k<<endl;
 
 
                all = i;
                all = all << 8;
                all = all + j;
                all = all << 8;
                all = all + k;
 
            //    all = 0x00666c61;
                cout << "十六进制拼接后是:" << all << endl;
 
                DWORD p1 = all >> 0x12;
 
                DWORD p2 = all >> 0xc;
                p2 = p2 & 0x3f;
 
                DWORD p3 = all >> 0x6;
                p3 = p3 & 0x3f;
 
                DWORD p4= all & 0x3f;
 
                cout << "四个结果是:" << dict[p1] << dict[p2] << dict[p3] << dict[p4]<<endl;
 
                int cc = 0;
 
            }
        }
    }
}

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

最后于 2021-5-10 18:09 被褐眼男子编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//