逆向加密 | ISCTF2024 | Reverse Ezre
2024/12/10约 410 字大约 1 分钟
把文件拖进 IDA 分析可得以下内容:

程序运行时,会让你输入 flag,并将你输入的文本传给一个加密算法,如果验证和已加密文本v5吻合,则提示Yeah,You get what you want!!!
我们可以观察到,验证结果在v2上,如果v2为True,则通过验证。
if ( v2 )
      v1 = "Yeah,You get what you want!!!";
我们继续查看v2
v2 = sub_140011217(v6, (unsigned int)v0, v5);
追踪该函数可得:
__int64 __fastcall sub_140011860(__int64 a1, int a2, _BYTE *a3)
{
  __int64 v4; // rbx
  _BYTE *v6; // rax
  __int64 v7; // rdi
  v4 = a2;
  sub_1400112C1(&unk_14001E00F);
  if ( (int)v4 <= 0 )
    return 1LL;
  v6 = a3;
  v7 = a1 - (_QWORD)a3;
  while ( v6[v7] == *v6 )
  {
    if ( ++v6 - a3 >= v4 )
      return 1LL;
  }
  return 0LL;
}
这是一个比较函数,用于比对字符串是否符合要求。将v6和v5进行比对。
我们继续向上分析,v6为我们输入的文本,
sub_140011073("%s", (const char *)v6);
然后会传入
sub_1400112E9(v6, (unsigned int)v0, v4);
推测这个就是加密函数,v4就是密钥:
strcpy(v4, "ISCTF");
追踪sub_1400112E9函数可得:
__int64 __fastcall sub_1400117A0(_BYTE *a1, int a2, __int64 a3)
{
  __int64 result; // rax
  int i; // r9d
  int v8; // r8d
  result = sub_1400112C1((__int64)&unk_14001E00F);
  for ( i = 0; i < a2; ++a1 )
  {
    v8 = (char)*a1;
    result = (unsigned int)(v8 - 65);
    if ( (unsigned __int8)(*a1 - 65) <= 0x19u )
    {
      v8 += *(char *)(i % 5u + a3);
      result = (unsigned int)(26 * (v8 / 26));
      LOBYTE(v8) = v8 % 26 + 65;
    }
    *a1 = v8;
    ++i;
  }
  return result;
}
将加密模块用 Python 复现:
def generate_payload(target_text, key):
    payload = ""
    key_length = len(key)
    for i, char in enumerate(target_text):
        if 'A' <= char <= 'Z':
            shift = ord(key[i % key_length])
            original_char = (ord(char) - 65 - shift + 65) % 26 + 65
            payload += chr(original_char)
        else:
            payload += char
    return payload
target_text = "QKEMK{7JB5_i5_W3SllD_3z_W3}"
key = "ISCTF"
payload = generate_payload(target_text, key)
print("Generated Payload:", payload)
运行即可得到 flag.