Windows Audit Part 4: Tracing file deletions in MS PowerShell

Three years ago I posted a series of articles on Windows auditing using MS Log Parser; the last article was named “Windows Audit Part 3: Tracing file deletions”

Now, when the MS PowerShell is widely used among many operating systems for various purposes, I think it would be pertinent to rewrite that article using PowerShell scripts instead of Log Parser’s commands. So I won’t change the “theory part” of the previous post and will just publish PS scripts and the corresponding results instead of those in Windows Audit Part 3.

Here’s how we can parse Security logs using MS PowerShell.

The task:

To find out ‘what, by whom, when and at what location” was deleted.

(on the example of Windows Server 2012 R2)

Prerequisites:  First of all we should enable “Object Access” audit with “File System”,  “File Share” and “Handle Manipulation” subcategories (Win2008/2012) or just  “File System” category for Win2003.

Let’s consider this scheme:
(upper event id-s are for Win2008-Win2012R2, lower ones are for Win2003)

deletion2

I An object was deleted from the shared folder (“Network deletion”)

1-1)   Network Logon (pay attention to user name, workstation, Logon ID)

1-2)   Share Folder Access (only for Win2008)

2-1)   Open Handle ID  – e.g.  a file is open.
(pay attention to the list (*) of user permissions for the object and Logon ID.)

2-2)   Registration of the exercised “DELETE” permission** (0x10000)
(the empty “Process/Image File Name” field means “network deletion”)

2-3)   Object deletion
(the name of the deleted object might be  known from 2-2  or from 2-1 by its Handle ID).

2-4)  Handle ID Close – e.g. the file is closed.

3)    Network logoff (with the same Logon ID as in 1-1).

 

II An object was deleted locally  (“Local deletion”)

2-1)    Open Handle ID  – e.g.  a file is open.
(pay attention to the list (*) of user permisions for the object and Logon ID.)

2-2)    Registration of the exercised  “DELETE” permission** (0x10000)
(the “Process/Image File Name” field will show the application by wich the object was deleted. )

2-3)    Object deletion
(the name of the deleted object might be  known from 2-2
or from 2-1 by its Handle ID).

2-4)    Handle ID Close – e.g. the file is closed.

*: permissions mentioned here mean what user CAN do but not necessary WILL do!

**: this permission has been realy exercised.

Note: As the “network” deletions “contain” the events  for the local deletions I’ll post the answers in the reverse order.

 

Answer I – File(s) deleted locally

Note1:    For future use I prefer to save the PS output to a text file,
for instance to D:\Reports.

Note2: On my test server I have enabled object access auditing for the two folders: C:\Audit and D:\Reports.

I-a) We’ll get started by finding out if there was any file deletion:

#
# STEP I-a in auditing file deletions
#
# Finding out if there were any object deletions – events 4660
#
# Author: Michael Firsov
cls

Write-Output “TimeCreated, EventID, User, Domain, LogonID, HandleID” > D:\Reports\Deletion1-a.txt

$events = Get-WinEvent -FilterHashTable @{Logname=’Security’;ID=4660}

foreach ($event in $events) {

$event2=new-object psobject -Property @{
TimeCreated = $event.TimeCreated
EventID = $event.Id
User = $event.Properties[1].Value
Domain = $event.Properties[2].Value
LogonID = $event.Properties[3].Value
HandleID = $event.Properties[5].Value
}

Write-Output “$($event2.TimeCreated), $($event2.EventId), $($event2.User), $($event2.Domain), $($event2.LogonID), $($event2.HandleID)” >> D:\Reports\Deletion1-a.txt
}

PS1-a

The result (for the sake of readability I’ve formatted the column names a bit):1-a

I-b) Then we should find out what exactly was deleted, when and by whom:  (note that LogonID and HandleID should be the same as in the previous output)

#
# STEP I-b in auditing object deletions
#
# Determining what objects were deleted – events 4663 + AccessMask = 65536 (0x10000) – “OBJECT DELETED”
#
# Author: Michael Firsov
cls

Write-Output “TimeCreated, EventID, USER, Domain, LogonID, ObjectName, HandleID, ProcessName, AccessMASK” > D:\Reports\Deletion1-b.txt

$event0 = Get-WinEvent -FilterHashTable @{Logname=’Security’;ID=4663}

$events = $event0 | Select |Where {$_.Properties[9].Value -eq 65536}

foreach ($event in $events) {

$event2=new-object psobject -Property @{
TimeCreated = $event.TimeCreated
EventID = $event.Id
User = $event.Properties[1].Value
Domain = $event.Properties[2].Value
LoginID = $event.Properties[3].Value
ObjectName = $event.Properties[6].Value
HandleID = $event.Properties[7].Value
ProcessName = $event.Properties[11].Value
AccessMASK = $event.Properties[9].Value
}

Write-Output “$($event2.TimeCreated), $($event2.EventId), $($event2.User), $($event2.Domain), $($event2.LoginID), $($event2.ObjectName), $($event2.HandleID), $($event2.ProcessName), $($event2.AccessMASK)” >> D:\Reports\Deletion1-b.txt
}

PS1-b

The result:1-bYes, I did a lot of testing and there’s lots of deleted files: you can see that all of them (strictly speaking the ones that can be shown in this Notepad window) have been deleted localy (as defined by the Process Name field = C:\Windows\explorer.exe).

Attention! Second to last row shows Process Name field =C:\Windows\System32\mmc.exe – I’ll explain it in the end of the article! *

The answer I:

a) User ‘michael’ deleted LOCALLY a number of files (the list is included) from D:\Reports. Date/Time of file deletions: …07/14/2015 02:32:19 – 03:46:18 (NOT all of them fitted to the Deletion1-b.txt image)

b) User ‘jane’ deleted two files on 07/13/2015 at 06:36:41 and 06:41:13 – what files have been deleted and from which workstation we’ll discuss in Answer II

 

Answer II – File(s) deleted from a network share

Note: The first two steps in tracing local and network deletions are the same.

II-a = I-a) Once again we get started by finding out if there was any file deletion:

#
# STEP I-a in auditing file deletions
#
# Finding out if there were any object deletions – events 4660
#
# Author: Michael Firsov
cls

Write-Output “TimeCreated, EventID, User, Domain, LogonID, HandleID” > D:\Reports\Deletion1-a.txt

$events = Get-WinEvent -FilterHashTable @{Logname=’Security’;ID=4660}

foreach ($event in $events) {

$event2=new-object psobject -Property @{
TimeCreated = $event.TimeCreated
EventID = $event.Id
User = $event.Properties[1].Value
Domain = $event.Properties[2].Value
LogonID = $event.Properties[3].Value
HandleID = $event.Properties[5].Value
}

Write-Output “$($event2.TimeCreated), $($event2.EventId), $($event2.User), $($event2.Domain), $($event2.LogonID), $($event2.HandleID)” >> D:\Reports\Deletion1-a.txt
}

PS1-a

Of cource the output is the same as in I-a:2-a…but this time I’d like to know what files/folders have been deleted by user ‘jane’:

 

II-b = I-b) Then we should find out what exactly was deleted, when and by whom:  (note that LogonID and HandleID should be the same as in the previous output)

#
# STEP I-b in auditing object deletions
#
# Determining what objects were deleted – events 4663 + AccessMask = 65536 (0x10000) – “OBJECT DELETED”
#
# Author: Michael Firsov
cls

Write-Output “TimeCreated, EventID, USER, Domain, LogonID, ObjectName, HandleID, ProcessName, AccessMASK” > D:\Reports\Deletion1-b.txt

$event0 = Get-WinEvent -FilterHashTable @{Logname=’Security’;ID=4663}

$events = $event0 | Select |Where {$_.Properties[9].Value -eq 65536}

foreach ($event in $events) {

$event2=new-object psobject -Property @{
TimeCreated = $event.TimeCreated
EventID = $event.Id
User = $event.Properties[1].Value
Domain = $event.Properties[2].Value
LoginID = $event.Properties[3].Value
ObjectName = $event.Properties[6].Value
HandleID = $event.Properties[7].Value
ProcessName = $event.Properties[11].Value
AccessMASK = $event.Properties[9].Value
}

Write-Output “$($event2.TimeCreated), $($event2.EventId), $($event2.User), $($event2.Domain), $($event2.LoginID), $($event2.ObjectName), $($event2.HandleID), $($event2.ProcessName), $($event2.AccessMASK)” >> D:\Reports\Deletion1-b.txt
}

PS1-b

Here’s the rest of the output:1-b-Net

Now I see user ‘jane’ has deleted C:\Audit\Test1.txt and C:\Audit\Ipconfig.txt. You can make sure these are the files mentioned in the 4660 events by comparing the respective HandleIDs (4072 and 4156) – they are the same as in the 4660 and 4663 events.

As the field  ProcessName  is empty we know there was what I call a “network deletion” and the next step is to find out from what workstation the deletion has occurred.

 

II-c) Determining from which workstation the deletion has occurred

At first we should search for the network logon event (4624) with the same LogonID – 232168502 (0×DD69C36) as in the events 4660 and 4663  – in this case both deletions occured during the same logon session (please pay attention to the fact that PowerShell displays LogonID in decimal notation while Event Log displays it in hexadecimal notation):

#
# STEP II-c in auditing object deletions
#
# Determining from which workstation has the network deletion occured – events 4624 + LogonID from the events 4660 and 4663
#
# Author: Michael Firsov
cls

Write-Output “TimeCreated, EventID, USER, Domain, LogonID, LogonTYPE, ClientAddress” > D:\Reports\Deletion2-c.txt

$events = Get-WinEvent -FilterHashTable @{Logname=’Security’;ID=4624}

foreach ($event in $events) {

$event2=new-object psobject -Property @{
TimeCreated = $event.TimeCreated
EventID = $event.Id
User = $event.Properties[5].Value
Domain = $event.Properties[6].Value
LogonID = $event.Properties[7].Value
LogonTYPE = $event.Properties[8].Value
ClientAddress = $event.Properties[18].Value
}
if ($event2.LogonID -eq 232168502) {

Write-Output “$($event2.TimeCreated), $($event2.EventId), $($event2.User), $($event2.Domain), $($event2.LogonID), $($event2.LogonTYPE), $($event2.ClientAddress)” >> D:\Reports\Deletion2-c.txt
}
}

PS2-c

The output:Ic-FormattedAs we see user ‘jane’ connected to the server from the workstation with the IP = 10.1.1.239

 

II-d) Determining wich shared folder ‘jane’ was accessing

In this script I’ll use the same LogonID – 232168502 and the $event2.SHARE -ne ‘\\*\IPC$ expression to rule out displaying IPC$ share.

#
# STEP II-d in auditing object deletions
#
# Determining the SHARE from wich the object has been deleted – event 5140
#
# Author: Michael Firsov
cls

Write-Output “TimeCreated, EventID, USER, Domain, LogonID, SourceIP, SHARE” > D:\Reports\Deletion2-dF.txt

$events = Get-WinEvent -FilterHashTable @{Logname=’Security’;ID=5140}

foreach ($event in $events) {

$event2=new-object psobject -Property @{
TimeCreated = $event.TimeCreated
EventID = $event.Id
User = $event.Properties[1].Value
Domain = $event.Properties[2].Value
LogonID = $event.Properties[3].Value
SourceIP = $event.Properties[5].Value
SHARE = $event.Properties[7].Value
}
if ($event2.LogonID -eq 232168502 -and $event2.SHARE -ne ‘\\*\IPC$’) {

Write-Output “$($event2.TimeCreated), $($event2.EventId), $($event2.User), $($event2.Domain), $($event2.LogonID), $($event2.SourceIP), $($event2.SHARE)” >> D:\Reports\Deletion2-dF.txt
}
}

PS2-d

The output:IId-F
And the last step:

 

II-e) Determining the time of user’s log off

#
# STEP II-e in auditing object deletions
#
# Determinig the client LOG oFF time – Event 4634
#
# Author: Michael Firsov
cls

Write-Output “TimeCreated, EventID, USER, Domain, LogonID, LogonTYPE” > D:\Reports\Deletion2-e.txt

$events = Get-WinEvent -FilterHashTable @{Logname=’Security’;ID=4634}

foreach ($event in $events) {

$event2=new-object psobject -Property @{
TimeCreated = $event.TimeCreated
EventID = $event.Id
User = $event.Properties[1].Value
Domain = $event.Properties[2].Value
LogonID = $event.Properties[3].Value
LogonTYPE = $event.Properties[4].Value
}
if ($event2.LogonID -eq 232168502) {

Write-Output “$($event2.TimeCreated), $($event2.EventId), $($event2.User), $($event2.Domain), $($event2.LogonID), $($event2.LogonTYPE)” >> D:\Reports\Deletion2-e.txt
}
}

PS2-e(Please don’t forget to change the LogonID to your own value!)

The result:IId-E

The complete answer 2:

User ‘jane’ made a connection to the shared folder \\HOST2\Audit  (event 5140) at 06:36:29 on 13/07/2015  (event 4624), deleted the file Test1.txt at 06:41:13, then the file IPconfig.txt at 06:36:41 (event 4660, 4663).  The session of user ‘jane’ was ended at 06:41:32 on 07/13/2015 (event 4634).

You can download all the scripts here: SCRIPTS.docx

Here should have been the end of the article… but there was something  strange in the Deletion1-b.txt image I promissed to explain so  let’s get back to the step I-b. As I’ve already said a file/folder can be deleted either locally – it’s defined as Process Name = C:\Windows\explorer.exe – or by accessing a shared folder – that’s defined as an empty Process Name field. I have never seen any other values for the Process Name field…and don’t know how to interprit Process Name = C:\Windows\System32\mmc.exe or C:\Windows\System32\notepad.exe. The combination of the Process Name field = mmc.exe/notepad.exe and the Access Mask =0x10000 (65536) should mean these programs (mmc and notepad) have deleted the respective files – for example, D:\Reports\Deletion1-a-ARTICLE.txt(deleted by Notepad.exe) or D:\ARTICLE-LOG.evtx (deleted by mmc). I don’t know how it can be possible. And that is not the main question that arises here – worst of all that those files have never been deleted! For example, here are the steps that led to the D:\ARTICLE-LOG.evtx “deletion”:

1) I open Event Log console, navigate to the Security log

2) Right-click it, navigate to “Save all events” and save the Security log to the D:\ARTICLE-LOG.evtx.

That’s all – I’ve never tried to delete it as well I’ve never even opened it.

Q2…but here’s the 4363 event with the exercised “DELETE” permission:

Q1

This problem (or two problems) leads us to the following conclusion: the whole process of parsing security logs described in this article has no meaning: unless the log can guarantee the accuracy of information it won’t be of much use to parse it.

I very much hope that there’s some explanation to this and is opening a case with MS regarding it. I will update this post as soon as I have any new information on the matter.

As it turned out MS MSDN Professional support can’t answer such questions so I published a new post regarding this problem  here: Windows Audit Part 5: Problems in tracing file deletions.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: