Я пытаюсь установить контроль аудита для ряда файлов (перечисленных в ACLsWin.txt
) находится в \%Windows%\System32
(например, aaclient.dll
) с помощью следующего скрипта Powershell:
$FileList = Get-Content ".\ACLsWin.txt"
$ACL = New-Object System.Security.AccessControl.FileSecurity
$AccessRule = New-Object System.Security.AccessControl.FileSystemAuditRule("Everyone", "Delete", "Failure")
$ACL.AddAuditRule($AccessRule)
foreach($File in $FileList)
{
Write-Host "Changing audit on $File"
$ACL | Set-Acl $File
}
Всякий раз, когда я запускаю скрипт, я получаю сообщение об ошибке PermissionDenied [Set-Acl] UnauthorizedAccessException
.
Похоже, это связано с тем, что владельцем этих файлов является TrustedInstaller
. Я запускаю эти сценарии как администратор (хотя я использую встроенную учетную запись администратора), но все равно не работает. Я могу настроить эти контрольные элементы вручную, используя вкладку «Безопасность», но есть как минимум 200 файлов, выполнение которых вручную может привести к человеческим ошибкам.
Как я могу обойти TrustedInstaller
и установить эти элементы управления аудитом с помощью Powershell?
Единственный поддерживаемый способ изменения файлов, защищенных Windows Resource Protection (которые учетная запись TrustedInstaller является частью WRP), - это использовать службу Windows Module Installer, которая на самом деле является просто способом сказать «вы не можете изменять эти файлы в поддерживаемый способ самостоятельно; только путем установки исправлений и пакетов обновления эти файлы можно изменить поддерживаемым способом ».
В sfc.exe
Утилита также является частью Windows Resource Protection. С помощью sfc.exe
вы можете сказать, что файл был изменен, и он заменит его копией из хранилища WinSxS.
Ты бы иметь чтобы самому стать владельцем этих файлов, прежде чем вы сможете их изменить. Самый простой способ сделать это с помощью takeown.exe
.
Но дело в том, что вы не должны изменять эти файлы.
Разработчики приложений могут использовать SfcIsFileProtected
или SfcIsKeyProtected
API-интерфейсы для проверки, находится ли файл под защитой WRP.
Причина, по которой я не стал бы писать сценарий для кого-то, чтобы сделать это, заключается в том, что изменение этих файлов не поддерживается, а как профессионал я не мог с чистой совестью помочь кому-либо привести его систему в неподдерживаемое состояние. ;) Изменить: Черт, я только что ...
Изменить: если вы все еще настаиваете на его взломе, то технически один вариант - запускать Powershell.exe
используя токен безопасности TrustedInstaller.exe
.
Или, что проще было бы написать сценарий с блоком Try / Catch, и если блок catch запускается [UnauthorizedAccessException]
, затем станьте владельцем файла и повторите попытку.
C:\Windows\system32>takeown /A /F C:\Windows\System32\aaclient.dll
SUCCESS: The file (or folder): "C:\Windows\System32\aaclient.dll" now owned by the administrators group.
Вы также можете отслеживать изменения в этих файлах с помощью драйвера фильтра. Вот как это делают такие вещи, как антивирусные продукты. Но эээ ... это, наверное, больше работы, чем ты хочешь делать в данный момент ...
Отредактируйте еще раз !: О, вы хотите вернуть владельца в TrustedInstaller после этого? Вам нужен SeRestorePrivilege
привилегия для этого.
Скопируйте и вставьте это в. \ Enable-Privilege.ps1:
Function Enable-Privilege
{
param([ValidateSet("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")]$Privilege,
$ProcessId = $pid,
[Switch]$Disable)
$Definition = @'
using System;
using System.Runtime.InteropServices;
public class AdjPriv
{
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public static bool EnablePrivilege(long processHandle, string privilege, bool disable)
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = new IntPtr(processHandle);
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
if(disable)
{
tp.Attr = SE_PRIVILEGE_DISABLED;
}
else
{
tp.Attr = SE_PRIVILEGE_ENABLED;
}
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
}
'@
$ProcessHandle = (Get-Process -id $ProcessId).Handle
$type = Add-Type $definition -PassThru
$type[0]::EnablePrivilege($processHandle, $Privilege, $Disable)
}
В Powershell точка-источник Enable-Privilege.ps1 выглядит так:
PS C:\> . .\Enable-Privilege.ps1
PS C:\> [System.Security.Principal.NTAccount]$TrustedInstaller = "NT SERVICE\TrustedInstaller"
Сохраните текущий ACL:
PS C:\> $ACL = Get-Acl C:\Windows\System32\aaclient.dll
Измените владельца на TrustedInstaller:
PS C:\> $ACL.SetOwner($TrustedInstaller)
Включите SeRestorePrivilege:
PS C:\> Enable-Privilege SeRestorePrivilege
Повторно примените измененный ACL. Это та часть, которая выйдет из строя даже для учетной записи Local System, если вы явно не установите привилегию SeRestorePrivilege:
PS C:\> Set-Acl -Path C:\Windows\System32\aaclient.dll -AclObject $ACL
Я бесстыдно украл функцию Enable-Privilege из этой ветки форума TechNet.