病毒使用自定义 XOR 加密,需要帮助可能破解它/逆向 EXE

逆向工程 艾达 加密 解密 修补 恶意软件
2021-07-05 09:08:12

正如我在上一个问题中所述,我被加密病毒感染,该病毒以某种类型的自定义 CFB XOR 加密对任何给定文件的两个 1024 字节块(第一个 1024 个和最后一个 1024 个)进行加密。我能够得到另一个受害者支付的解密器(当然它对我不起作用,因为不同的密钥)并在 IDA 中找到解密函数,但是 C 生成的代码很糟糕,整个 EXE 都被混淆了使用自定义方法。stackexchange 的用户将其转换为 C# 以便我更好地理解它(感谢Edward)有关这方面的更多信息,请参阅最后一篇文章:

用于解密功能的 IDA Pro C 转储

所以说到点子上了。这家伙使用的加密几乎是带有一些技巧的异或,因此加密功能与解密几乎相同。在解密器中保存了一个 20 字节的密钥,我通过将受害者支付的 4 个不同的解密器放在一起比较发现这一点,所有这些解密器在同一区域都只有 20 字节的差异,并且后来在 IDA 中将其推送到堆。

即使密钥是 20 个字节,加密中也只使用了 16 个字节,4 个用于为每个加密文件生成一个标头,以便解密者以后可以找到它们。所以在ida中它看起来像这样:

双字:C4 67 0E 46 双字:99 2F D3 E4 40 BD 87 EB 8F 35 04 96 3B CE 8D 73

我的猜测是在每个 512 块加密中使用 4 个字节,两个 512 块相互进行 CFB 处理以生成 2 1024 个加密数据块。对不起,如果这没有意义。

可悲的是,正如我所说,解密器被严重混淆,并且还使用了大量垃圾 JMP 和函数,使其无法阅读。花了很长时间才找到解密功能。

所以对于代码,这是解密(也加密)功能的清理代码。

int mystery(char *buff, int bufsize, int nonce1, int nonce2)
{
  int result = 0;
  // ch is the next byte (character) in the buffer
  char ch = 0; 
  int count = bufsize; 
  char *ptr = buff; 
  int x;

  for (x = nonce1; count; --count)
  {
      // this bit of trickery just replaces the low 8 bits
      // of x with the low 8 bits of (x+ch) neglecting carry, if any
      x = (x & ~0xff) | ((x+ch) & 0xff);
      // XOR the buffer with the calculated x value
      *ptr ^= x;
      // read in the next character into ch
      ch = *ptr++;
      // obfuscate by adding nonce2 
      x += nonce2;
      // if x = 0x12345678, this would make it 0x34567812
      // for 32-bit ints.  Just a rotate left of 8 bits.
      x = (x<<8) | ((x >>((sizeof(int)-1)*8) ) & 0xff);  
  }
  result = x;
  // return the last calculated x which may be used to chain all
  // of the blocks together.  That is, the return value x is 
  // probably passed as nonce1 to encode the next block.
  return result;
}

以上 2 个名为 nonce 的 INT 是从 16 个字节以某种方式生成的。

所以基本上,我和许多其他人都想知道这是否像常规 XOR 一样可以暴力破解或破解?当然我不知道我的密钥,但如果可能的话,几乎每个人都会有至少一个纯文本和加密文件用于像 XOR 这样的纯文本攻击。

下面是与此解密器一起使用的相同 Decrypted(纯文本)和加密文件,以及作为资源的解密器本身。上面的示例密钥也是此解密器中的密钥。(遗憾的是没有特别的顺序)

解密(纯文本)文件

加密文件

解密器EXE

(这个EXE绝对不是恶意的,运行时不会影响任何文件,因为它检测到加密文件。我已经在我的个人电脑上运行了数百次没有故障。它可以连接到调试器并安全运行。病毒total 说其他明智的只是因为它是一个已知的 exe 被感染。)

最后一点,我相信 IDA 函数 4075F3 会生成随机数,但不能是 100%

我很抱歉这么长,很难一下子解释清楚。

2个回答

我目前没有时间制定适当的解决方案,但我会提供一些提示,希望对您有所帮助。

老实说,我会将其分解为一个更简单的问题,将整数转换为更少的位。例如,您可以采用该算法并对其进行修改,使其适用于 8 位随机数,然后将您的旋转量降低到 2 位(随机数大小的四分之一)。然后,您也将掩码从 8 位切换为 2 位,并将密码异或切换为 2 位。这样您就可以处理更易于管理的问题。您甚至可以将其简化为 4 位随机数和 1 位密码。

从这个简化的问题中,您可以为从明文到密文的每一位制定方程。将其插入Z3 之类的东西可能是获得答案的最简单方法。这是一篇使用Z3攻击简单哈希函数的文章。

看看它,如果你有明文和密文,你就可以解出密钥(nonce1 和 nonce2)。添加 nonce2 可能是一个问题,因为它实际上是一个加法模数 2^32。由于它是一个加法,由于对 nonce2 和 x 的约束,实际上只有两个值可以映射到相同的值,因此反转并非不可能。

如果你不确定你是否可以自己解决方程,一旦你弄清楚了,我会把问题带到math.stackexchange.com

如果确实如此ch=*prt++(而不是ch=*++ptr),则ch是刚刚写在前一行中的字符,而不是如注释所暗示的那样读取的下一个字符。总之,相反你写的这个方法是不是不由自主的:随着nonce1= nonce2=0明文1,2,3,4,5,6,7,8被转化为1,3,0,4,1,5,0 ,8(如果我没记错的话)然后转换为 (1,2,2,...)