【CTF-RE】[ctf.show]re2

Author Avatar
白菀枯
发表:2025-04-03 22:53:41
修改:2025-04-03 22:53:41

“勒索病毒”的逻辑是把flag.txt经rc4加密后的内容输出至enflag.txt

加密后的enflag.txt已经提供(加密的内容大概就是flag),又由于rc4是对称加密,目标是找到密钥。

  1. main函数:

  2. 充值函数内部:

char __cdecl sub_401A70(char *inputS, char *Str1)
{
  char v3; // [esp+0h] [ebp-E4h]
  signed int i; // [esp+D0h] [ebp-14h]
  signed int v5; // [esp+DCh] [ebp-8h]

  __CheckForDebuggerJustMyCode(&unk_40B027);
  v5 = strlen(inputS);
  for ( i = 0; i < v5; ++i )
    Str1[i] += inputS[i] ^ 0x1F;
  if ( !strcmp(Str1, "DH~mqqvqxB^||zll@Jq~jkwpmvez{") )// str1原始为0,异或回去是[Warnning]Access_Unauthorized
    print("充值成功.\n", v3);
  else
    print("Error!\n", v3);
  return *Str1;
}

其中的str1已在main函数里memset为0了。

所以可以反推出来应该输入的inputS,_注意运算优先级+->^>+=

def decrypt(encrypted_str):
    # 初始化解密后的字符串
    decrypted_str = []

    # 遍历加密字符串的每个字符
    for char in encrypted_str:
        # 解密逻辑:Str[i] = (Str1[i] - Original_Str1[i]) ^ 0x1F
        # 假设 Original_Str1 的初始值为全零(即 0)
        decrypted_char = (ord(char) - 0) ^ 0x1F
        # decrypted_char = ord(char) - ord(char) ^ 0x1F -的优先级高于^
        decrypted_str.append(chr(decrypted_char))

    # 将字符列表拼接成字符串并返回
    return ''.join(decrypted_str)


# 测试解密函数
if __name__ == "__main__":
    # 加密后的字符串
    encrypted_str = "DH~mqqvqxB^||zll@Jq~jkwpmvez{"

    # 调用解密函数
    decrypted_str = decrypt(encrypted_str)

    # 输出解密结果
    print("解密后的字符串:", decrypted_str)

解密后的字符串: [Warnning]Access_Unauthorized

  • 有了密钥和密文,即可得到原文了

    • 既可以把enflag.txt复制成flag.txt,再加密,相当于两次异或获得到原内容;也可以通过特定工具输入密钥和密文。

    • 比较坑的一点,给出的enlag.txt以ANSI编码,复制到flag.txt建议直接复制文件重命名;到工具中复制也建议直接读取文件,或复制为HEX。而新输出的flag又是UTF-8

    • Latin1编码原来就是ISO-8859-1,向下兼容ANSI,而ANSI作为ASCII的扩展。

  1. RC4内部:

int __cdecl sub_4014E0(char *inputString, int a2, int a3, FILE *FlagTXT, FILE *ENflagTXT)
{
  char v6; // [esp+0h] [ebp-D8h]
  int strLen; // [esp+D0h] [ebp-8h]

  __CheckForDebuggerJustMyCode(&unk_40B027);
  strLen = strlen(inputString);
  TwotoOne(a2, (int)inputString, strLen);       // 第二个参数写入第一个参数
  Zeroto255(a3);                                // a3写入0到255
  RC4_KSA(a3, a2);                              // (目标数组,密钥数组)。用来伪随机打乱目标数组
  RC4_PRGA(a3, FlagTXT, ENflagTXT);             // 从FlagTXT逐字节读入
                                                // 结合随机后的a3异或,生成加密字节
                                                // 写入EnflagTXT
  fclose(FlagTXT);
  fclose(ENflagTXT);
  return print(aE, v6);
}

总之是通过input的密钥,把flag.txt加密到enflag.txt中

评论