【问题标题】:Deny Access to Kiosk program process拒绝访问 Kiosk 程序流程
【发布时间】:2011-07-19 19:08:20
【问题描述】:

我有一个自助服务终端应用程序,必须始终禁用任务管理器以防止用户关闭程序
但是有些用户需要TaskManager来关闭挂起的程序。

任何帮助都会被占用。

但是,我确信 Windows 中有一个功能可以防止关闭程序的进程,就像试图杀死 rundll.exe 进程一样。如果我可以用DllImport 调用它,我想知道该函数

任何人都可以帮忙吗?
黑客?
一个函数?
还有其他解决方案吗?

编辑:

至少如果没有办法阻止进程被关闭,我需要一种方法将其隐藏在任务管理器中出现的进程列表中。

编辑 2: 目前还没有找到解决办法

【问题讨论】:

  • 作为替代方案,您可以随时禁用任务管理器
  • @Wiiliam 不太清楚,有些程序是不能通过TaskManager关闭的,比如安全甚至有些病毒
  • @Mr.DDD 这些通常只是通过拦截返回进程列表的低级操作系统函数来从任务管理器中隐藏进程——仍然可以杀死它们。
  • 您是担心有人意外关闭它,还是试图防范有人恶意关闭它?
  • 与其阻止关闭,为什么不在强制关闭时重新启动?如果 Kiosk 挂起,阻止用户终止 Kiosk 可能会阻止他们重新启动它。还有很多方法可以杀死您必须避开的进程,并且重新启动应用程序非常简单。

标签: c# c++ windows kiosk win32-process


【解决方案1】:

如果您可以在管理上下文中访问进程 ID,则一种方法是拒绝最终用户对该进程的 PROCESS_TERMINATE 权限。终止进程(通过任务管理器或其他上下文)默认授予所有者,但可以明确拒绝。当它被拒绝时,终止进程将需要所有者手动更改 ACL,然后终止进程。如果用户既不是管理员也不是进程的所有者,他将无法强制终止进程(例如,通过任务管理器),但允许进程正常退出。

以下代码将显式拒绝 ACE 放在 PID processid 的进程上,用于所有人组的成员。

#include "Aclapi.h"
#include "Sddl.h"
DWORD RestrictTerminateOnProcessId(DWORD processid)
{
    PACL dacl = NULL, newdacl = NULL;
    HANDLE ph = NULL;
    PSECURITY_DESCRIPTOR* desc = NULL;
    PSID everyonesid = NULL;
    ph = OpenProcess(WRITE_DAC | READ_CONTROL, false, processid);
    if (!ph) goto cleanup;

    if (ERROR_SUCCESS != GetSecurityInfo(ph,
            SE_KERNEL_OBJECT,
            DACL_SECURITY_INFORMATION,
            NULL,
            NULL,
            &dacl,
            NULL,
            desc)) goto cleanup;

    SID_IDENTIFIER_AUTHORITY WorldAuth = SECURITY_WORLD_SID_AUTHORITY;
    if (!AllocateAndInitializeSid(
            &WorldAuth,1,SECURITY_WORLD_RID,
            0,0,0,0,0,0,0,&everyonesid)) goto cleanup;

    // begin copy dacl
    _ACL_SIZE_INFORMATION si;
    GetAclInformation(dacl,
            &si,
            sizeof(si),
            AclSizeInformation);

    DWORD dwNewAclSize = si.AclBytesInUse +
            (2*sizeof(ACCESS_DENIED_ACE)) + (2*GetLengthSid(everyonesid)) -
            (2*sizeof(DWORD));

    newdacl = (PACL)HeapAlloc(
            GetProcessHeap(),
            HEAP_ZERO_MEMORY,
            dwNewAclSize);

    if (newdacl == NULL) goto cleanup;

    if (!InitializeAcl(newdacl, dwNewAclSize, ACL_REVISION_DS))
            goto cleanup;

    if (!AddAccessDeniedAce(newdacl,
            ACL_REVISION_DS,
            PROCESS_TERMINATE,
            everyonesid)) goto cleanup;

    for (int i = 0; i < si.AceCount; i++)
    {
            LPVOID pace = NULL;
            if (!GetAce(dacl, i, &pace)) goto cleanup;
            if (!AddAce(newdacl, ACL_REVISION_DS,
                    MAXDWORD, pace, ((PACE_HEADER)pace)->AceSize))
                    goto cleanup;
    }

    // end copy dacl

    if (!SetSecurityInfo(ph,
            SE_KERNEL_OBJECT,
            DACL_SECURITY_INFORMATION,
            NULL,
            NULL,
            newdacl,
            NULL)) goto cleanup;
     SetLastError(0);

cleanup:
    DWORD ret = GetLastError();
    if (desc) LocalFree(desc);
    if (newdacl) HeapFree(GetProcessHeap(), 0, (LPVOID)newdacl);
    if (ph) CloseHandle(ph);
    if (everyonesid) FreeSid(everyonesid);
    return !ret;
}

【讨论】:

    【解决方案2】:

    您可以创建一个在启动时运行的服务。然后monitors when the user logs 进入并启动您的程序。从那里你有两个选择:

    1. 让它等待程序并在用户会话持续时恢复它。
    2. 在管理员帐户下运行它,并确保用户始终在受限帐户上运行。 Windows 的特权执行应该确保您的程序不死。

    如果您必须授予用户管理权限(因此他们可以杀死您的服务),请确保注册您的服务,以便 SCM restarts it automatically

    如 mdm 所说,除此之外的任何事情都需要一些内核黑客攻击,或者潜入 rootkit 领域。我建议你避免。

    如果您仍然在运行 Windows XP,而不是系统服务,您可以注册 Winlogon notification package。它们基本上是无法杀死的,因为它们在 winlogon.exe 的上下文中运行,这就是它们在 Vista 及更高版本中为 removed 的原因。

    【讨论】:

      【解决方案3】:

      正确的做法是:

      为 Kiosk 应用程序创建一个用户。让我们说 KioskUser 创建在计算机中执行操作的其他用户。假设用户1 他们都不应该是管理员。他们不需要是管理员吗?他们当然可以拥有特权。

      您将照常使用 User1 帐户。 然后,您以 KioskUser 身份运行 Kiosk 应用程序。 (使用 runas 命令) - 将应用程序添加到会话并使其可见(有关更多信息,请参阅参数)

      当 User1 登录并且 Kiosk 应用程序从 KioskUser 运行时,User1 无法终止进程。

      我不建议“破解”系统,也不建议更改注册表。 此外,您可以将 Kiosk 应用程序设为服务,并在 Kiosk 用户下运行。

      【讨论】:

        【解决方案4】:

        听起来您无法阻止进程被杀死 - 请参阅 this question,特别是 link posted to an explanation

        但是,您可以阻止用户从任务栏打开任务管理器(右键单击 -> 打开任务管理器)、按 Ctrl-Shift-Esc 或使用以下注册表项在命令提示符处键入 taskman

        HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableTaskMgr 
        

        设置为 1 禁用任务管理器,设置为 0 再次启用。

        在命令提示符下,像这样禁用它:

        reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 1 /f
        

        你可以用这个命令重新启用:

        reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System /v DisableTaskMgr /t REG_DWORD /d 0 /f
        

        您还需要找到一种方法来阻止用户在注册表中写入此键 - 尽管在我的 Windows 7 64 位计算机上,我必须先打开管理命令提示符才能更改键。

        编辑

        按照 cmets 中的建议,您可以拦截低级系统调用来更改报告的进程列表。 This answer 逃避它,您基本上必须编写一个内核模式 rootkit - 可能实现为设备驱动程序。由于在 Vista 及更高版本中进行了内核更改,这可能仅适用于 Windows XP 及更低版本。可以,但是,我的一个朋友为他的 BSc 毕业论文创建了一个原型。

        您还必须考虑查询进程的其他方法 - IIRC NtQuerySystemInformation 不是可以枚举进程的唯一方法。

        【讨论】:

        • 谢谢,但我已经知道如何关闭任务管理器了。我只是想要一种方法来防止进程被杀死。
        【解决方案5】:

        使用一些您无法使用的 rootkit/驱动程序来保护您的 Kiosk 应用程序的不足...尽管在这种情况下您需要使用的方法是“类似恶意软件的”,所以要小心...

        在这里http://blogs.msdn.com/b/oldnewthing/archive/2004/02/16/73780.aspx,您一方面可以看到为什么这是一项实际上不可能完成的任务,另一方面您可以看到几种可能性……这将是:

        拒绝 PROCESS_TERMINATE
        拒绝 PROCESS_CREATE_THREAD
        拒绝 PROCESS_VM_WRITE
        拒绝 PROCESS_SUSPEND_RESUME
        再加上您可以针对调试器采取的任何防御措施——另一项非常棘手的工作。

        【讨论】:

          【解决方案6】:

          很抱歉没有将此作为评论发布(没有足够的声誉)。 我正在使用 drfs 解决方案,但使用 GetSecurityInfo 的方式似乎会导致内存泄漏。我更改了代码并像这样摆脱了内存泄漏:

          声明:

          PSECURITY_DESCRIPTOR desc = NULL;
          

          初始化:

          desc = (PSECURITY_DESCRIPTOR)GlobalAlloc(GMEM_FIXED,  sizeof(PSECURITY_DESCRIPTOR));
          

          清理:

          if (desc) GlobalFree(desc);
          

          呼叫:

          GetSecurityInfo(ph, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &desc)
          

          我也找到了这篇关于这个问题的文章:http://i1.blogs.msdn.com/b/oldnewthing/archive/2012/12/12/10376639.aspx

          【讨论】:

            【解决方案7】:

            虽然您无法阻止授权用户终止您的进程,但您可以阻止用户拥有终止您的进程所需的权限。也就是说,本地管理员将始终有权终止任何进程。您希望防止任何用户或非管理员关闭您的应用程序吗?如果是前者,只需在专用用户帐户下运行该进程就足够了。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-11-02
              • 2013-10-31
              • 2011-12-26
              • 1970-01-01
              • 1970-01-01
              • 2016-06-04
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多