【问题标题】:How to set the owner of a file to SYSTEM?如何将文件的所有者设置为SYSTEM?
【发布时间】:2016-10-25 20:06:04
【问题描述】:

在代码方面,这非常简单:

var fs = IO.File.GetAccessControl(path);
fs.SetOwner(new NTAccount("NT AUTHORITY\\SYSTEM"));
IO.File.SetAccessControl(path, fs);

这会引发一个异常,提示“不允许安全标识符成为此对象的所有者。”

据说这意味着我无权指定此用户为所有者:source 1source 2。但是,我可以很容易地使用资源管理器将此文件的所有者设置为 SYSTEM。既然 Explorer 可以以某种方式做到这一点,我必须拥有必要的权限 - 那么我该如何做 Explorer 所做的并将文件的所有者设置为 SYSTEM?

【问题讨论】:

  • 如何使用 Windows 资源管理器设置 所有者?为新用户/组添加权限(如在.NET 的AddAccessRule 中)不是您可以在资源管理器中做的所有事情吗?根据this,您不能将文件的所有者更改为您自己或管理员组以外的其他人。
  • @Christian.K 属性/安全/高级/所有者/编辑/其他用户和组/键入“系统”/按“确定”。关闭所有内容,再次打开以确保其正常工作。确实如此。
  • 哦,是的,谢谢。经过一些谷歌搜索和参考代码研究。 It looks 好像您需要拥有 SE_TAKE_OWNERSHIP_NAMESE_RESTORE_NAME 权限。否则,您只能将所有者设置为您自己或 BUILTIN\Adminstrations 组。对您的代码进行一些试验似乎可以证明后者。抱歉,我现在没有时间查找/编写 P/Invoke 代码来执行测试所需的 AdjustTokenPrivileges...
  • @Christian.K 谢谢,事实证明这是足够的信息来完成这项工作。单独SE_RESTORE_NAME 就足够了。

标签: .net access-rights windows-security


【解决方案1】:

Christian.K 的帮助下,他将我指向AdjustTokenPrivilegesSE_RESTORE_NAME,所需要做的就是在进程令牌上启用此权限:

// Allow this process to circumvent ACL restrictions
WinAPI.ModifyPrivilege(PrivilegeName.SeRestorePrivilege, true);

// Sometimes this is required and other times it works without it. Not sure when.
WinAPI.ModifyPrivilege(PrivilegeName.SeTakeOwnershipPrivilege, true);

// Set owner to SYSTEM
var fs = IO.File.GetAccessControl(path);
fs.SetOwner(new NTAccount("NT AUTHORITY\\SYSTEM"));
IO.File.SetAccessControl(path, fs);

下面是这种ModifyPrivilege 辅助方法的代码:

static class WinAPI
{
    /// <summary>
    ///     Enables or disables the specified privilege on the primary access token of the current process.</summary>
    /// <param name="privilege">
    ///     Privilege to enable or disable.</param>
    /// <param name="enable">
    ///     True to enable the privilege, false to disable it.</param>
    /// <returns>
    ///     True if the privilege was enabled prior to the change, false if it was disabled.</returns>
    public static bool ModifyPrivilege(PrivilegeName privilege, bool enable)
    {
        LUID luid;
        if (!LookupPrivilegeValue(null, privilege.ToString(), out luid))
            throw new Win32Exception();

        using (var identity = WindowsIdentity.GetCurrent(TokenAccessLevels.AdjustPrivileges | TokenAccessLevels.Query))
        {
            var newPriv = new TOKEN_PRIVILEGES();
            newPriv.Privileges = new LUID_AND_ATTRIBUTES[1];
            newPriv.PrivilegeCount = 1;
            newPriv.Privileges[0].Luid = luid;
            newPriv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;

            var prevPriv = new TOKEN_PRIVILEGES();
            prevPriv.Privileges = new LUID_AND_ATTRIBUTES[1];
            prevPriv.PrivilegeCount = 1;
            uint returnedBytes;

            if (!AdjustTokenPrivileges(identity.Token, false, ref newPriv, (uint) Marshal.SizeOf(prevPriv), ref prevPriv, out returnedBytes))
                throw new Win32Exception();

            return prevPriv.PrivilegeCount == 0 ? enable /* didn't make a change */ : ((prevPriv.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) != 0);
        }
    }

    const uint SE_PRIVILEGE_ENABLED = 2;

    [DllImport("advapi32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool AdjustTokenPrivileges(IntPtr TokenHandle, [MarshalAs(UnmanagedType.Bool)] bool DisableAllPrivileges, ref TOKEN_PRIVILEGES NewState,
       UInt32 BufferLengthInBytes, ref TOKEN_PRIVILEGES PreviousState, out UInt32 ReturnLengthInBytes);

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool LookupPrivilegeValue(string lpSystemName, string lpName, out LUID lpLuid);

    struct TOKEN_PRIVILEGES
    {
        public UInt32 PrivilegeCount;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1 /*ANYSIZE_ARRAY*/)]
        public LUID_AND_ATTRIBUTES[] Privileges;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct LUID_AND_ATTRIBUTES
    {
        public LUID Luid;
        public UInt32 Attributes;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct LUID
    {
        public uint LowPart;
        public int HighPart;
    }
}

enum PrivilegeName
{
    SeAssignPrimaryTokenPrivilege,
    SeAuditPrivilege,
    SeBackupPrivilege,
    SeChangeNotifyPrivilege,
    SeCreateGlobalPrivilege,
    SeCreatePagefilePrivilege,
    SeCreatePermanentPrivilege,
    SeCreateSymbolicLinkPrivilege,
    SeCreateTokenPrivilege,
    SeDebugPrivilege,
    SeEnableDelegationPrivilege,
    SeImpersonatePrivilege,
    SeIncreaseBasePriorityPrivilege,
    SeIncreaseQuotaPrivilege,
    SeIncreaseWorkingSetPrivilege,
    SeLoadDriverPrivilege,
    SeLockMemoryPrivilege,
    SeMachineAccountPrivilege,
    SeManageVolumePrivilege,
    SeProfileSingleProcessPrivilege,
    SeRelabelPrivilege,
    SeRemoteShutdownPrivilege,
    SeRestorePrivilege,
    SeSecurityPrivilege,
    SeShutdownPrivilege,
    SeSyncAgentPrivilege,
    SeSystemEnvironmentPrivilege,
    SeSystemProfilePrivilege,
    SeSystemtimePrivilege,
    SeTakeOwnershipPrivilege,
    SeTcbPrivilege,
    SeTimeZonePrivilege,
    SeTrustedCredManAccessPrivilege,
    SeUndockPrivilege,
    SeUnsolicitedInputPrivilege,
}

【讨论】:

  • 如果你从System.Security.AccessControl.Win32.GetSecurityInfo收到错误UnauthorizedAccessException,试试这个
猜你喜欢
  • 2017-12-14
  • 2013-09-23
  • 2020-01-30
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 2012-06-04
  • 1970-01-01
  • 2013-05-26
相关资源
最近更新 更多