• 【无标题】



    title: [ACTF新生赛2020]fungame
    categories: CTF题解——reverse


    [ACTF新生赛2020]fungame

    • 这个题虽然不难,但出题思路清奇,写个题解

    • 查壳,32位无壳,进IDA

    • F5main函数

      int __cdecl main(int argc, const char **argv, const char **envp)
      {
        void *v4; // [esp+1Ch] [ebp-4h]
      
        __main();
        v4 = malloc(0x14u);
        memset(v4, 0, 0x14u);
        memset(x, 0, 0x18u);
        sub_401340(v4);
        sub_4013BA((char *)v4);
        return 0;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    • 挨个看,第一个函数,有意思,简单异或,提取y2,y1,解密一下

      int __cdecl sub_401340(int flag)
      {
        char i; // [esp+1Fh] [ebp-9h]
      
        printf("Please input:");
        scanf("%s", flag);           //输入第一段flag
        for ( i = 0; i <= 15; ++i )
        {
          //异或加密
          if ( (*(_BYTE *)(i + flag) ^ *((_BYTE *)y1 + i)) != y2[i] )
            exit(0);
        }
        return 0;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14

      提取y1,y2解密flag:

      # Re_1s_So0_funny!
      
      • 1

      提交了,假flag,再探,下一位函数

    • 这个就有意思了,16位flag存进了12位的数组,搞溢出哇

      int __cdecl sub_4013BA(char *flag)
      {
        //12位,溢出
        char Destination[12]; // [esp+1Ch] [ebp-Ch] BYREF
      
        strcpy(Destination, flag);	//传给des,溢出部分作为参数传递
        strcpy(x, flag);				//又复制一份给x,有问题
        return 0;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 交叉引用查x

      void __noreturn sub_40233D()
      {
        char Str2[13]; 
        char Str1[16]; 
        char Str[12]; 
        size_t v3; 
      
        printf("Please input again:");
        strcpy(Str2, "YTFzMF9wV24=");	  //base64加密结果
        memset(Str, 0, sizeof(Str));
        memset(Str1, 0, sizeof(Str1));
        scanf("%s", Str);				   //第二段输入
        v3 = strlen(Str);
        sub_402421(Str, v3, Str1);	   //base64
        if ( !strcmp(Str1, Str2) )
        {
          printf("%s%s", x, Str);
          exit(0);
        }
        exit(0);
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
    • sub_40233D就是对新的输入进行一个base64加密

    • 但是这个函数是怎么被执行的,答案就是上面的溢出,通过溢出调用了这个函数40233D

    • 所以真正的flag就是:

      x + 溢出(注意大小端序问题) + str

    • 解密脚本

      #异或解密
      list=[0x23,0x61,0x3e,0x69,0x54,0x41,0x18,0x4d,0x6e,0x3b,0x65,0x53,0x30,0x79,0x45,0x5b]
      list1=[0x71,0x4,0x61,0x58,0x27,0x1e,0x4b,0x22,0x5e,0x64,0x3,0x26,0x5e,0x17,0x3c,0x7a]
      for i in range(0,len(list)):
          list[i] = chr(list[i]^list1[i])
      list = list[:12]
      #溢出
      yichu = [0x3d,0x23,0x40]
      for i in yichu:
          list.append(chr(i))
      list = ''.join(list)
      #base64
      s="YTFzMF9wV24="
      import base64
      s = str(base64.b64decode(s),encoding='utf-8')
      print('flag{' + list + s + '}')
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 个人博客:woodenmandu.cn

  • 相关阅读:
    rstudio server 服务器卡死了怎么办
    关于windows下ffmpeg视频(libx264,h264_qsv,h264_cuvid,h264_amf)编码参数纪要
    linux系统下,mysql增加用户
    ES6 | Symbol以及迭代器
    【OpenCV】Chapter2.图像的数值运算
    量化交易:公司基本面的量化
    面向对象编程原则(02)——单一职责原则
    适合短期内想快速上手数字孪生系统的人使用的数字孪生软件推荐
    实现MySQL主从同步
    第三方软件测试报告原来有这么多用途?还不知道的你out了!
  • 原文地址:https://blog.csdn.net/qq_59700927/article/details/127814138