自验证二进制文件?

时间:2020-03-06 14:24:52  来源:igfitidea点击:

我的问题很简单:我们是一个可执行文件,输出"授予访问权限"或者"拒绝访问权限",邪恶的人会试图理解算法或者修补内脏,以便使我们一直说"授予访问权限"。

介绍之后,我们可能会很想知道我在做什么。一旦出了暗黑破坏神3,他会破解吗?我可以安抚后顾之忧,我不是其中的一员。我的目标是打击。

可以在例如www.crackmes.de上找到Crackmes。 Crackme是一个小小的可执行文件,(大多数情况下)包含一个小算法来验证串行,并根据串行输出"已授予访问权限"或者"拒绝访问"。目标是始终使此可执行输出"已授予访问权限"。作者被允许使用的方法可能不受作者的限制,不得进行任何修补,分解或者涉及我们可以使用二进制,objdump和十六进制编辑器进行的任何操作。毫无疑问,破解裂缝是乐趣的一部分,但是,作为一名程序员,我想知道如何创建困难的裂缝。

基本上,我认为crackme由两个主要部分组成:特定的串行验证和周围的代码。

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

但是,更困难的部分是保护二进制文件。让我们假设一个完全安全的序列验证,该验证不能以某种方式被撤消(当然,我知道它可以被撤消,毫无疑问,我们从二进制文件中剥离了部分内容,然后尝试破解并向其抛出随机序列,直到接受为止)。我们如何才能防止攻击者仅仅覆盖二进制文件中的跳转,以使我们的二进制文件接受任何内容?

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

我目前的想法包括:

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

我们是否能够想到更多方法来更长时间地困扰潜在的攻击者? (当然,我们无法永远让他离开,有时,所有支票都将被破坏,除非我们通过能够在程序本身中嵌入程序的正确校验和来破坏校验和生成器,否则)

解决方案

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

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

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

有TPM技术:维基百科上的tpm

它使我们可以将二进制文件的加密校验和存储在特殊芯片上,这可以用作单向验证。

注意:TPM有点不好,因为它可以用于DRM​​。但是对于该领域的专家来说,这是不公平的,甚至还有一个开放的TPM组,它允许linux用户精确控制其TPM芯片的使用方式。

我们正在使用"防逆向技术"。基本上,这是一门艺术。更糟糕的是,即使我们脚了新手,也为olly和IDA Pro提供了"反反反转插件",他们可以下载并绕过许多对策。

应对措施包括通过陷阱调试器API进行调试器检测,或者检测"单步执行"。我们可以插入代码,在检测到调试器中断后,该代码可以继续运行,但在程序中稍后会随机运行。这确实是一场猫捉老鼠的游戏,而饼干则占了上风。

退房...
http://www.openrce.org/reference_library/anti_reversing一些可用的东西。

http://www.amazon.com/Reversing-Secrets-Engineering-Eldad-Eilam/dp/0764574817/本书提供了非常好的防逆转信息,并逐步介绍了这些技术。一般而言,如果要进行int反转,则是一个很好的起点。

对此问题最有力的解决方案之一是可信计算。基本上,我们将对应用程序进行加密,并将解密密钥传输到特殊芯片("受信任的平台模块")。只有在验证计算机处于"受信任"状态后,芯片才会对应用程序进行解密:没有内存查看器/编辑器,基本上没有调试器等。基本上,我们将需要特殊的硬件才能查看解密的程序代码。

因此,我们想编写一个程序,该程序在开始时会接受一个密钥,并将其存储在内存中,然后从光盘中检索它。如果密钥正确,则软件可以运行。如果输入的密码错误,软件将崩溃。目的是使盗版者很难生成有效密钥,并且很难对程序进行修补以使其与未授权密钥一起使用。

实际上,无需特殊硬件即可实现。考虑我们的遗传密码。它基于这个宇宙的物理原理而工作。我们试图破解它,制造毒品等,但不幸的是我们失败了,通常会产生大量不良后果,因为我们还没有完全逆向改造遗传"代码"演变为可操作的复杂"世界" 。基本上,如果我们正在所有人都可以访问的通用处理器(通用"世界")上运行所有程序,那么实际上不可能编写这样的安全代码,正如当前软件如此容易被破解所证明的。

为了获得软件的安全性,我们基本上必须编写自己的足够复杂的平台,其他人必须对其进行完全彻底的逆向工程,以便修改代码的行为而不会产生不可预期的副作用。但是,一旦对平台进行了逆向工程,我们将回到第一位。

问题是,平台可能要在通用硬件上运行,这使平台更易于逆向工程,从而使代码更易于逆向工程。当然,这可能仅意味着针对平台所需的复杂程度(对于反向工程而言足够困难)提高了一些标准。

一个足够复杂的软件平台会是什么样?例如,也许在每6次加法运算之后,第7次加法运算将返回结果乘以PI除以自系统初始化以来执行的减法和乘法运算总数之差的模5的对数的平方根。为了解码正确的结果,平台必须与代码本身一样独立跟踪这些数字。因此,将基于对我们设计的平台的复杂基础行为的了解来编写代码。是的,这会占用处理器周期,但是有人必须对很少出现的意外行为进行逆向工程,然后将其重新工程为任何新代码,以使其正常工作。此外,一旦编写,我们自己的代码将很难更改,因为它会陷入无法减少的复杂性,每一行取决于之前发生的一切。当然,在足够安全的平台上会有更多的复杂性,但是重点是,有人在对平台进行反向工程之前可以对其进行反向工程和修改代码,而不会损害副作用。

关于复制保护和保护保护的出色文章防止海盗入内:
实施Spyro的裂缝保护:龙年

此处尚未提到的最有趣的想法是级联故障,校验和会修改单个字节,从而导致另一个校验和失败。最终,校验和之一导致系统崩溃或者发生奇怪的事情。这使盗版程序的尝试看起来不稳定,并且导致崩溃的原因很长一段时间。