python - 使用 Python 在 Windows 上获取目录所有权会导致 "Access denied"错误

标签 python windows security file-permissions ownership

我正在尝试使用以下代码获取目录的所有权:

sd = win32security.SECURITY_DESCRIPTOR()
sd.SetSecurityDescriptorOwner(curUser, False)
win32security.SetFileSecurity("C:/ProgramData/Test", 
    win32security.OWNER_SECURITY_INFORMATION, sd)

SetFileSecurity 调用失败并出现“访问被拒绝”错误。

当前用户的访问权限已从此目录中删除。在资源管理器中我可以看到它,但是当我尝试打开它时,我首先必须以管理员身份获得所有权。这在资源管理器中有效,但是上面的代码是使用提升的权限执行的,并且由于某种原因它仍然失败。有什么建议吗?

最佳答案

您可以通过启用 SeTakeOwnerShipPrivilege 来强制取得所有权,但当然前提是您的访问 token 具有此权限(例如提升的管理员)。此外,您还可以通过启用 SeRestorePrivilege 强制将所有权分配给另一个安全主体,例如 SYSTEM。如果没有后者,分配可能会失败并出现错误代码 ERROR_INVALID_OWNER

以下 set_file_owner 函数有一个 force 选项,尝试临时启用这两种权限。

import win32api
import win32security

def set_file_owner(path, sid=None, force=False):
    try:
        hToken = win32security.OpenThreadToken(win32api.GetCurrentThread(),
                    win32security.TOKEN_ALL_ACCESS, True)
    except win32security.error:
        hToken = win32security.OpenProcessToken(win32api.GetCurrentProcess(),
                    win32security.TOKEN_ALL_ACCESS)
    if sid is None:
        sid = win32security.GetTokenInformation(hToken,
                win32security.TokenOwner)
    prev_state = ()
    if force:
        new_state = [(win32security.LookupPrivilegeValue(None, name),
                      win32security.SE_PRIVILEGE_ENABLED)
                        for name in (win32security.SE_TAKE_OWNERSHIP_NAME,
                                     win32security.SE_RESTORE_NAME)]
        prev_state = win32security.AdjustTokenPrivileges(hToken, False,
                        new_state)
    try:
        sd = win32security.SECURITY_DESCRIPTOR()
        sd.SetSecurityDescriptorOwner(sid, False)
        win32security.SetFileSecurity(path, 
            win32security.OWNER_SECURITY_INFORMATION, sd)
    finally:
        if prev_state:
            win32security.AdjustTokenPrivileges(hToken, False, prev_state)

def get_file_owner(path):
    sd = win32security.GetFileSecurity(path,
            win32security.OWNER_SECURITY_INFORMATION)
    sid = sd.GetSecurityDescriptorOwner()
    return win32security.LookupAccountSid(None, sid)

示例

if __name__ == '__main__':
    import os
    import tempfile
    import subprocess

    username = os.environ['UserName']
    test_path = tempfile.mkdtemp()
    print('Test path: {}'.format(test_path))
    subprocess.call(['icacls.exe', test_path, '/setowner', 'SYSTEM'],
                     creationflags=8)
    owner = get_file_owner(test_path)
    print('Initial owner: {}\\{}'.format(owner[1], owner[0]))
    try:
        print('Denying write owner access')
        subprocess.call(['icacls.exe', test_path, '/deny',
                         '{}:(WO)'.format(username)], creationflags=8)
        try:
            set_file_owner(test_path)
        except win32security.error:
            print('Trying with force=True')
            try:
                set_file_owner(test_path, force=True)
            except win32security.error:
                pass
    finally:
        owner = get_file_owner(test_path)
        print('Final owner: {}\\{}'.format(owner[1], owner[0]))
        os.rmdir(test_path)

输出

Test path: C:\Users\eryksun\AppData\Local\Temp\tmpizgemrdz
Initial owner: NT AUTHORITY\SYSTEM
Denying write owner access
Trying with force=True
Final owner: BUILTIN\Administrators

关于python - 使用 Python 在 Windows 上获取目录所有权会导致 "Access denied"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41081263/

相关文章:

windows - PowerShell 中的复制项;不支持给定路径的格式

c++ - 以编程方式获取主机的 DNS IPv6 服务器

security - Struts2 + 类加载器漏洞 + 如何重现

python - 无法使用 pyenv ipython 笔记本导入 matplotlib

python - 结构错误 找不到记录器 "paramiko.transport"的处理程序

c# - 在 Windows 中检测耳机

javascript - 如何检查文件名字符串不是文件路径

android - Android 的 Crashwrangler 或 !exploitable 等价物

python - 打开大结果 mat-File 会引发缓冲区对于请求的数组来说太小

python - 如何使用带有 python 的 Selenium 下载 HTML 网页?