如何在 Windows 下自动启动非管理员用户无法关闭的 UI 应用程序?

发布于 2024-12-25 10:04:17 字数 641 浏览 3 评论 0原文

我开发了一个 C# Windows 窗体应用程序,它作为系统托盘图标在后台运行,并在单击它时执行一些操作。它应该在 Windows 启动并持续运行时启动,并且不允许没有管理员权限的普通用户将其关闭。

最好的方法是什么?我最初打算通过任务计划程序在 LocalSystem 帐户上运行它,但后来我(艰难的方式)了解了 会话 0 隔离(即应用程序将运行,但其 UI 元素不显示)。当我使用登录用户运行它时,即使它运行提升,用户仍然可以通过任务管理器将其关闭(不需要提升)。

有没有办法让 LocalSystem 中的进程访问 UI?我有一个 winlogon 和一个来自 LocalSystem 的 csrss 进程在会话 1 中运行,所以我想它可以完成,我只是不知道如何完成。或者是否有一种更简单的方法来禁止用户通过任务管理器关闭自己的进程?我能想到的唯一的其他选择是创建一个额外的 Windows 服务,如果应用程序正在运行,它会持续轮询,如果有人杀死它,它会立即再次启动它 - 但这看起来非常笨拙(而且,我希望它在应用程序运行时保持死机状态)自行崩溃,以避免单个错误导致进程创建无限循环)。

I have developed a C# Windows Forms application that runs in the background as a systray icon and does some stuff when it's clicked. It is supposed to launch when Windows starts and run continously, and a normal user without administrator rights shall not be allowed to shut it down.

What is the best way to do this? I initially intended to run it on the LocalSystem account through Task Scheduler, but then I learned (the hard way) about Session 0 isolation (i.e. the application will run but its UI elements do not show). When I run it with the logged in user, even if it runs elevated, the user can still shut it down through task manager (without requiring elevation).

Is there any way to give a process from LocalSystem access to the UI? I have a winlogon and a csrss process from LocalSystem running in session 1, so I guess it can be done, I just don't know how. Or is there maybe an easier way to disallow users to shut down a process of their own through the task manager? The only other option I can think of is to create an extra Windows Service that keeps polling if the app is running, and immediately launches it again if someone kills it - but that seems incredibly clumsy (also, I want it to stay dead when it crashed by itself, to avoid a single bug causing infinite loops of process creation).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

水波映月 2025-01-01 10:04:17

取决于他们为什么不能关闭它。
自然的方法是创建一个服务,由高权限帐户启动,然后让桌面应用程序显示它正在做什么。

如果他们应该看到某些内容,但不要看到,因为他们没有运行服务监视器应用程序。 (并向服务人员确认消息),向他们发送一封电子邮件,向他们的老板发送一封电子邮件,向自己发送一封电子邮件,然后对他们大喊大叫……

这比尝试重新打开这罐罐头的盖子要容易得多蠕虫。

确保桌面应用程序正在运行的一个好方法是简单地安排它运行每个 X,但如果它已经运行或设置了一些非常错误的 flkag,则立即退出。

不值得编写一个服务来检查它是否仍然存在,因为他们也可以杀死它,除非你想让它成为他们无法杀死的服务。 :(

你试图对此过于严厉。添加某种审计,这样你就可以看到它死掉或被关闭,监视它并处理任何不利的报告。这要容易得多,并且给管理人员一些事情可做...

Deponds on why they can't shut it down.
The natural way to go would to have created a service, started by a high priv account, and then had the desktop app just show what it was doing.

If there's something that they should see, but don't becasue they aren't running the service monitor app. (and acknowledge message back to the service), send them an email, send their boss an email, send yourself one and then go shout at them.....

Be a lot easier than trying to get the lid back on this tin of worms.

A nice way to make sure the desktop app is ruuning, would be simply to schedule it to run every X, but drop out immediately if it already is or the somethingwenthorriblywrong flkag is set.

Not worth writing a service to check if it's still there, as they could kill that as well, unless you want to make that a service they can't kill. :(

You are trying to be too draconian with this. Add some sort of auditing so you can see it dies or was shutdown, monitor that and deal with any adverse reports. It's a heck of a lot easier, and gives manage something to do...

我要还你自由 2025-01-01 10:04:17

您可以在用户的​​登录会话中运行管理进程。一种方法是让主进程(系统服务)复制自己的令牌,使用 SetTokenInformation 更改与令牌关联的会话,然后调用 CreateProcessAsUser。 lpStartupInfo 参数可用于将进程与特定的窗口站和桌面关联起来。可能需要首先显式更改窗口站和桌面上的权限。

然而,从安全角度来看,这是一个坏主意,因为 GUI 应用程序很容易受到同一桌面上其他进程发送的恶意消息的影响(“粉碎攻击”)。

在用户自己的上下文中运行该进程但对其应用 ACL 会更安全。这可以使用 CreateProcess 或 CreateProcessAsUser 的 lpProcessAttributes 参数或使用 SetSecurityInfo 函数来完成。我从未尝试过此操作,但理论上它应该阻止用户使用任务管理器关闭进程。

如果您从用户的上下文中创建进程,则该用户将是所有者,因此知识足够丰富的人员可以更改回权限以终止该进程。如果您需要阻止此漏洞,则从特权主进程(可以从用户会话中的现有进程之一复制令牌)使用 CreateProcessAsUser 应该(同样,理论上)意味着该用户不是进程所有者。

另一个潜在的问题:如果您侦听表明用户正在注销(以便退出)的消息,则此类消息可能是伪造的。如果不这样做,那么您需要在用户注销时找到其他退出方式。您可能需要在这里进行实验,我不确定系统会如何反应。

You can run an administrative process in the user's logon session. One method would be to for a master process (a system service) to duplicate its own token, use SetTokenInformation to change the session associated with the token, and then call CreateProcessAsUser. The lpStartupInfo parameter can be used to associate the process with a particular window station and desktop. It may be necessary to explicitly change the permissions on the window station and desktop first.

HOWEVER, this is a bad idea from a security standpoint, because GUI applications are vulnerable to malicious messages sent from other processes on the same desktop ("shatter attacks").

It would be safer to run the process in the user's own context but apply an ACL to it. This can be done using the lpProcessAttributes parameter to CreateProcess or CreateProcessAsUser, or with the SetSecurityInfo function. I've never tried this, but it should in theory prevent the user from using task manager to close the process.

If you are creating the process from the user's context, then the user will be the owner, so a sufficiently knowledgeable person could change the permissions back in order to terminate the process. If you need to block this hole, using CreateProcessAsUser from a privileged master process (the token can be duplicated from one of the existing processes in the user's session) should (again, in theory) mean that the user is not the process owner.

Another potential issue: if you listen for messages indicating that the user is logging out (in order to exit) such a message could be faked. If you don't then you need to find some other way of exiting when the user logs out. You may need to experiment here, I'm not sure how the system will react.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文