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:

# 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