admin管理员组

文章数量:1623579

又是C++,杀了我吧

拿去Linux环境运行一下,确定在程序一开始就让我们输入字符串,在“Checking”附近找关键函数。

$ ./crazy
sssssssssssssssssssssssss
-------------------------------------------
Quote from people's champ
-------------------------------------------
*My goal was never to be the loudest or the craziest. It was to be the most entertaining.
*Wrestling was like stand-up comedy for me.
*I like to use the hard times in the past to motivate me today.
-------------------------------------------
Checking....
Too short or too long

载入IDA定位函数

  v24 = __readfsqword(0x28u);
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v18, argv, envp);
  std::operator>><char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v18);//输入存到变量v18
  v3 = std::operator<<<std::char_traits<char>>(&std::cout, "-------------------------------------------");
  std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
  v4 = std::operator<<<std::char_traits<char>>(&std::cout, "Quote from people's champ");
  std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
  v5 = std::operator<<<std::char_traits<char>>(&std::cout, "-------------------------------------------");
  std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);
  v6 = std::operator<<<std::char_traits<char>>(
         &std::cout,
         "*My goal was never to be the loudest or the craziest. It was to be the most entertaining.");
  std::ostream::operator<<(v6, &std::endl<char,std::char_traits<char>>);
  v7 = std::operator<<<std::char_traits<char>>(&std::cout, "*Wrestling was like stand-up comedy for me.");
  std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);
  v8 = std::operator<<<std::char_traits<char>>(
         &std::cout,
         "*I like to use the hard times in the past to motivate me today.");
  std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>);
  v9 = std::operator<<<std::char_traits<char>>(&std::cout, "-------------------------------------------");
  std::ostream::operator<<(v9, &std::endl<char,std::char_traits<char>>);  
  HighTemplar::HighTemplar((DarkTemplar *)&v23, (__int64)&v18);//v18与v23有关
  v10 = std::operator<<<std::char_traits<char>>(&std::cout, "Checking....");
  std::ostream::operator<<(v10, &std::endl<char,std::char_traits<char>>);
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string(&v19, &v18);
  func1(&v20, &v19);
  func2(&v21, &v20);
  func3(&v21, 0LL);
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v21);
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v20);
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v19);
  HighTemplar::calculate((HighTemplar *)&v23);//可能是关键函数
  if ( (unsigned int)HighTemplar::getSerial((HighTemplar *)&v23) == 0 )//可能是关键函数
  {
    v11 = std::operator<<<std::char_traits<char>>(&std::cout, "/");
    std::ostream::operator<<(v11, &std::endl<char,std::char_traits<char>>);
    v12 = std::operator<<<std::char_traits<char>>(&std::cout, "Do not be angry. Happy Hacking :)");
    std::ostream::operator<<(v12, &std::endl<char,std::char_traits<char>>);
    v13 = std::operator<<<std::char_traits<char>>(&std::cout, "/");
    std::ostream::operator<<(v13, &std::endl<char,std::char_traits<char>>);
    ZN11HighTemplar7getFlagB5cxx11Ev(&v22, &v23);
    v14 = std::operator<<<std::char_traits<char>>(&std::cout, "flag{");
    v15 = std::operator<<<char,std::char_traits<char>,std::allocator<char>>(v14, &v22);
    v16 = std::operator<<<std::char_traits<char>>(v15, "}");
    std::ostream::operator<<(v16, &std::endl<char,std::char_traits<char>>);
    std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v22);
  }
  HighTemplar::~HighTemplar((HighTemplar *)&v23);
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::~basic_string(&v18);
  return 0;
}

进入HighTemplar::HighTemplar

unsigned __int64 __fastcall HighTemplar::HighTemplar(DarkTemplar *a1, __int64 a2)
{
  char v3; // [rsp+17h] [rbp-19h]
  unsigned __int64 v4; // [rsp+18h] [rbp-18h]

  v4 = __readfsqword(0x28u);
  DarkTemplar::DarkTemplar(a1);
  *(_QWORD *)a1 = &off_401EA0;
  *((_DWORD *)a1 + 3) = 0;
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string((__int64)a1 + 16, a2);//存储输入
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string((__int64)a1 + 48, a2);//存储输入
  std::allocator<char>::allocator(&v3, a2);
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::basic_string((char *)a1 + 80, "327a6c4304ad5938eaf0efb6cc3e53dc", &v3);//存储字符串
  std::allocator<char>::~allocator((__int64)&v3);
  return __readfsqword(0x28u) ^ v4;
}

进入HighTemplar::calculate

bool __fastcall HighTemplar::calculate(HighTemplar *this)
{
  __int64 v1; // rax
  _BYTE *v2; // rbx
  bool result; // al
  _BYTE *v4; // rbx
  int i; // [rsp+18h] [rbp-18h]
  int j; // [rsp+1Ch] [rbp-14h]

  if ( std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length((char *)this + 16) != 32 )//输入字符串长度要等于32
  {
    v1 = std::operator<<<std::char_traits<char>>(&std::cout, "Too short or too long");
    std::ostream::operator<<(v1, &std::endl<char,std::char_traits<char>>);
    exit(-1);
  }
  for ( i = 0; i <= (unsigned __int64)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length((char *)this + 16); ++i )
  {
    v2 = (_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16, i);
    *v2 = (*(_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16, i) ^ 0x50) + 23;//(flag[i]^0x50)+23
  }
  for ( j = 0; ; ++j )
  {
    result = j <= (unsigned __int64)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length((char *)this + 16);
    if ( !result )
      break;
    v4 = (_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16,j);
    *v4 = (*(_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16, j) ^ 0x13) + 11;//(flag[i])^0x13+11
  }
  return result;
}

进入HighTemplar::getSerial

__int64 __fastcall HighTemplar::getSerial(HighTemplar *this)
{
  __int64 v1; // rbx
  __int64 v2; // rax
  __int64 v3; // rax
  __int64 v4; // rax
  __int64 v5; // rax
  unsigned int i; // [rsp+1Ch] [rbp-14h]

  for ( i = 0; (signed int)i < (unsigned __int64)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::length((char *)this + 16); ++i )
  {
    v1 = *(unsigned __int8 *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 80, (signed int)i);
    if ( (_BYTE)v1 != *(_BYTE *)std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::operator[]((char *)this + 16, (signed int)i) )//字符串与输入对比
    {
      v4 = std::operator<<<std::char_traits<char>>(&std::cout, "You did not pass ");
      v5 = std::ostream::operator<<(v4, i);
      std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);
      *((_DWORD *)this + 3) = 1;
      return *((unsigned int *)this + 3);
    }
    v2 = std::operator<<<std::char_traits<char>>(&std::cout, "Pass ");
    v3 = std::ostream::operator<<(v2, i);
    std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
  }
  return *((unsigned int *)this + 3);
}

总结一下分析,输入的字符串长度要等于32,进行一些加密运算后与327a6c4304ad5938eaf0efb6cc3e53dc相等。

exp

char temp[33]="327a6c4304ad5938eaf0efb6cc3e53dc";
int flag[32];
int i;
for(i=0; i<32; i++)
{
    flag[i] = (temp[i]-11)^0x13;
    flag[i] = (flag[i]-23)^0x50;
    printf("%c",(char)flag[i]);
}
//tMx~qdstOs~crvtwb~aOba}qddtbrtcd

本文标签: gfsjrecrazy