[ACTF新生赛2020]fungame


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;
    }
    
  • 挨个看,第一个函数,有意思,简单异或,提取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;
    }
    

    提取y1,y2解密flag:

    # Re_1s_So0_funny!
    

    提交了,假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;
    }
    
  • 交叉引用查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);
    }
    
  • 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 + '}')
    
  • 个人博客:woodenmandu.cn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UmVfX1BvaW50

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值