防止C#应用程序被进程终止

9
如何保护我的C#应用程序免受他人通过任务管理器或编程方式终止其进程的攻击?
以下是我的情况:
App A是由另一个团队开发的MFC应用程序。它具有未发布的基于文本的远程接口,可以通过后门启用。
我正在开发应用程序B,这是一个与A交互的C# WinForms应用程序。当需要远程访问时,B会启用A的后门,并在完成(或失败)后关闭它。
我正在探索用户可能滥用B以获取对A隐藏功能的访问权限的方法,例如在启用A的远程接口后终止B的进程。我希望在发生这种情况时,B有最后一次机会关闭A的后门。
B使用localhost与A进行交互,因此我不担心断电情况。
我正在寻找不涉及更改A的解决方案。
我并不指望能够阻止黑客(虽然那将是一个额外的好处),但现在一个脚本小子可能会轻易地攻击这个设计:)
这些应用程序在Windows XP上运行,但很快也将支持Vista和7。
提前感谢您的帮助, Jim

1
这样做可能会被一些检测引擎标记为恶意软件/病毒。这是病毒或恶意软件经常使用的模式。 - Aren
3
有趣的是,防病毒/恶意软件扫描器也会使用这种策略,因为恶意软件会试图禁用常驻检测软件。这意味着确实存在合法的理由来做到这一点,尽管使用情况非常有限。 - Joe
1
听起来你更关心如何确保在离开之前清理干净。如果你能详细说明,你可能会得到一些帮助你解决真正问题的答案。 - Jim L
1
过去,我曾经发布了一些很长的问题,感觉自己提供了太多信息。这次似乎我又走得太远了。很快会有编辑后的帖子... - Jim C
9个回答

6
我愿意在他们试图关闭应用程序之前关闭它,但需要先完成一些操作。
在程序关闭时执行必要步骤会导致程序变得脆弱易坏。即使你可以防止通过任务管理器结束你的程序,但你无法阻止他们关闭计算机,甚至拔掉电源线。任何非常重要的任务都将丢失。如果发生断电怎么办?你的任务仍将未能完成,你的重要清理代码也不会被运行。
相反,你应该让你的程序对故障点具有鲁棒性。使用事务,并始终以原子方式保存状态到文件中-确保你始终拥有至少一个有效副本的数据。不要以使它们暂时无效的方式覆盖重要文件。
最后,你可以在你的程序中添加一个对话框,当他们试图关闭它时,警告他们程序需要正确关闭。如果你让程序快速关闭,用户就不想杀死它并会让其正常终止。如果你的关闭需要很长时间,则人们会试图杀死它。如果你对用户友好,他们也会对你友好。
如果快速关闭意味着用户将失去一些未完成的工作,则警告他们并给他们等待任务完成的机会,但如果他们真的想退出你的程序,则让他们退出。

你对一个表现得如此强烈的人做出了一个过于笼统的假设......具体来说,你假设他为什么想在应用程序关闭时运行任何东西。除了存在脏写/仍然打开的事务之外,确保运行关闭其他内容还有其他原因。主要是关闭任何子进程或其他资源。 - Jim L
我曾经遇到过这个问题。我有一个进程,使用信号量与其它实例进行通信。如果您错误地终止它,它会在信号量上留下未知数量的计数,从而破坏所有其他实例。 - Gabe
@Jim Leonardo:解决你提到的问题的另一种方法是使子进程编写更加健壮的代码,以正确处理父进程突然中止的情况。如果每个组件都能够独立地合理运行,那么分布式应用程序的鲁棒性就会增强。 - Mark Byers

4

你真的,真的,真的不想这样做。这会让用户非常生气!但是,如果它应该是一个服务,请将其作为服务帐户运行,并不要给用户管理员权限。


4
只要用户有权调用TerminateProcess终止您的程序,您就无法阻止任务管理器中的End Process立即杀死您。 Raymond Chen在一段时间前发布了这篇文章:程序和用户之间的军备竞赛。请注意,保留HTML标记。

那你肯定没见过那种阻止用户打开任务管理器、控制面板或者MSCONFIG的病毒吧?我朋友就是因为点击了“你中了病毒!”的横幅广告而中招了。真是让人头疼。 - Phil Gan
@Phil - 我也不会做那么恶毒的事 :) 无论如何,一个人可以编写一个应用程序,以编程方式执行TerminateProcess操作,因此仅保护GUI终止是不够的。 - Jim C
2
最后,您提供的链接中的讨论使我意识到了我的愚蠢。我将对A团队进行反驳。 - Jim C
@AshishSinha 我刚刚替换了链接。 这个主题上 Raymond Chen 的另一篇相关文章: https://devblogs.microsoft.com/oldnewthing/20040722-00/?p=38373 - Bob

2
短答案:你不能也不应该这样做。
长答案:你可以尝试启动第二个“辅助”进程,每隔x秒检查一次你的应用程序是否仍在运行。如果没有运行,则重新启动它。
如果你想让一个进程长时间运行,不要相信用户能够保持其运行,考虑使用Windows服务。它们是为此而设计的。

2
我认为大家都没有理解重点。如果我理解正确的话(在你的编辑之后),你希望知道何时被“杀死”,以便您能够优雅地关闭?
“杀死”的关键在于您“无法”停止它。当然,有一些解决方法,例如使用第二个应用程序来恢复已被杀死的应用程序,但这与简单地能够优雅地关闭无关。
最好的方法是要么运行为服务(这样您就无法被杀死,只能被要求关闭),要么重新构造应用程序工作方式,使其不需要在退出前进行“清理”。当应用程序退出时,它所持有的大多数资源都会自动清除,因此您只需要清除自己的数据即可。您可以尝试的方法包括:
- 经常将状态提交到磁盘上,以便在意外退出时不会损失太多(或任何)内容。(请记得刷新所有I / O流以确保它们已提交到磁盘) - 将信息保存到磁盘上,以便下次程序运行时能够检测到意外关闭,并纠正可能由被杀死引起的任何问题。 - 告诉您的用户不要做傻事,并优雅地退出您的应用程序。如果他们忽略您,请戳他们的眼睛。通常不超过两次,他们就会听您的话 :-)

+1 是为“下次应用程序启动时进行恢复”,因为意外的关闭事件确实会发生(例如电源故障、磁盘故障等)。 - Ben Voigt
@rohit - 许多用户知道如何终止任务。相对较少的人知道如何停止服务,更不用说 Kill 一个了。 - Jason Williams
@Jason Williams: 运行中的服务在任务管理器的“进程”选项卡下是可见的,就像其他运行的进程一样。我拥有管理员权限,并刚刚运行了一些自定义服务(可以看到它是在SYSTEM用户下运行的),然后使用任务管理器将其终止,这将使服务变为停止状态。 - mr.b
@mr.b:进程选项卡显示进程,其中可能包括与某些服务相关的进程。我的古老XP框(作为管理员)为所有用户报告了31个进程,但services.exe列出了96个可用服务和46个正在运行的服务。也许您已经特别配置了您的PC,但普通用户无法从XP T.M.中看到或终止大多数服务。在Vista和Win7中,TM有一个额外的服务选项卡,其中列出了服务(您可以从中停止但仍然不能杀死服务),但是只有进程显示在进程列表中。 - Jason Williams
@Jason:抱歉,我误解了你的陈述。是的,在我的系统上,即使在TM进程选项卡中也不是所有服务都可见。 - mr.b
显示剩余3条评论

1
为了防止您的应用程序被终止,您可以将其作为另一个用户(即作为服务或另一个用户帐户)运行,并将用户限制为标准用户
这样,没有恶意用户可以杀死您的进程,因为只有管理员才能杀死它,而这是一种特权,显然您不信任任何人。
它具有遵循操作系统预期设计的优点。

1

@Jim

如果App A可以接收修改请求

  1. 最好的情况是,我希望有一种架构,在打开后门时注册所有的App B,并要求它们以一定的间隔向App A发送注册信息,以便App A在App B未通知其仍需要访问时关闭自己的后门。这仍然不是完全安全的,但是如果没有某种“安全”通信的自我调节,App A不应该被设计为具有这样的接口。

  2. 或者,您可以建议修改App A以检查有效进程,如果在其后门打开时找不到任何进程,则关闭它(这是可欺骗的,因为它根据进程名称进行判断)。

否则,当App B不需要立即访问时,听起来像是应该尽可能经常关闭后门。

要求App B提供对App A的访问安全性确实是一个糟糕的模型。


当任务完成时,B会关闭后门。我同意,A的设计并不是最优的。 - Jim C

0
据我所知,你不能这样做,即使你可以,你也不应该这样做。想象一下,如果你不能强制终止一个应用程序会有多烦人。
如果你的应用程序保持运行很重要,你可以创建一个 Windows 服务来“ping”应用程序以确保它正在运行(你可以使用命名管道、套接字、pid 文件等)。如果服务检测到进程已经死亡,那么它就可以重新启动它。这可能是你最好的选择。

0

当应用程序第一次启动时,您能否不执行在后台运行并尝试回调到App B的第三方应用程序/进程,以便当关闭App B时.. App C可以看到并执行一个过程来关闭App A的后门。

因此,当App B通过预期的关闭按钮成功关闭时,它将禁用App C检查App B是否仍然正常工作...

我目前对C#并不是很熟悉,但看着您的问题,这可能是我尝试解决它的方法之一..

另外,如果App B也检查App C,那么如果App C已经关闭,App B将尝试关闭后门。

正如其他人所说,这可能不是一个好主意。


有趣。不幸的是,“App B”实际上代表了一类应用程序,每个应用程序都操作后门。虽然一次只运行一个B,但这会使第三方应用/服务如何监视B的存在变得更加复杂。 - Jim C
正如我所说,我很抱歉在这个领域缺乏技能,但我的评论是基于我认为可能的情况以及我如何解决这种情况。在我的一方创建和部署这个并不是我的强项,我只是试图给你提供一个实际的解决方案。你是解决问题的人。 - RobertPitt
是的,我明白了。我不是让你帮我写代码,只是想给你更多关于B概念的信息。 - Jim C

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