【问题标题】:Prevent external assembly injection via PublicKeyToken通过 PublicKeyToken 防止外部程序集注入
【发布时间】:2012-11-14 02:12:18
【问题描述】:

我正在使用以下代码:

AppDomain.CurrentDomain.AssemblyLoad += (sender, args) =>
{
    var token = args.LoadedAssembly.GetName().GetPublicKeyToken();

    if (!IsValidToken(token))
    {
        Process.GetCurrentProcess().Kill();
    }
};

IsValidToken() 将正在加载的程序集的公钥令牌与在我的应用程序中硬编码为字节数组的授权公钥令牌列表进行比较。

这是防止代码注入攻击的良好安全措施吗?此外,考虑到我稍后将使用 NetReactor 混淆我的应用程序,这是否必要?我试图防止对我的应用程序进行任何“窥探”,不仅来自 Snoop 工具,还来自任何外部不受欢迎的来源。

【问题讨论】:

  • 您将很难找出完美且面向未来的有效令牌授权列表。您可能会对您的有效用户产生不希望的副作用(例如受版权保护的 CD 的问题,这些问题仅对购买它的人来说是个问题......)。同时,优秀的黑客会反汇编整个代码,然后用 nops 修补代码。

标签: c# .net-4.0 assemblies code-injection


【解决方案1】:

乍一看,我会说“不,这还不够”。

原因:

  • CreateRemoteThread 攻击是直接的 win32 调用,没有托管代码跟踪会触发这样的检测器

  • 我认为可以在注入的 dll 中创建另一个 AppDomain,从而完全绕过此检查。然后可以从该AppDomain 执行代码,可能(我必须仔细考虑)通过AppDomain.DoCallback 回调到“主”AppDomain

  • Process.Kill 是删除应用程序的可怕方式,尽管它是一种不可捕获的方式 - 也就是说,任何连接的人都无法阻止它(它使用 Win32 TerminateProcess引擎盖下)

我必须拿出我的“Injecterator”工具来测试这些语句,不过——如果我能记得我把代码放在哪里...

不管这些——你绝对想把这个程序集弄糊涂,特别是如果你打算在里面存储敏感位(事实上,我反对存储 ANY 敏感如果您可以提供帮助,请在程序集中提供信息)-您的预防方法绝对不会阻止任何反汇编程序,例如 Reflector、ILSpy、dotPeek 等。

【讨论】:

  • 您会推荐哪些额外的安全措施?除了混淆(我已经在做)以防止注入(导致应用程序具有不需要的行为)和知识产权保护之外?
  • @highcore 这在很大程度上取决于您的部署方案以及您的应用程序是什么。
  • 这是我的客户端/服务器应用程序框架中Core 类的一部分,它包含由 WCF 服务器部分和 WPF 客户端共享的公共基础结构。使用我的框架开发的应用程序将作为客户端/服务器应用程序部署在我客户设施的 LAN 环境中。
  • 嗯...只是大声思考,但在托管方面,您可以捕获程序集加载事件并拒绝任何不是 gac' ed/strong 命名...但防止注入路线是另一种野兽。我必须考虑一下——我通常会处理这个等式的灰色方面。 :)
【解决方案2】:

如果您在运行时生成完整密钥(可能来自多个部分密钥),也会更安全。这可以静态检查您的二进制文件中的键。

【讨论】:

  • 你能详细说明一下吗?
  • 我会将密钥分成 2 个以上的部分,最好是轻度加密——Rot13 甚至可以工作,但我会推荐与 Rot13 不同的东西,比如 Rot11 或 Rot17。然后解密这些片段并将它们连接在一起以创建真正的密钥。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-25
  • 1970-01-01
  • 1970-01-01
  • 2011-09-09
  • 2015-11-17
  • 1970-01-01
相关资源
最近更新 更多