Если процесс имеет SeRestorePrivilege, он может изменить владельца файла с помощью win32security.SetNamedSecurityInfo
. В соответствии с Windows документацией API ,
SeRestorePrivilege:
заставляет систему предоставлять все права доступа для записи любому файлу независимо от ACL, указанного для файл. Любой запрос доступа, кроме записи, все еще оценивается с помощью ACL. Следующие права доступа предоставляются, если эта привилегия удерживается: WRITE_DA C, WRITE_OWNER, ACCESS_SYSTEM_SECURITY, FILE_GENERIC_WRITE, FILE_ADD_FILE, FILE_ADD_SUBDIRECTORY, DELETE
право доступа ко всем упомянутым правам на все упомянутые права на все упомянутые права , но изменение владельца не выполняется с ошибкой 1307: «Этот идентификатор безопасности не может быть назначен владельцем данного объекта». Почему?
Код:
import ntsecuritycon
import win32security
import win32api
import sys
import os
# grant access rights of SeRestorePrivilege
def simulate_se_restore_privilege(path):
sd = win32security.GetNamedSecurityInfo(path, win32security.SE_FILE_OBJECT, win32security.OWNER_SECURITY_INFORMATION)
owner_sid = sd.GetSecurityDescriptorOwner()
dacl = win32security.ACL()
dacl.SetEntriesInAcl([
{'AccessPermissions': ntsecuritycon.WRITE_DAC
| ntsecuritycon.WRITE_OWNER
| ntsecuritycon.ACCESS_SYSTEM_SECURITY
| ntsecuritycon.FILE_GENERIC_WRITE
| ntsecuritycon.FILE_ADD_FILE
| ntsecuritycon.FILE_ADD_SUBDIRECTORY
| ntsecuritycon.DELETE,
'AccessMode': win32security.GRANT_ACCESS,
'Inheritance': 0,
'Trustee': {
'MultipleTrustee': None,
'MultipleTrusteeOperation': 0,
'TrusteeForm': win32security.TRUSTEE_IS_SID,
'TrusteeType': win32security.TRUSTEE_IS_UNKNOWN,
'Identifier': owner_sid,
}
}
])
win32security.SetNamedSecurityInfo(
path,
win32security.SE_FILE_OBJECT,
win32security.DACL_SECURITY_INFORMATION,
None,
None,
dacl,
None,
)
def enable_se_restore_privilege():
tok = win32security.OpenProcessToken(
win32api.GetCurrentProcess(), win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY
)
luid = win32security.LookupPrivilegeValue(None, win32security.SE_RESTORE_NAME)
new_state = [(luid, win32security.SE_PRIVILEGE_ENABLED)]
win32security.AdjustTokenPrivileges(tok, 0, new_state)
win32api.CloseHandle(tok)
def change_ownership(path):
win32security.SetNamedSecurityInfo(
path,
win32security.SE_FILE_OBJECT,
win32security.OWNER_SECURITY_INFORMATION,
win32security.ConvertStringSidToSid("S-1-0-0"),
None,
None,
None,
)
path = sys.argv[1]
try:
os.unlink(path)
except OSError:
pass
with open(path, "w"):
pass
print("Adding access rights from SeRestorePrivilege")
simulate_se_restore_privilege(path)
try:
change_ownership(path)
except Exception as e:
print(f"Changing ownership failed: {e}")
print("Enabling SeRestorePrivilege")
enable_se_restore_privilege()
change_ownership(path)
print("Changing ownership succeeded")
Вывод в приподнятой консоли:
> python .\chown.py file
Adding access rights from SeRestorePrivilege
Changing ownership failed: (1307, 'SetNamedSecurityInfo', 'This security ID may not be assigned as the owner of this object.')
Enabling SeRestorePrivilege
Changing ownership succeeded