【xctf-reverse】六六六

开始分析

用64位ida打开
shift f12
搜索字符串
看到
.rodata:000000000000203D 0000001A C flag{This_1s_f4cker_flag}
提交下发现不是flag

双击跳转到调用该数据的函数
f12反编译

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [sp+0h] [bp-1E0h]@1
  char v5; // [sp+F0h] [bp-F0h]@1

  memset(&s, 0, 0x1EuLL);
  printf("Please Input Key: ", 0LL);
  scanf("%s", &v5);
  encode(&v5, (__int64)&s);
  if ( strlen(&v5) == key )
  {
    if ( !strcmp(&s, enflag) )                  // izwhroz""w"v.K".Ni
      puts("You are Right");
    else
      puts("flag{This_1s_f4cker_flag}");
  }
  return 0;
}

程序逻辑如下

首先需要你输入一个字符串
程序通过encode函数对其加密并把结果地址交给s变量
当输入字符串长度等于key(值为18)时
进行s与enflag(值为izwhroz"“w"v.K”.Ni)的比较
结果正确则现实You are Right
故输入的字符串就是flag

encode 加密函数如下

int __fastcall encode(const char *a1, __int64 a2)
{
  int result; // eax@5
  char v3[32]; // [sp+10h] [bp-70h]@3
  char v4[32]; // [sp+30h] [bp-50h]@3
  char v5[40]; // [sp+50h] [bp-30h]@3
  int v6; // [sp+78h] [bp-8h]@1
  int i; // [sp+7Ch] [bp-4h]@1

  i = 0;
  v6 = 0;
  if ( strlen(a1) == key_18 )                   // key=lenth=18
  {
    for ( i = 0; i < key_18; i += 3 )           // 0 3 6 9 12 15 18
    {
      v5[i] = key_18 ^ (a1[i] + 6);
      v4[i + 1] = (a1[i + 1] - 6) ^ key_18;
      v3[i + 2] = a1[i + 2] ^ 6 ^ key_18;
      *(_BYTE *)(a2 + i) = v5[i];
      *(_BYTE *)(a2 + i + 1LL) = v4[i + 1];
      *(_BYTE *)(a2 + i + 2LL) = v3[i + 2];     // string a2= izwhroz""w"v.K".Ni
    }
    result = a2;
  }
  else
  {
    result = puts("Your Length is Wrong");
  }
  return result;
}

看到函数把字符串分为三个字符一组
分别进行异或运算加密
因为异或同一个数两次的值等于异或运算前的数
故而对encode函数逆向

代码如下

a2 = "izwhroz\"\"w\"v.K\".Ni"
s=""
for i in range(0,18,3):
    s+=chr((ord(a2[i])^18)-6)
    s+=chr((ord(a2[i+1])^18)+6)
    s+=chr(ord(a2[i+2])^18^6)

print(s)


上一篇:计算机网络简答题知识点


下一篇:leetcode189.轮转数组