[buuctf.reverse] 092_[MRCTF2020]EasyCpp

C++写的东西,太长了

第1部分读入9个数

  v3 = std::operator<<<std::char_traits<char>>(&std::cout, "give me your key!");
  std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
  for ( i = 0; i <= 8; ++i )
  {
    std::istream::operator>>(&std::cin, &keys[i]);// int[9]
    std::to_string((std::__cxx11 *)v22, keys[i]);
    std::string::operator+=(v18, v22);
    std::string::~string(v22);
  }

第2块作了个lamba操作

  v4 = std::vector<int>::end(v20);
  v5 = std::vector<int>::begin(v20);
  std::for_each<__gnu_cxx::__normal_iterator<int *,std::vector<int>>,main::{lambda(int &)#1}>(v5, v4);// 1

他调用了一个for_each的方法 

__int64 __fastcall std::for_each<__gnu_cxx::__normal_iterator<int *,std::vector<int>>,main::{lambda(int &)#1}>(
        __int64 a1,
        __int64 a2)
{
  unsigned int v2; // ebx
  __int64 v3; // rax
  char v5; // [rsp+Fh] [rbp-21h] BYREF
  __int64 v6; // [rsp+10h] [rbp-20h] BYREF
  __int64 v7[3]; // [rsp+18h] [rbp-18h] BYREF

  v7[0] = a1;
  v6 = a2;
  while ( (unsigned __int8)__gnu_cxx::operator!=<int *,std::vector<int>>(v7, &v6) )
  {
    v3 = __gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator*(v7);
    main::{lambda(int &)#1}::operator()(&v5, v3);
    __gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator++(v7);
  }
  return v2;
}

里边调用另外一个lamba,对输入数字进行第1次加密 异或1

_DWORD *__fastcall main::{lambda(int &)#1}::operator()(__int64 a1, _DWORD *a2)
{
  _DWORD *result; // rax

  result = a2;
  *a2 ^= 1u;
  return result;
}

第2部分是个循环,对每个数字调用depart和lambda func,lamdba check分别是分解因子,替换和比较

  while ( (unsigned __int8)__gnu_cxx::operator!=<int *,std::vector<int>>(&v16, &v15) )
  {
    v25 = *(_DWORD *)__gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator*(&v16);
    std::allocator<char>::allocator(&v23);
    std::string::basic_string(v14, &unk_500E, &v23);
    std::allocator<char>::~allocator(&v23);
    depart(v25, v14);                           // 求因子
    {lambda(std::string &)#1}::operator()(&func, v14);// OlzEAsGTBq=  => 0123456789空格                        
    std::string::basic_string(v24, v14);
    v6 = {lambda(std::string,int)#2}::operator()(&check, v24, v31) ^ 1;// 与ans比较
    std::string::~string(v24);
    if ( v6 )
    {
      v7 = std::operator<<<std::char_traits<char>>(&std::cout, "Wrong password!");
      std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);
      system("pause");
      exit(0);
    }
    ++v31;
    std::string::~string(v14);
    __gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator++(&v16);
  }

递归求因子

__int64 __fastcall depart(int a1, __int64 a2)
{
  char v3[32]; // [rsp+20h] [rbp-60h] BYREF
  char v4[40]; // [rsp+40h] [rbp-40h] BYREF
  int i; // [rsp+68h] [rbp-18h]
  int v6; // [rsp+6Ch] [rbp-14h]

  v6 = a1;
  for ( i = 2; std::sqrt<int>((unsigned int)a1) >= (double)i; ++i )
  {
    if ( !(a1 % i) )
    {
      v6 = i;
      depart((unsigned int)(a1 / i), a2);
      break;
    }
  }
  std::to_string((std::__cxx11 *)v4, v6);       // 最小素因子
  std::operator+<char>(v3, &asc_500C, v4);      // 空格+str(p)
  std::string::operator+=(a2, v3);
  std::string::~string(v3);
  return std::string::~string(v4);
}

替换

__int64 __fastcall {lambda(std::string &)#1}::operator()(__int64 a1, __int64 a2)
{
......

  v25 = 79;                                     // OlzEAsGTBq=
                                                // 0123456789空格
  v26 = 48;
  v2 = std::string::end(a2);
  v3 = std::string::begin(a2);
  std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v3, v2, &v26, &v25);
......
}

比对

_BOOL8 __fastcall {lambda(std::string,int)#2}::operator()(__int64 a1, __int64 a2, int a3)
{
  const char *v3; // rbx
  const char *v4; // rax

  v3 = (const char *)std::string::c_str((char *)&ans[abi:cxx11] + 32 * a3);
  v4 = (const char *)std::string::c_str(a2);
  return strcmp(v4, v3) == 0;
}

逆向查引用找ans的来源

int __fastcall __static_initialization_and_destruction_0(int a1, int a2)
{
......

  if ( a1 == 1 && a2 == 0xFFFF )
  {
    std::ios_base::Init::Init((std::ios_base::Init *)&std::__ioinit);
    __cxa_atexit((void (__fastcall *)(void *))&std::ios_base::Init::~Init, &std::__ioinit, &_dso_handle);
    std::allocator<char>::allocator(&v3);
    std::string::basic_string(&ans[abi:cxx11], "=zqE=z=z=z", &v3);
    std::allocator<char>::~allocator(&v3);
    std::allocator<char>::allocator(&v4);
    std::string::basic_string((char *)&ans[abi:cxx11] + 32, "=lzzE", &v4);
    std::allocator<char>::~allocator(&v4);
......
    return __cxa_atexit(_tcf_0, 0LL, &_dso_handle);
  }
  return result;
}

最后提示flag的组成

  v9 = std::operator<<<std::char_traits<char>>(&std::cout, "flag:MRCTF{md5(");
  v10 = std::operator<<<char>(v9, v18);
  v11 = std::operator<<<std::char_traits<char>>(v10, ")}");
  std::ostream::operator<<(v11, &std::endl<char,std::char_traits<char>>);
  v12 = std::operator<<<std::char_traits<char>>(
          &std::cout,
          "md5()->{32/upper case/put the string into the function and transform into md5 hash}");

逆向程序

ans = ["=zqE=z=z=z", "=lzzE", "=ll=T=s=s=E", "=zATT", "=s=s=s=E=E=E", "=EOll=E", "=lE=T=E=E=E", "=EsE=s=z", "=AT=lE=ll"]
str1 = 'OlzEAsGTBq='
str2 = '0123456789*'

fstr = ''
for s in ans:
    t = '1'+''.join([str2[str1.index(c)] for c in s ])
    fstr += str(eval(t) ^ 1)
    print(eval(t))

from hashlib import md5 
#from string import toupper 
print(md5(fstr.encode()).hexdigest().upper())    
#4367FB5F42C6E46B2AF79BF409FB84D3
#flag{4367FB5F42C6E46B2AF79BF409FB84D3}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值