攻防世界-reverse-reverse-for-the-holy-grail-350

Posted pluie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了攻防世界-reverse-reverse-for-the-holy-grail-350相关的知识,希望对你有一定的参考价值。

拖到linux中调试
技术图片

IDA中查看主函数

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // ebx
  int v4; // ebx
  __int64 v5; // rbx
  void *v7; // [rsp+0h] [rbp-70h]
  __int64 v8; // [rsp+10h] [rbp-60h]
  void *v9; // [rsp+20h] [rbp-50h]
  __int64 v10; // [rsp+30h] [rbp-40h]
  void *v11; // [rsp+40h] [rbp-30h]
  __int64 v12; // [rsp+48h] [rbp-28h]
  char v13; // [rsp+50h] [rbp-20h]

  v11 = &v13;
  v12 = 0LL;
  v13 = 0;
  std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What... is your name?", 21LL);
  std::endl<char,std::char_traits<char>>(&std::cout);
  std::operator>><char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v11);
  std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What... is your quest?", 22LL);
  std::endl<char,std::char_traits<char>>(&std::cout);
  std::istream::ignore((std::istream *)&std::cin);
  std::getline<char,std::char_traits<char>,std::allocator<char>>(&std::cin, &v11);
  std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "What...  is the secret password?", 32LL);
  std::endl<char,std::char_traits<char>>(&std::cout);
  std::operator>><char,std::char_traits<char>,std::allocator<char>>(&std::cin, &userIn);
  v7 = &v8;
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::_M_construct<char *>(
    &v7,
    (_BYTE *)userIn,
    (_BYTE *)(qword_601AE8 + userIn));
  v3 = validChars(&v7);
  if ( v7 != &v8 )
    operator delete(v7);
  if ( v3 < 0 )
    goto LABEL_14;
  v9 = &v10;
  std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char>>::_M_construct<char *>(
    &v9,
    (_BYTE *)userIn,
    (_BYTE *)(qword_601AE8 + userIn));
  v4 = stringMod((__int64 *)&v9);            //关键函数
  if ( v9 != &v10 )
    operator delete(v9);
  if ( v4 < 0 )
  {
LABEL_14:
    std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "Auuuuuuuugh", 11LL);
    std::endl<char,std::char_traits<char>>(&std::cout);
  }
  else
  {
    std::__ostream_insert<char,std::char_traits<char>>(&std::cout, "Go on. Off you go. tuctf{", 25LL);
    v5 = std::__ostream_insert<char,std::char_traits<char>>(&std::cout, userIn, qword_601AE8);
    std::__ostream_insert<char,std::char_traits<char>>(v5, "}", 1LL);
    std::endl<char,std::char_traits<char>>(v5);
  }
  if ( v11 != &v13 )
    operator delete(v11);
  return 0;
}

stringMod函数:

__int64 __fastcall stringMod(__int64 *input_password_str)
{
  __int64 v1; // r9
  __int64 v2; // r10
  __int64 v3; // rcx
  signed int v4; // er8
  int *v5; // rdi
  int *v6; // rsi
  signed int v7; // ecx
  signed int v8; // er9
  int v9; // er10
  unsigned int v10; // eax
  int v11; // esi
  int v12; // esi
  int v14[24]; // [rsp+0h] [rbp-60h]

  memset(v14, 0, 0x48uLL);
  v1 = input_password_str[1];
  if ( v1 )
  {
    v2 = *input_password_str;
    v3 = 0LL;
    v4 = 0;
    do
    {
      v12 = *(char *)(v2 + v3);
      v14[v3] = v12;
      if ( 3 * ((unsigned int)v3 / 3) == (_DWORD)v3 && v12 != firstchar[(unsigned int)v3 / 3] )//       第 0,3,6,9,12,15个字符对应firstchar的六个字符
        v4 = -1;
      ++v3;
    }
    while ( v3 != v1 );
  }
  else
  {
    v4 = 0;
  }
  v5 = v14;
  v6 = v14;
  v7 = 666;
  do
  {
    *v6 = v7 ^ *(unsigned __int8 *)v6;          // 每个字符与v7异或
    v7 += v7 % 5;
    ++v6;
  }
  while ( &v14[18] != v6 );
  v8 = 1;
  v9 = 0;
  v10 = 1;
  v11 = 0;
  do
  {
    if ( v11 == 2 )
    {
      if ( *v5 != thirdchar[v9] )               // 异或后的字符串的第 2,5,8,11,14,17位对应thirdchar的六个数
        v4 = -1;
      if ( v10 % *v5 != masterArray[v9] )
        v4 = -1;
      ++v9;
      v10 = 1;
      v11 = 0;
    }
    else
    {                                                  //只有v11==2时才校验字符,所以
      v10 *= *v5;                               // v10 == 异或后的字符串的第 0+3*n 位 乘以第 1+3*n 位
      if ( ++v11 == 3 )
        v11 = 0;
    }
    ++v8;
    ++v5;
  }
  while ( v8 != 19 );                           // 循环 1~18
  return (unsigned int)(v7 * v4);
}

stringMod函数校验过程一共分为三部分,第一部分中需要值得注意的是:
v3是int型,除以一个数后小数部分会被去掉,所以3 * ((unsigned int)v3 / 3) == (_DWORD)v3成立的条件是v33的倍数,因此flag的第 3*n 个字符对应firstchar的六个字符

脚本

i = 666
num = []                                       # v7
flag = ‘A**i**n**E**o**a**‘           # flag第0+3*n位对应firstchar
Xorflag = []                                   # flag每位与v7异或的结果
thirdchar = [0x2ef, 0x2c4, 0x2dc, 0x2c7, 0x2de, 0x2fc]
masterarray = [0x1d7, 0xc, 0x244, 0x25e, 0x93, 0x6c]
for j in range(18):                         # 求v7
    num.append(i)
    i += (i % 5)
temp_num = 0
for i in range(2, len(flag)+1, 3):        # 求flag 第 1+3*n位
    temp = thirdchar[temp_num] ^ num[i]
    temp_num += 1
    flag = flag[:i] + chr(temp) + flag[i+1:]
temp_num = 0
for i in range(len(flag)):                 # flag每位与v7异或
    temp = ord(flag[i]) ^ num[i]
    Xorflag.append(temp)
for i in range(1, 19, 3):                    # 求flag第1+3*n位
    for j in range(32, 128):
        j ^= num[i]
        temp = j * Xorflag[i-1] % Xorflag[i+1]
        if temp == masterarray[temp_num]:
            flag = flag[:i] + chr(j ^ num[i]) + flag[i+1:]
            temp_num += 1
            break
print("tuctf{" + flag + ‘}‘)


以上是关于攻防世界-reverse-reverse-for-the-holy-grail-350的主要内容,如果未能解决你的问题,请参考以下文章

攻防世界(解密篇Crypto)---混合编码

手机版我的世界起床战争攻防模式房主怎么开创造?

攻防世界-evil

攻防世界 Reverse高手进阶区 2分题 easyre-153

攻防世界 bug

攻防世界 ics-07