zoukankan      html  css  js  c++  java
  • buu [MRCTF2020]EasyCpp

    上次没写出,这次认真分析了一下,发现自己的调试水平也有了上涨,也看了一些C++逆向的文章,尤其是stl,发现C++的oop还是挺复杂,这题还没考啥虚函数的还行了。
    一.拖入ida,找到主函数,还是挺容易的

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      double v3; // xmm0_8
      __int64 v4; // rax
      __int64 v5; // rcx
      __int64 v6; // r8
      __int64 v7; // r9
      __int64 v8; // rbx
      __int64 v9; // rax
      int v10; // ebx
      __int64 v11; // rax
      __int64 v12; // rax
      __int64 v13; // rax
      __int64 v14; // rax
      __int64 v15; // rax
      __int64 v16; // rax
      char v18; // [rsp+0h] [rbp-140h]
      __int64 v19; // [rsp+28h] [rbp-118h]
      __int64 v20; // [rsp+30h] [rbp-110h]
      int v21; // [rsp+3Ch] [rbp-104h]
      char v22; // [rsp+40h] [rbp-100h]
      char v23; // [rsp+60h] [rbp-E0h]
      char v24; // [rsp+90h] [rbp-B0h]
      char v25; // [rsp+AFh] [rbp-91h]
      char v26; // [rsp+B0h] [rbp-90h]
      char v27; // [rsp+DFh] [rbp-61h]
      char v28; // [rsp+E0h] [rbp-60h]
      int v29; // [rsp+104h] [rbp-3Ch]
      char *v30; // [rsp+108h] [rbp-38h]
      int *v31; // [rsp+110h] [rbp-30h]
      _DWORD *v32; // [rsp+118h] [rbp-28h]
      int *v33; // [rsp+120h] [rbp-20h]
      int i; // [rsp+128h] [rbp-18h]
      int v35; // [rsp+12Ch] [rbp-14h]
    
      v35 = 0;
      std::vector<int,std::allocator<int>>::vector(&v24, argv, envp);
      std::vector<bool,std::allocator<bool>>::vector(&v23);
      std::allocator<char>::allocator(&v25);
      std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v22, &unk_500E, &v25);
      std::allocator<char>::~allocator(&v25);
      v4 = std::operator<<<std::char_traits<char>>(&std::cout, "give me your key!");
      std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
      for ( i = 0; i <= 8; ++i )
      {
        std::istream::operator>>(&std::cin, &keys[i]);
        std::__cxx11::to_string((std::__cxx11 *)&v26, keys[i], (unsigned int)keys[i], v5, v6, v7);
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator+=(&v22, &v26);
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v26);// 输入9组字符
      }
      v32 = keys;
      v33 = keys;
      v31 = (int *)&unk_83E4;
      while ( v33 != v31 )
      {
        v21 = *v33;
        std::vector<int,std::allocator<int>>::push_back(&v24, &v21);
        ++v33;
      }                                             // 将输入的字符串存入vector中
      v8 = std::vector<int,std::allocator<int>>::end(&v24);
      v9 = std::vector<int,std::allocator<int>>::begin(&v24);
      std::for_each<__gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>>,main::{lambda(int &)#1}>(// 每组异或1
        v8,
        v9,
        v8);
      v30 = &v24;
      v20 = std::vector<int,std::allocator<int>>::begin(&v24);
      v19 = std::vector<int,std::allocator<int>>::end(v30);// 类似头指针和尾指针
      while ( (unsigned __int8)__gnu_cxx::operator!=<int *,std::vector<int,std::allocator<int>>>(&v20, &v19) )
      {
        v29 = *(_DWORD *)__gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>>::operator*(&v20);
        std::allocator<char>::allocator(&v27);
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v18, &unk_500E, &v27);// 定义string
        std::allocator<char>::~allocator(&v27);
        depart(v29, (__int64)&v18, v3);             // 一波骚操作
        {lambda(std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>> &)#1}::operator()(
          (__int64)&func,                           // 一波替换
          (__int64)&v18);
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v28, &v18);// string复制
        v10 = (unsigned __int64){lambda(std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>,int)#2}::operator()(
                                  (__int64)&check,  // 比较函数
                                  (__int64)&v28,
                                  v35) ^ 1;
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v28);
        if ( (_BYTE)v10 )
        {
          v11 = std::operator<<<std::char_traits<char>>(&std::cout, "Wrong password!");
          std::ostream::operator<<(v11, &std::endl<char,std::char_traits<char>>);
          system("pause");
          exit(0);
        }
        ++v35;
        std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v18);
        __gnu_cxx::__normal_iterator<int *,std::vector<int,std::allocator<int>>>::operator++(&v20);// 头指针加一
      }
      v12 = std::operator<<<std::char_traits<char>>(&std::cout, "right!");
      std::ostream::operator<<(v12, &std::endl<char,std::char_traits<char>>);
      v13 = std::operator<<<std::char_traits<char>>(&std::cout, "flag:MRCTF{md5(");
      v14 = std::operator<<<char,std::char_traits<char>,std::allocator<char>>(v13, &v22);
      v15 = std::operator<<<std::char_traits<char>>(v14, ")}");
      std::ostream::operator<<(v15, &std::endl<char,std::char_traits<char>>);
      v16 = std::operator<<<std::char_traits<char>>(
              &std::cout,
              "md5()->{32/upper case/put the string into the function and transform into md5 hash}");
      std::ostream::operator<<(v16, &std::endl<char,std::char_traits<char>>);
      system("pause");
      std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v22);
      std::vector<bool,std::allocator<bool>>::~vector(&v23);
      std::vector<int,std::allocator<int>>::~vector(&v24);
      return 0;
    }
    

    把我的分析都写在注释里了,发现这个程序大体的逻辑是,输入9个数字,每个数字异或1,之后,遍历每个数字,进过depart函数,再进行替换,flag里面包含是md5加密的输入的9个数字。这里比较坑的有几点:
    1.在这里插入图片描述
    当时一直没找到这个函数在哪。。原来点击那个Lambda就可以进入函数中了,lambda之前也百度了一下,之前一道加密题也碰到过,不过是python的语法,C++里面这个和python里面意思大体一致,相当于一个匿名函数,在主函数体里面定义,()里面是指的捕捉对象,具体,用的时候,再回忆。
    2.在这里插入图片描述
    depart函数,这个递归感觉会劝退很多人,这个函数意思就是将数字分解,最后将除数和最后一个数字拼接成字符串。

    二.根据我们的思路逆向写出一个脚本,最后的数字找个在线网站直接加密下就好了。

    strs=["=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"]
    def replacediy(str):
        str=str.replace("O","0")
        str=str.replace("l","1")
        str=str.replace("z","2")
        str=str.replace("E","3")
        str=str.replace("A","4")
        str=str.replace("s","5")
        str=str.replace("G","6")
        str=str.replace("T","7")
        str=str.replace("B","8")
        str=str.replace("q","9")
        str=str.replace("="," ")
        return str
    flag=""
    for i in strs:
        tmp=replacediy(i).split(" ")[1:]
        print tmp
        sum=1
        for j in range(len(tmp)):
            sum*=int(tmp[j],10)
        sum^=1
        flag+=str(sum)
    print flag
    
    
  • 相关阅读:
    CCPC 2020 长春站 部分简略题解
    atcoder arc106 D Powers
    循环节与拓展欧拉定理(广义欧拉降幂)
    最长公共上升子序列 题解
    namomo fish round1 A~C题解
    Codeforces Round #666 (Div. 2) A~E题解
    Educational Codeforces Round 93 Div2 A~E题解
    Codeforces Round #578 Div2 1200 A~E题解
    UVA11997 K Smallest Sums 题解
    LCA模板
  • 原文地址:https://www.cnblogs.com/YenKoc/p/12779874.html
Copyright © 2011-2022 走看看