You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows进程权限调整疑问:关闭SE_DEBUG_NAME后仍可删除受限文件

问题分析与解决方案

你的代码无效的核心原因

  • SE_DEBUG_NAME权限和文件删除无关:这个权限仅用于允许进程调试其他进程,和文件系统的读写/删除权限完全不相关。关掉它根本不会影响你删除文件的能力。
  • 管理员身份未被移除:你的进程是用管理员权限启动的,进程令牌里包含管理员组的SID且处于启用状态。就算你关掉个别特权,管理员的高权限身份依然存在,所以你还是能删除普通用户无权操作的文件。

正确的实现思路

要实现「普通权限删除,必要时提权」的逻辑,你需要:

  1. 先检查目标文件夹的权限:用AccessCheck函数验证当前普通用户身份(非管理员身份)是否拥有该文件夹的DELETE权限。
  2. 权限足够时:创建受限令牌移除管理员SID,再用这个令牌启动子进程执行删除操作——已启动的管理员进程无法直接降级自身权限,只能通过低权限子进程实现。
  3. 权限不足时:直接以当前管理员权限执行删除。

关键代码示例(创建受限令牌并启动低权限进程)

#include <windows.h>
#include <iostream>

// 创建受限令牌,移除管理员SID
bool CreateRestrictedToken(HANDLE hOriginalToken, HANDLE& hRestrictedToken)
{
    DWORD dwSidSize = SECURITY_MAX_SID_SIZE;
    BYTE adminSid[SECURITY_MAX_SID_SIZE];
    if (!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, adminSid, &dwSidSize))
    {
        std::cout << "CreateWellKnownSid error: " << GetLastError() << std::endl;
        return false;
    }

    SID_AND_ATTRIBUTES denySids[] = { {adminSid, 0} };
    TOKEN_GROUPS tg;
    tg.GroupCount = 1;
    tg.Groups[0] = denySids[0];

    if (!CreateRestrictedToken(hOriginalToken, RESTRICTED_TOKEN_DISABLE_MAX_PRIVILEGE, 1, denySids, 0, NULL, 0, NULL, &hRestrictedToken))
    {
        std::cout << "CreateRestrictedToken error: " << GetLastError() << std::endl;
        return false;
    }
    return true;
}

// 用受限令牌启动删除文件的子进程
bool DeleteFileWithRestrictedPrivilege(LPCWSTR filePath)
{
    HANDLE hToken;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, &hToken))
    {
        std::cout << "OpenProcessToken error: " << GetLastError() << std::endl;
        return false;
    }

    HANDLE hRestrictedToken;
    if (!CreateRestrictedToken(hToken, hRestrictedToken))
    {
        CloseHandle(hToken);
        return false;
    }

    STARTUPINFOW si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    WCHAR cmdLine[MAX_PATH * 2];
    swprintf_s(cmdLine, L"cmd.exe /c del \"%s\"", filePath);

    if (!CreateProcessWithTokenW(hRestrictedToken, LOGON_WITH_PROFILE, NULL, cmdLine, 0, NULL, NULL, &si, &pi))
    {
        std::cout << "CreateProcessWithTokenW error: " << GetLastError() << std::endl;
        CloseHandle(hRestrictedToken);
        CloseHandle(hToken);
        return false;
    }

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    CloseHandle(hRestrictedToken);
    CloseHandle(hToken);
    return true;
}

int main()
{
    LPCWSTR filePath = L"C:\\Users\\SH0249\\Desktop\\floder\\sample.txt";
    
    // 此处可补充AccessCheck逻辑,验证普通用户权限是否足够
    // 示例中直接尝试低权限删除,失败则用管理员权限重试
    if (!DeleteFileWithRestrictedPrivilege(filePath))
    {
        std::cout << "低权限删除失败,尝试管理员权限删除..." << std::endl;
        if (!DeleteFile(filePath))
        {
            std::cout << "删除失败,错误码: " << GetLastError() << std::endl;
        }
    }

    getchar();
    return 0;
}

补充说明

  • 权限检查实现:需要先用GetFileSecurity获取目标文件夹的安全描述符,再通过ImpersonateSelf+OpenThreadToken构造客户端上下文,最后调用AccessCheck验证DELETE权限。
  • 不要尝试修改当前管理员进程的令牌降级权限,Windows不支持该操作,只能通过受限令牌创建子进程实现低权限操作。

内容的提问来源于stack exchange,提问作者Rookie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 23:55:17