Step 1: Turn on File Editing

Here is how to check for effective local group policy with respect to file auditing:

PS C:\> auditpol /get /category:*
System audit policy
Category/Subcategory                      Setting
System
  Security System Extension               No Auditing
  System Integrity                        No Auditing
  IPsec Driver                            No Auditing
  Other System Events                     No Auditing
  Security State Change                   No Auditing
Logon/Logoff
  Logon                                   No Auditing
  Logoff                                  No Auditing
  Account Lockout                         No Auditing
  IPsec Main Mode                         No Auditing
  IPsec Quick Mode                        No Auditing
  IPsec Extended Mode                     No Auditing
  Special Logon                           No Auditing
  Other Logon/Logoff Events               No Auditing
  Network Policy Server                   No Auditing
  User / Device Claims                    No Auditing
  Group Membership                        No Auditing
Object Access
  File System                             Success and Failure
  Registry                                No Auditing
  Kernel Object                           No Auditing
  SAM                                     No Auditing
  Certification Services                  No Auditing
  Application Generated                   No Auditing
  Handle Manipulation                     Success and Failure
  File Share                              Success and Failure
  Filtering Platform Packet Drop          No Auditing
  Filtering Platform Connection           No Auditing
  Other Object Access Events              No Auditing
  Detailed File Share                     Success and Failure
  Removable Storage                       No Auditing
  Central Policy Staging                  No Auditing
Privilege Use
  Non Sensitive Privilege Use             No Auditing
  Other Privilege Use Events              No Auditing
  Sensitive Privilege Use                 No Auditing
Detailed Tracking
  Process Creation                        No Auditing
  Process Termination                     No Auditing
  DPAPI Activity                          No Auditing
  RPC Events                              No Auditing
  Plug and Play Events                    No Auditing
  Token Right Adjusted Events             No Auditing
Policy Change
  Audit Policy Change                     Success and Failure
  Authentication Policy Change            No Auditing
  Authorization Policy Change             Success and Failure
  MPSSVC Rule-Level Policy Change         No Auditing
  Filtering Platform Policy Change        No Auditing
  Other Policy Change Events              No Auditing
Account Management
  Computer Account Management             No Auditing
  Security Group Management               No Auditing
  Distribution Group Management           No Auditing
  Application Group Management            No Auditing
  Other Account Management Events         No Auditing
  User Account Management                 No Auditing
DS Access
  Directory Service Access                No Auditing
  Directory Service Changes               No Auditing
  Directory Service Replication           No Auditing
  Detailed Directory Service Replication  No Auditing
Account Logon
  Kerberos Service Ticket Operations      No Auditing
  Other Account Logon Events              No Auditing
  Kerberos Authentication Service         No Auditing
  Credential Validation                   No Auditing

 

Enabling File Auditing via CLI method:

# Sample commands

# Enable Audit Accessing of files and folders
auditpol /set /category:"Object Access" /success:enable
auditpol /set /category:"Object Access" /failure:enable

# Audit logon and logoff events
auditpol /set /category:"Logon/logoff" /failure:enable
auditpol /set /category:"Logon/logoff" /success:enable

GUI method:

Run: GPEDIT.MSC > Computer Configuration > Security Settings > Local Policies > Audit Policy > double-click ‘Audit object access’ > put check marks next to ‘Success’ and ‘Failures’ > OK > repeat for ‘Audit logon events’ if desired

Navigate to Configuration > Windows Settings > Security Settings > Advanced Audit Policy Configuration > config the following settings according to the business requirements:

Category Sub category Audit Events Purpose
Object Access
  • Audit File System
  • Audit File Share
  • Audit Handle Manipulation
  • Success, Failure
  • Success
  • Success, Failure
  • File share auditing
Policy Change
  • Audit Policy Change
  • Authorization Policy Change
  • Success, Failure
  • Success
  • File permission change auditing
Step 2: Apply Audit Policy to Shared Folders

Run: explorer.exe > navigate to Shared folder > right-click folder and select Properties > click on Security tab > Advanced

Click on Auditing tab > if the Auditing entries are empty, click Add

Set Principle as ‘everyone’ > Applies to ‘This folder, subfolders and files’ > insert check marks next to ‘Read & execute’, ‘List folder contents’, and ‘Read’ > OK

Click OK or Continue to bypass these warnings

Step 3: Test

Logon to SMB Server to check event log (eventvwr.exe) > navigate to Windows Logs > right-click Security > Filter current log >  input value ‘5140’, as shown in the list below, into the Event IDs field > OK

SMB Access Event IDs List:

5140(S, F): A network share object was accessed.
5142(S): A network share object was added.
5143(S): A network share object was modified.
5144(S): A network share object was deleted.
5145(S): A network share object was checked to see whether client can be granted desired access (Synchronize, ReadData, ListDirectory, ReadAttribute)
5168(F): SPN check for SMB/SMB2 failed.

Access the SMB share path from a remote machine to open a file on the SMB Server > Return to SMB Server console session to refresh the event viewer and see the ‘Audit Success’ item

Here’s a sample text of the event above:

A network share object was accessed.

Subject:
Security ID: intranet\TestUser
Account Name: TestUser
Account Domain: intranet
Logon ID: 0x80160F50

Network Information:
Object Type: File
Source Address: 10.10.10.10
Source Port: 58341

Share Information:
Share Name: \\*\IPC$
Share Path:

Access Request Information:
Access Mask: 0x1
Accesses: ReadData (or ListDirectory)

 

PowerShell Script from ManageEngine ADAudit Plus:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# This script is authored by ManageEngine
# Displaying here as illustration purpose - if this is not allowed by author, this will be removed
 
# Purpose: Configure Object Level Auditing for File Integrity Monitoring
 
param([String]$file,[String]$mode,[String]$recurse,[String]$username)
$networkDrive="z"
$date = Get-Date -Format M-d-yyyy
$time = Get-Date -Format HH-mm-ss-fff
$fileName = 'ADAP-SET-SACL-('+$date+')_('+$time+').txt'
$folderName = pwd
$folderName = "$folderName\ADAP-SET-SACL-Logs\"
$logFilepath = "$folderName$fileName"
if(!(Test-Path $folderName)){
    New-Item -Path $folderName -ItemType "directory"
}
if(!(Test-Path $logFilepath)){
    New-Item -Path $logFilepath -ItemType "file"
}
Start-Transcript -path $logFilepath -append
$time = Get-Date -Format hh:mm:ss:fff:tt
write-host "Start Time : "$date" - "$time
Function ExitInfo {
    Write-Host "`n`rUsage: `n`r"
    Write-Host "ADAP-Set-SACL.ps1 -file -mode [-recurse] [-username]`n`r"
    Write-Host "-file       [ Mandatory ]  CSV file`r"
    Write-Host "-mode       [ Mandatory ]  add (Adding the SACL on all folder and subfolders) or remove (removing the SACL on the folder and subfolders) : For remove - 'recurse' not applicable`r"
    Write-Host "-recurse    [ Optional ]   Enable Inheritance and Remove all explicit SACL on all subfolders : 'true' or 'false' : By default false`r"
    Write-Host "-username   [ Optional ]   Domain User having privilege over the folder or shares `n`r"
    Write-Host "Examples: `r"
    Write-Host "1) .\ADAP-Set-SACL.ps1 -file '.\folders.csv' -mode add `r"
    Write-Host "2) .\ADAP-Set-SACL.ps1 -file '.\folders.csv' -mode add -username DOMAIN_NAME\username `r"
    Write-Host "3) .\ADAP-Set-SACL.ps1 -file '.\folders.csv' -mode add -recurse true `r"
    Write-Host "4) .\ADAP-Set-SACL.ps1 -file '.\folders.csv' -mode remove `r"
    Write-Host "5) .\ADAP-Set-SACL.ps1 -file '.\folders.csv' -mode remove -username DOMAIN_NAME\username`n`r"
    Write-Host "In Input csv file, Format should be as"
    Write-Host "<Folder>,<type>"
    Write-Host "    -Folder     UNC Path (Ex: \\SERVERNAME\ShareName) or Local Path (Ex: C:\Test Folder)"
    Write-Host "    -type       FA (File Auditing) or FIM (File Integrity Monitoring)`n`r"
    Write-Host "For removing SACL -type is not required`n`r"
    Write-Host "Examples: `n`r"
    Write-Host "In file 'folders.csv' `n`r"
    Write-Host "\\SERVERNAME\folder,FA"
    Write-Host "c:\test folder,FA"
    Write-Host "E:\test folder,FIM"
    Write-Host "\\SERVERNAME\c$\folder,FIM`n`r"
    $time = Get-Date -Format hh:mm:ss:fff:tt
    write-host "End Time : "$date" - "$time
    Stop-Transcript
    exit #terminate the script.
}
$ErrorActionPreference = "Continue"
$recurseFlag=1
$flag=1
$errorcode=0
 
if($file -eq $null -or $file -eq ""){
    Write-Host "`nERROR :: -file should not be empty"
    $errorcode=1
}
if($mode -eq $null -or $mode -eq ""){
    Write-Host "`nERROR :: -mode should be empty"
    $errorcode=1
} ElseIf ($mode.Trim() -ne "add") {
    if($mode.Trim() -ne "remove"){
        Write-Host "`nERROR :: -mode is invalid '$mode'"
        $errorcode=1
    }
}
if(!($recurse -eq $null -or $recurse -eq "")){
    if($recurse -ieq "true") {
        $recurseFlag=2
    }elseif($recurse -ieq "false") {
        $recurseFlag=1
    }else{
        Write-Host "`nERROR :: -recurse is invalid '$recurse'"
        $errorcode=1
    }
}
if($errorcode -ne 1 -and $username -ne $null -and $username -ne ""){
        $flag=2
        $Cred = Get-Credential $username
        $username = $cred.UserName
        $password = $cred.GetNetworkCredential().Password
 
        # Get current domain using logged-on user's credentials
        $CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
        $domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$username,$password)
 
        if ($domain.name -eq $null)
        {
            write-host "`nERROR :: Authentication failed - please verify your username and password."
            $time = Get-Date -Format hh:mm:ss:fff:tt
            write-host "End Time : "$date" - "$time
            Stop-Transcript
            exit #terminate the script.
        }
        else
        {
            write-host "Successfully authenticated with domain "$domain.name
        }
}
if($errorcode -ne 0)
{
    ExitInfo
}
 
Function Clear-SACL {
    [cmdletbinding()]
    Param (
        [string]$Path,
        [string]$isAll
    ) # End of Parameters
    $isRuleRemoved=$False
    $clearACL = Get-ACL -Audit $Path
    if($isAll -eq "all"){
        $clearACL.Audit | %{$clearACL.RemoveAuditRule($_)} > $null
    }elseif ($isAll -eq "explicit"){
        Foreach($entries in $clearACL.Audit)
        {
            if ($entries.isinherited -eq $false)
            {
                $isRuleRemoved=$True
                $clearACL.RemoveAuditRule($entries)  > $null
            }
        }
    }
    #Get-ACL -Audit $Path | select *
    return $clearACL,$isRuleRemoved
}
 
Function Enable-inherit {
    [cmdletbinding()]
    Param (
        [string]$Path
    ) # End of Parameters
     
    $PathSACL = Get-ACL -Audit $Path | select Path,Audit,AreAuditRulesProtected
 
    if($PathSACL.AreAuditRulesProtected){
        $inheritlevel = $False
    }
    if(!($inheritlevel)){
        Foreach($entries in $PathSACL.Audit)
        {
            $count = $True
            break
        }
    }
    if(!($count) -and !($inheritlevel)){
        $setDummySACL = Get-ACL -Audit $Path
        $Dummypermission = "everyone","ChangePermissions","None","None","Success"
        $saclinherit = New-Object  System.Security.AccessControl.FileSystemAuditRule $Dummypermission
        $setDummySACL.AddAuditRule($saclinherit)
    }
    if(!$inheritlevel){
        $setSACL = Get-ACL -Audit $Path
        $setSACL.SetAuditRuleProtection($False,$True)
        $setSACL | Set-Acl $Path
    }
    #Get-ACL -Audit $Path | select *
}
 
Function Add-SACL {
    [cmdletbinding()]
    Param (
        [string]$Path,
        [string]$Type,
        [PSObject]$folderAcl
    )
 
    $permission1 = "everyone","ChangePermissions,TakeOwnership","ContainerInherit","None","Success,Failure"
    $AuditRule1 = New-Object  System.Security.AccessControl.FileSystemAuditRule $permission1
    $folderAcl.AddAuditRule($AuditRule1)
 
    $permission2 = "everyone","CreateFiles,WriteData,CreateDirectories,AppendData,WriteAttributes,WriteExtendedAttributes,DeleteSubdirectoriesAndFiles,Delete","ContainerInherit,ObjectInherit","None","Success,Failure"
    $AuditRule2 = New-Object  System.Security.AccessControl.FileSystemAuditRule $permission2
    $folderAcl.AddAuditRule($AuditRule2)
 
    if($Type -eq $null -or $Type -eq "" -or $Type.Trim() -eq "FA")
    {
        $permission3 = "everyone","ListDirectory,ReadData","ObjectInherit","InheritOnly","Success,Failure"
        $AuditRule3 = New-Object  System.Security.AccessControl.FileSystemAuditRule $permission3
        $folderAcl.AddAuditRule($AuditRule3)
 
        $permission4 = "everyone","ListDirectory,ReadData","ContainerInherit","None","Failure"
        $AuditRule4 = New-Object  System.Security.AccessControl.FileSystemAuditRule $permission4
        $folderAcl.AddAuditRule($AuditRule4)
    }
    $folderAcl.SetAuditRuleProtection($false,$false)
    $folderAcl | Set-Acl $Path
    #Get-ACL -Audit $Path | select *
}
 
if($file -ne $null -and $file.Trim() -ne "")
{
    Write-Host "`r"
    Import-Csv "$file" -Header folderPath,Type | foreach-object{
        $errorcode=0
        $parentfolder = $_.folderPath
        $parentType = $_.Type
        try
        {
            if($flag -eq 2 -and $parentfolder.startswith("\\"))
            {
                $Error.clear()
                net use $parentfolder $password /user:$username   > $null
                if($LASTEXITCODE -ne 0){
                    throw $Error
                }
            }
            if($mode -ne $null -and $mode -ieq "add"){
                Write-Host "Adding SACL on '"$parentfolder"' for type "$parentType  -NoNewline
                if($parentType -eq $null -or $parentType -eq "") {
                    Write-Host "`n`rError on folder '"$parentfolder"' -type should not be empty`r"
                    $errorcode=1
                }elseif(!($parentType.Trim() -eq "FA" -or $parentType.Trim() -eq "FIM")){
                    Write-Host "`n`rError on folder '"$parentfolder"' -type '"$parentType"' is wrong`n`r"
                    $errorcode=1
                }
                if($errorcode -ne 0 )
                {
                    ExitInfo
                }
                $parentSACL = Get-ACL -Audit $parentfolder | select Path,Audit,AreAuditRulesProtected
                $ClearSACLreturn=Clear-SACL -Path $parentfolder -isAll "explicit"
                $parentSACL = $ClearSACLreturn[0]
                $isSAClmodified = $ClearSACLreturn[1]
                $parentstartTime = Get-Date -Format hh:mm:ss:fff:tt
                Add-SACL -Path $parentfolder -Type $parentType $parentSACL
                $parentendTime = Get-Date -Format hh:mm:ss:fff:tt
                write-host " ( Start Time : $parentstartTime )( End Time : $parentendTime )"
                if($recurseFlag -eq 2){
                    Write-Host "Enable Inheritance and Removing explicit SACL on subfolders of "$parentfolder
                    Get-ChildItem -Path $parentfolder -Recurse | Where-Object { $_.PSIsContainer } | foreach-object {
                        try 
                        {
                            $subfolderpath = $_.FullName
                            Write-Host "`tSubfolder - '"$subfolderpath"'"  -NoNewline
                            $childstartTime = Get-Date -Format hh:mm:ss:fff:tt
                            Enable-inherit -Path $subfolderpath
                            $ClearSACLreturn = Clear-SACL -Path $subfolderpath -isAll "explicit"
                            $subfolderAcl = $ClearSACLreturn[0]
                            $isSAClmodified = $ClearSACLreturn[1]
                            if($isSAClmodified){
                                $subfolderAcl | Set-Acl $subfolderpath
                            }
                            $childendTime = Get-Date -Format hh:mm:ss:fff:tt
                            write-host " ( Start Time : $childstartTime )( End Time : $childendTime )"
                        }catch [System.Exception] { 
                            Write-Host "`nError on SubFolder'"$subfolderpath"' : "$_.Exception.Message
                        }
                        #Get-ACL -Audit $subfolderpath | select Path,AreAuditRulesProtected,Audit
                    }
                    Write-Host "`r"
                }
            }elseif($mode -ne $null -and $mode -ieq "remove"){
                Write-Host "Removing SACL on '"$parentfolder"'"  -NoNewline
                $parentstartTime = Get-Date -Format hh:mm:ss:fff:tt
                $ClearSACLreturn=Clear-SACL -Path $parentfolder -isAll "all"
                $subfolderAcl = $ClearSACLreturn[0]
                $subfolderAcl | Set-Acl $parentfolder
                $parentendTime = Get-Date -Format hh:mm:ss:fff:tt
                write-host " ( Start Time : $parentstartTime )( End Time : $parentendTime )"
            }
        }
        catch [System.Exception] { 
            Write-Host "`nError on Parent Folder '"$parentfolder"' ("$parentType") : "$_.Exception.Message
        }
        finally {
            if($flag -eq 2 -and $parentfolder.startswith("\\"))
            {
                net use $parentfolder /delete  > $null      
            
        }
    }
}
$time = Get-Date -Format hh:mm:ss:fff:tt
write-host "End Time : "$date" - "$time
Stop-Transcript