如何从客户端的DLL注入保护.NET命名管道通信?

How to Secure .NET Named Pipe Communication From DLL Injection on the Client Side?

提问人:Abdur Rahman 提问时间:10/29/2023 最后编辑:Abdur Rahman 更新时间:10/31/2023 访问量:87

问:

我们的 .NET Framework C# 应用程序由两部分组成:客户端(未提升)和服务(提升)。客户端和服务之间的通信通过命名管道进行。每当要执行提升的任务时,客户端(命名管道客户端)始终与服务(命名管道服务器)进行通信。通信采用 JSON 字符串的形式。需要保护此通信,以便服务不会被欺骗代表攻击者执行提升的任务。@Xecrets 该服务是客户端执行提升任务的一种特权帮助程序。该服务具有一些强大的功能,例如将文件复制到 Program Files、安装 MSI 以及运行 .reg 注册表文件。

服务器端已经采取了一些安全措施:

  1. Pipe Security 对象具有一些安全措施:
PipeSecurity pipeSecurity = new PipeSecurity();
var id = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);

// Allow read and write access to the pipe from different user sessions
pipeSecurity.SetAccessRule(new PipeAccessRule(id, PipeAccessRights.ReadWrite, AccessControlType.Allow));
            
// Grant Service user instance full control.
pipeSecurity.AddAccessRule(new PipeAccessRule(System.Security.Principal.WindowsIdentity.GetCurrent().User, PipeAccessRights.FullControl, AccessControlType.Allow));
           
  1. 该服务检查尝试连接到名为管道的服务的进程 exe 的路径。仅当客户端进程位于白名单路径上时,服务才接受连接。

问题

但是,存在另一个漏洞的风险,即 DLL 注入。如果将 DLL 注入到客户端进程中,则当 DLL 尝试连接到名为管道的服务时,DLL 的路径似乎与客户端应用的路径相同。这会欺骗服务,并且某些任意命令可以从注入的 DLL(恶意)传递到服务。这可能会导致权限提升。如何确保只有客户端应用才能与服务通信?

相关

也许这是相关的,我不确定:从命名管道获取客户端用户令牌

我们是否应该尝试保护命名管道以避免注入的 DLL 与我们的服务进行通信,还是应该尝试完全使用不同的 IPC,例如服务契约?

脑海中的想法

尝试优化以下想法来解决此问题:

  1. Microsoft安全和访问权限 (https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-security-and-access-rights) 这看起来有点难以理解。另外,我不确定这是否真的能解决我的问题。

  2. 考虑在客户端和服务之间的通信中使用非对称加密。但这种方法的挑战在于,在客户端和服务之间安全地分发公钥和私钥似乎是不可能的。如果客户端在未提升的情况下运行,则客户端肯定无法将公钥存储在安全位置。因此,攻击者可以很容易地修改公钥并提供自己的公钥来欺骗服务。

C# 安全 加密 命名管道 访问权限

评论

0赞 Xecrets 10/30/2023
不要真正了解如何保护自己免受成功的代码注入到可执行进程中的攻击。有很多方法可以让代码在现有流程的上下文中执行......例如,请参阅 ired.team/offensive-security/code-injection-process-injection 以获取一长串选项...由于我们不知道客户端或服务器是做什么的,因此很难说更多,但从安全的角度来看,您应该将这种情况视为用户被委派了服务的任何权限,并从该角度进行处理。
0赞 Abdur Rahman 10/30/2023
@Xecrets 该服务是客户端执行提升任务的一种特权帮助程序。该服务具有一些强大的功能,例如将文件复制到 Program Files、安装 MSI 以及运行 .reg 注册表文件。将此添加到原始帖子中。
0赞 Abdur Rahman 10/30/2023
我们@Xecrets说通信无法免受此类攻击?还是在安全的 Windows 环境中,未提升的用户本身的注入极不可能?
0赞 Damien_The_Unbeliever 10/30/2023
要问和回答的问题是 - 在首先可以进行 DLL 注入的情况下,如何将客户端代码留在客户端代码中?是的,弱势用户可能正在运行此代码,但这通常并不意味着他们也应该具有对可执行目录的写入权限。您似乎正试图找到最适合已经坏掉的门的最佳锁。
0赞 Xecrets 10/31/2023
我想说的是,您已经使用服务“沙盒化”了需要提升的操作,这很好。但是,一旦授予客户端对服务的访问权限,就实际上无法保证只有作为客户端运行的特定代码段才能使用它。您可以设置一些障碍,例如将代码位置列入白名单。这与命名管道或通信机制无关,而是与确定的攻击者以服务器接受的方式在客户端上下文中执行代码的可能能力有关。

答:

0赞 Ben Voigt 10/31/2023 #1

您需要更改请求的抽象级别。要求客户端请求操作(安装此更新)并让服务决定如何安全地执行该操作(也许它会检查需要安装的更新上的签名,如果该签名存在,则为) 它从签名的更新文件内部读取指令)

评论

0赞 Abdur Rahman 10/31/2023
不错的建议。谢谢。
0赞 Abdur Rahman 11/14/2023
我们已经朝着这个方向前进。只是好奇是否还有任何方法可以阻止任何其他应用程序与我们的服务进行通信。