通过PublicKeyToken防止外部程序集注入

11

我正在使用以下代码:

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

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

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

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


2
你会很难尝试找出完美且未来可靠的授权有效令牌列表。这可能会对您的有效用户产生不良副作用(例如受版权保护的 CD 的问题只影响购买者...)。同时,一个优秀的黑客将会反汇编整个程序,并使用 nops 对代码进行修补。 - Simon Mourier
2个回答

3
乍一看,我要说“不行,这还不够”。
原因:
- `CreateRemoteThread` 攻击是直接 win32 调用,没有托管代码的痕迹,不会触发此类检测器。 - 我认为可以在注入的 DLL 中创建另一个 `AppDomain`,从而完全绕过此检查。然后可以执行来自该 `AppDomain` 的代码,可能(我必须仔细思考)通过 `AppDomain.DoCallback` 回调到“主” `AppDomain`。 - `Process.Kill` 是一个可怕的关闭应用程序的方式,虽然它是一种不可捕获的方式 - 也就是说,任何连接的人都无法阻止它(它在底层使用 Win32 `TerminateProcess`)。
尽管如此,你绝对需要使这个程序集混淆,特别是如果你计划在其中存储敏感信息的话(事实上,如果你能避免的话,我会反对在程序集中存储任何敏感信息)- 你的预防方法绝对不会阻止任何像 Reflector、ILSpy、dotPeek 等反编译器。

除了混淆(我已经在做了)以防止注入(导致应用程序出现不良行为)和知识产权保护之外,您会推荐哪些额外的安全措施? - Federico Berasategui
@highcore 这在很大程度上取决于您的部署方案和应用程序是什么。 - JerKimball
这是我客户端/服务器应用程序框架中Core类的一部分,其中包含WCF服务器部分和WPF客户端共享的通用基础设施。使用我的框架开发的应用程序将作为客户端/服务器应用程序在我的客户设施的局域网环境中部署。 - Federico Berasategui
嗯...只是随口想想,但在托管方面,您可以捕获程序集加载事件并拒绝任何未经gac/强命名的内容...但防止注入路由是一种不同的技术。我得考虑一下 - 我通常处理这个方程式的灰色区域。 :) - JerKimball

2

如果你在运行时生成完整密钥(可能是由多个部分密钥组成),这样做会更加安全。这可以避免对二进制文件进行静态分析以寻找密钥。


你能详细说明一下吗? - Federico Berasategui
我会将密钥分成2个或更多部分,最好是轻度加密的--Rot13甚至可以使用,但我建议使用与Rot13不同的东西,比如Rot11或Rot17。然后解密这些部分并将它们连接在一起以创建真正的密钥。 - Mark Leighton Fisher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接