首页
社区
课程
招聘
[原创]记一次小白的逆(bei)向(du)之(da)旅---看雪CTF2019流浪者
发表于: 2021-2-8 23:18 7219

[原创]记一次小白的逆(bei)向(du)之(da)旅---看雪CTF2019流浪者

2021-2-8 23:18
7219

第一次发帖,写得不好的地方希望大家见谅,谢谢!
这道题在攻防世界Reverse刷到,下载下来还是挺惊喜的,看到exe还是挺亲切的,像多年不见的老朋友,哈哈哈。废话不多说,入正题。

第一步:

当然是先查壳了
丢到PEiD看看,无壳,还是VC6写的,意味着汇编代码很好看,简洁。

第二步:

双击打开看看程序运行效果,随便输入字符串,点确定,弹对话框了,提示错误(嘴角一丝笑意)

第三步:

直接拉进OD,搜中文字符串,看到“恭喜”,然后点过去看看,往上找到个判断的关键跳转,然后看到了strcmp(笑容逐渐疯狂)

第四步:

在判断跳转处下断点,然后随便输字符串,运行,看到对比的字符串:“KanXueCTF2019JustForhappy”。心想:这也算逆向题吗?这么简单不是秒破?

然而真的这么简单么?图样图森破。。。
仔细看了一下对比的字符串,我明明输入的是“aaaaa”,怎么变成“BBBBBca”了?意识到可能对输入做了处理,但是应该不难。

第五步:

拉到IDA里面进行分析。
主函数:

 

可以看出程序的基本逻辑:
1.接收字符串
2.如果某字节大于或小于一些值,对这个字符做一些减法操作
3.最后把这个处理过的字符串,扔到strcmp函数里去对比,也就是说最后处理出来的字符串要等于“KanXueCTF2019JustForhappy”。

 

程序本身给出了一个源字符串,这一步会在这个字符串里去找一些字符拼出来,那么下标就是上一个函数扔进来的东西。
字符串对比函数:

IDA这里解析得不太合适,看得我一脸懵逼,还是得去看反汇编(谁说搞逆向的眼里只有F5的。。。),看反汇编知道这就是个指针操作,不需要去关心它加了多少,只要求出下标就可以了。

 

贴上找下标的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int index;
char result[] = "KanXueCTF2019JustForhappy";
char raw_string[] = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ";
for (int i = 0; i < strlen(result); i++)
    {
        index = 0;
        for (int x = 0; x < strlen(raw_string); x++)
        {
            if (result[i]==raw_string[x])
            {
                printf("%d ", index);
            }
            else
            {
                index++;
                continue;
            }
        }
    }

得出下标为:

1
char index_arr[] = { 19 ,0, 27, 59, 44 ,4, 11, 55, 14, 30, 28, 29, 37, 18, 44, 42, 43, 14, 38, 41, 7, 0, 39, 39 ,48 };

这个函数就算是处理完了,然后再返回上一层函数(逆向么。。就得倒着看。。)

有嵌套的 if 判断,先看最外层的else假设他不成立之后的结果,看到条件:

1
2
3
4
5
6
7
8
if ( input_raw[i] > 57 || input_raw[i] < 48 )//0<=input<=9
    {
        ........
    }  
    else
    {
      input[i] = input_raw[i] - 48;
    }

当我们输入的字符串的第 i 位 大于 57 或者小于 48 的时候进入下一个判断条件,对应的ASCII码就是数字 0-9 之外的字符,那要跳到else的话,就得是 0-9 ,也就是48<=input<=57 ,else做了一个减48的操作,也就是我们之前求出的下标是减了48的结果,那再把判断条件减去48,就可以判断下标是否满足这个判断了,也就是0<=input<=9。

 

然后看下一个判断条件,同理上面的,这次减去87,得出判断条件:10<=input<=35

1
2
3
4
5
6
7
8
if ( input_raw[i] > 122 || input_raw[i] < 97 )//10<=input<=35
      {
       ......
      }
      else
      {
        input[i] = input_raw[i] - 87;
      }

最后一个判断条件减去29,为:36<=input<=61

1
2
3
4
if ( input_raw[i] > 90 || input_raw[i] < 65 )//36<=input<=61
          wrong();
        else
          input[i] = input_raw[i] - 29;

跳转到错误函数的那个判断就不用看了。。。

 

然后基本的思路就出来了:用我们之前得出的下标的那个数组,依次去判断这三个条件,如果成立的话就加上对应的数。

完整代码:

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
#include<stdio.h>
#include<Windows.h>
 
void main()
{
    int index;
    char result[] = "KanXueCTF2019JustForhappy";
    char raw_string[] = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ";
    //这里求出下标的函数拿到结果就注释掉了
    /*for (int i = 0; i < strlen(result); i++)
    {
        index = 0;
        for (int x = 0; x < strlen(raw_string); x++)
        {
            if (result[i]==raw_string[x])
            {
                printf("%d ", index);
            }
            else
            {
                index++;
                continue;
            }
        }
    }*/
    char index_arr[] = { 19 ,0, 27, 59, 44 ,4, 11, 55, 14, 30, 28, 29, 37, 18, 44, 42, 43, 14, 38, 41, 7, 0, 39, 39 ,48 };
    for (int y = 0; y < sizeof(index_arr); y++)
    {
        if (index_arr[y]>=0 && index_arr[y]<=9)
        {
            index_arr[y] += 48;
            printf("%c",index_arr[y]);
        }
        else if(index_arr[y]>=10 && index_arr[y]<=35)
        {
            index_arr[y] += 87;
            printf("%c", index_arr[y]);
        }
        else if (index_arr[y]>=36 && index_arr[y]<=61)
        {
            index_arr[y] += 29;
            printf("%c", index_arr[y]);
        }
        else
        {
            puts("Bug!");
        }
    }
}

结果跑出来这么个东西:

也不知道对不对,扔到exe先看看,提示“恭喜”,大功告成,那么flag就是这个了: j0rXI4bTeustBiIGHeCF70DDM(记得加上flag{})

最后:小白刚刚踏入CTF,第一次在看雪论坛发帖,如果有什么写得不好的地方希望大家指出,感谢!


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

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 3113
活跃值: (3669)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
先学习,我也刚开始接触不久
2021-2-9 00:02
0
雪    币: 1067
活跃值: (627)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
嗯哼,加油
2021-2-9 02:57
0
游客
登录 | 注册 方可回帖
返回
//