3

A friend of mine works in an organisation and one fine day realised that he has local admin access on his machine. He swear to me that he didn't have the privilege initially and needed to raise requests for installing any software. I verified that their written policy also says so.

Assuming that some privileged domain user added him to local admin group by mistake, how can we find the user who did that?

It would be helpful if I get specific answers on how to check the audit log and identify the user who granted local admin privilege to my friend.

1

The post by @Leo is correct however you may run into performance issues if combing through many events. The ideal approach is to construct a filter specific for what you're looking for. Since the SID for the local administrators group is well-known (S-1-5-32-544), the following XML filter can be used. One can copy/paste this into Event Viewer (Filter Current Log > XML) or use it with PowerShell.

<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[(EventID=4732)]] 
and 
*[EventData[Data[@Name='TargetSid'] and Data='S-1-5-32-544']]
</Select>
</Query>
</QueryList>

To use with PowerShell, set the XML filter to a variable and then run Get-WinEvent.

$xmlFilter = @"
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[(EventID=4732)]] 
and 
*[EventData[Data[@Name='TargetSid'] and Data='S-1-5-32-544']]
</Select>
</Query>
</QueryList>
"@

Get-WinEvent -FilterXml $xmlFilter

Alerting

If you'd like to run some custom action after the occurrence of an event like this, setting up alerts via Scheduled Tasks is possible as I recently posted on my blog - Microsoft Event Log Alerting. Doing so requires two parts:

  1. Setup Scheduled Task
  2. Setup PowerShell Script

Scheduled Task

The following PowerShell commands will setup the Scheduled Task to only trigger when a member is added to BuiltIn\Administrators. Note that many of these configuration settings are not available via the GUI.

# NOTE - ExecutionPolicy set to Unrestricted should only be used for testing.
$Action = New-ScheduledTaskAction -NoLogo `
            -Execute "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" `
            -NoProfile `
            -NonInteractive `
            -WindowStyle Hidden `
            -File .\Security_4732.ps1 -RecordID $(eventRecordID) `
            -ExecutionPolicy Unrestricted' `
            -WorkingDirectory "C:\AlertScripts\"

$Principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" `
            -LogonType ServiceAccount

$Settings = New-ScheduledTaskSettingsSet -DisallowDemandStart `
            -Compatibility Win8 `
            -Hidden `
            -WakeToRun `
            -RunOnlyIfNetworkAvailable `
            -AllowStartIfOnBatteries

$Settings.RunOnlyIfIdle = $FALSE
$Settings.ExecutionTimeLimit = "PT5M"
$Settings.StartWhenAvailable = $TRUE
$Settings.StopIfGoingOnBatteries = $FALSE
$Settings.DisallowStartOnRemoteAppSession = $FALSE
$Settings.DisallowStartIfOnBatteries = $FALSE

# Create Trigger via Security Event ID 4732 & Local Admin Group
$cimTriggerClass = Get-CimClass -ClassName MSFT_TaskEventTrigger `
                -Namespace Root/Microsoft/Windows/TaskScheduler:MSFT_TaskEventTrigger

$Trigger = New-CimInstance -CimClass $cimTriggerClass -ClientOnly

$Trigger.Subscription = @"
<QueryList>
<Query Id="0" Path="Security">
  <Select Path="Security">
  *[System[(EventID=4732)]] 
  and 
  *[EventData[Data[@Name='TargetSid'] and Data='S-1-5-32-544']]
  </Select>
</Query>
</QueryList>
"@
$Trigger.ExecutionTimeLimit = 'PT5M'
$Trigger.Enabled = $TRUE

# Set ValueQueries so the RecordID can be passed to the script
$Trigger.ValueQueries = [CimInstance[]]$(Get-CimClass -ClassName MSFT_TaskNamedValue `
            -Namespace Root/Microsoft/Windows/TaskScheduler:MSFT_TaskNamedValue)

$Trigger.ValueQueries[0].Name = "eventRecordID"
$Trigger.ValueQueries[0].Value = "Event/System/EventRecordID"

Register-ScheduledTask -TaskName "Security_4732" `
            -Description "Run script when user is added to local administrators group." `
            -TaskPath "\AlertScripts\" `
            -Action $Action `
            -Trigger $Trigger `
            -Settings $Settings `
            -Principal $Principal

PowerShell Script

With the Scheduled Task setup, save the following PowerShell code to C:\AlertScripts\Security_4732.ps1. Be sure to customize this for use with your own email. Though really it can be customized however you'd like. Just be sure to only allowed signed scripts when deploying into production which will also require updating the Scheduled Task.

param([int]$RecordID)

$xmlQuery = @"
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">*
[System[(EventRecordID=$($RecordID))]]
</Select>
</Query>
</QueryList>
"@

$triggeredEvent = Get-WinEvent -FilterXml $xmlQuery

Send-MailMessage -To "alert@my-domain.local" -From "$($env:COMPUTERNAME)@my-domain.local" `
                 -SmtpServer "smtp.my-domain.local" `
                 -Subject "User Added to Local Administrators Group" `
                 -Body "RecordID: $($RecordID)`r`n$($triggeredEvent.Message)" `
                 -Priority High

Testing

There have been issues when trying to copy/paste XML queries. Be sure to test thoroughly as I've had seemingly correct queries not even work in Event Viewer. It wasn't until I manually retyped them that they worked again.

Documentation

Microsoft has done a much better job documenting events by providing detailed explanations. The page for this particular event can be found here:

4732(S): A member was added to a security-enabled local group.

Here you'll find the account listed under Subject: is responsible for making this request.

2

You can use Powershell to filter the right events:

Get-EventLog Security -InstanceId 4732 

Heres a powershell command to get all the eventlog entries for which an user was added to local administrators:

Get-EventLog Security -InstanceId 4732 | `
Where-Object {$_.Message -like "*Administrators*"}` 
| Select-Object * 

Sadly I couldn't test the command because I'm at home and don't have access to AD. But you should get an Output like that:

EventID            : 4732
MachineName        : localhost
Data               : {}
Index              : 165325
Category           : (13826)
CategoryNumber     : 13826
EntryType          : SuccessAudit
Message            : A member was added to a security-enabled local group.

                     Subject:
                        Security ID:            SID of the user that added the user to the group.
                        Account Name:           bob
                        Account Domain:         contoso.com
                        Logon ID:               0x59461

                     Member:
                        Security ID:            SID of your friends user account
                        Account Name:           -

                     Group:
                        Security ID:            S-1-5-32-544
                        Group Name:             Administrators
                        Group Domain:           Builtin

                     Additional Information:
                        Privileges:             -
                        Expiration time:                %11
Source             : Microsoft-Windows-Security-Auditing
ReplacementStrings : {-, some sid, Users, Builtin...}
InstanceId         : 4732
TimeGenerated      : 26.01.2017 21:08:49
TimeWritten        : 26.01.2017 21:08:49
UserName           :
Site               :
Container          :

Maybe you need to change some stuff in my script, but you should have all the information, to find the admin.

Edit: Changed my powershell command. It still needs a filter to search for the individual user.

  • Hey @Leo The command didn't work but I found the corresponding event log from event viewer. In the subject section the Security ID is 'SYSTEM' and the account name is the user name of my friend. – hax Jan 26 '17 at 20:42
  • 1
    @hax Sorry, I messed up my script I changed it to just get the eventlog entries. The SYSTEM is the Computer Account in the AD, so it probably was a GPO. – Leo Jan 26 '17 at 20:48
  • Note that the first PowerShell query will get all EventID=4732. If a user was added to a different local group such as Power Users it will be included. The second query is doing a string search for Administrators which is fine for adhoc or small record sets where each returned event will be manually reviewed. The concern is the string Administrators could appear elsewhere in the message. – user2320464 Aug 25 '17 at 21:01
  • So the thing about this answer, is SYSTEM adding somebody to a group is what a GPO add looks like but also what an online breach looks like. (An offline breach doesn't log anything except a system startup event.) – Joshua Jul 22 '18 at 21:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.