【问题标题】:Self validating binaries?自我验证二进制文件?
【发布时间】:2010-09-11 03:06:43
【问题描述】:

我的问题很简单:你是一个可执行文件,输出“访问被授予”或“访问被拒绝”,而邪恶的人试图理解你的算法或修补你的内部,以便让你一直说“访问被授予” .

在此介绍之后,您可能会非常想知道我在做什么。暗黑破坏神3一出,他会破解吗?我可以平息你的烦恼,我不是那些饼干中的一员。我的目标是破解。

Crackmes 可以在 - 例如 - www.crackmes.de 上找到。 Crackme 是一个小可执行文件,(大多数时候)包含一个小算法来验证序列并根据序列输出“访问授权”或“访问被拒绝”。目标是让这个可执行输出始终“授予访问权限”。你被允许使用的方法可能会受到作者的限制——不能打补丁,不能反汇编——或者涉及你可以用二进制、objdump 和十六进制编辑器做的任何事情。破解crackmes肯定是乐趣的一部分,但是,作为一个程序员,我想知道你如何才能创建困难的crackmes。

基本上,我认为crackme由两大部分组成:一定的串行验证和周边代码。

仅使用汇编就很难跟踪串行验证是很有可能的,例如,我有想法将串行作为模拟微处理器的输入,该模拟微处理器必须以某种状态结束才能使串行被接受.另一方面,人们可能会变得便宜并更多地了解加密强大的方法来保护这部分。因此,使这变得足够困难以使攻击者尝试修补可执行文件不应该是 很难。

然而,更困难的部分是保护二进制文件。让我们假设一个完全安全的串行验证,它不能以某种方式被逆转(当然我知道它可以被逆转,毫无疑问,你从你试图破解的二进制文件中撕下部分,然后向它扔随机序列,直到它接受为止)。我们如何防止攻击者仅仅覆盖二进制文件中的跳转以使我们的二进制文件接受任何内容?

我一直在搜索这个主题,但大多数关于二进制安全性、自我验证二进制文件等的结果都出现在试图防止使用受损二进制文件攻击操作系统的文章中。通过签署某些二进制文件并使用内核验证这些签名。

我目前的想法包括:

  • 检查二进制文件中要跳转的显式位置。
  • 校验和部分二进制文件并将运行时计算的校验和与那些进行比较。
  • 对代码中的函数进行正负运行时检查。对串行验证有副作用。 :)

你能想出更多方法来更长时间地惹恼可能的攻击者吗? (当然,你不能让他永远离开,在某些时候,所有的检查都会被破坏,除非你设法通过在程序本身中嵌入正确的校验和来破坏校验和生成器,呵呵)

【问题讨论】:

    标签: security binary


    【解决方案1】:

    您正在学习“防倒车技术”。它基本上是一门艺术。更糟糕的是,即使你踩到新手,olly 和 IDA Pro 也有“反反倒车插件”,他们可以下载并绕过你的大部分反制措施。

    对策包括通过陷阱调试器 API 检测调试器,或检测“单步执行”。您可以插入在检测到调试器中断后继续运行的代码,但在程序中很晚才开始随机运行。这真是一场猫捉老鼠的游戏,饼干占了很大的上风。

    看看... http://www.openrce.org/reference_library/anti_reversing - 外面有一些东西。

    http://www.amazon.com/Reversing-Secrets-Engineering-Eldad-Eilam/dp/0764574817/ - 这本书提供了非常好的防逆转信息,并逐步介绍了这些技术。如果您总体上正在倒车,这是一个很好的起点。

    【讨论】:

      【解决方案2】:

      我相信这些事情通常比它们的价值更麻烦。

      您花费大量精力编写代码来保护您的二进制文件。坏人花费更少的精力来破解它(他们通常比你更有经验)然后释放破解,这样每个人都可以绕过你的保护。您唯一会惹恼的人是那些因您的保护而感到不便的诚实人。

      只需将盗版视为业务成本 - 如果您确保所有支持仅针对付费客户,则盗版软件的增量成本为零。

      【讨论】:

      • 是的,对于商业软件,我完全同意。包括一层又一层的自我验证只会让事情变得太复杂,无法维护,而且很烦人。但这不适用于商业软件 - 它是一款游戏,目标是在一方面花费大量精力。
      【解决方案3】:

      有TPM技术:tpm on wikipedia

      它允许您将二进制的加密校验和存储在特殊芯片上,这可以作为单向验证。

      注意:TPM 名声不好,因为它可以用于 DRM。但对于该领域的专家来说,这有点不公平,甚至还有一个open-TPM 组允许 linux 用户准确控制他们的 TPM 芯片的使用方式。

      【讨论】:

        【解决方案4】:

        解决此问题最有效的方法之一是Trusted Computing。基本上,您将加密应用程序并将解密密钥传输到特殊芯片(Trusted Platform Module),该芯片仅在验证计算机处于“受信任”状态后才会解密应用程序:没有内存查看器/编辑器,没有调试器等。基本上,您需要特殊的硬件才能查看解密的程序代码。

        【讨论】:

          【解决方案5】:

          因此,您想编写一个程序,该程序在开始时接受一个密钥并将其存储在内存中,然后从磁盘中检索它。如果它是正确的密钥,则该软件可以工作。如果是错误的密钥,软件就会崩溃。目标是盗版者很难生成有效密钥,并且很难修补程序以使用未经许可的密钥。

          这实际上可以在没有特殊硬件的情况下实现。考虑我们的遗传密码。它的工作原理是基于这个宇宙的物理学。我们尝试破解它,制造药物等等,但我们惨遭失败,通常会产生大量不良副作用,因为我们还没有完全逆向设计复杂的“世界​​”,遗传“密码”在其中进化运作.基本上,如果您在每个人都可以访问的通用处理器(一个通用“世界”)上运行所有东西,那么几乎不可能编写如此安全的代码,正如当前软件如此容易破解所证明的那样。

          要实现软件的安全性,您基本上必须编写自己的足够复杂的平台,而其他人必须对其进行完全彻底的逆向工程,以便修改您的代码行为而不会产生不可预知的副作用。但是,一旦您的平台被逆向工程,您就会回到原点。

          问题是,您的平台可能会在通用硬件上运行,这使您的平台更容易进行逆向工程,从而使您的代码更容易进行逆向工程。当然,这可能只是意味着您的平台要求的复杂程度提高了一点,从而难以进行逆向工程。

          足够复杂的软件平台应该是什么样子?例如,可能在每 6 次加法运算之后,第 7 次加法返回的结果乘以 PI 除以自系统初始化以来执行的减法和乘法运算总数之差的模数 5 的对数的平方根。该平台必须像代码本身一样独立跟踪这些数字,才能解码正确的结果。因此,您的代码将基于您设计的平台的复杂底层行为的知识编写。是的,它会占用处理器周期,但必须有人对这个小小的意外行为进行逆向工程,并将其重新设计为任何新代码,以使其正常运行。此外,您自己的代码一旦编写就很难更改,因为它会崩溃成不可简化的复杂性,每一行都取决于之前发生的一切。当然,在一个足够安全的平台中会有更多的复杂性,但关键是有人会在逆向工程和修改您的代码之前对您的平台进行逆向工程,而不会造成负面影响。

          【讨论】:

            【解决方案6】:

            关于复制保护和保护保护的好文章Keeping the Pirates at Bay: Implementing Crack Protection for Spyro: Year of the Dragon

            其中提到的最有趣但尚未提及的想法是级联故障 - 您的校验和会修改单个字节,从而导致另一个校验和失败。最终,其中一个校验和导致系统崩溃或做一些奇怪的事情。这使得盗版您的程序的尝试看起来不稳定,并使原因发生在距离崩溃很远的地方。

            【讨论】:

              猜你喜欢
              • 2020-01-13
              • 1970-01-01
              • 2010-10-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-03-13
              • 2012-11-07
              • 2011-05-25
              相关资源
              最近更新 更多