Posts tagged ‘data-exfiltration’

How to search exchange server logs recursively.

If we need to investigate a breach on the On-Prem Exchange server , the first course of action is to read the log files in the location X:\Program Files\Microsoft\Exchange Server\V15\Logging\.

The manual approach will be tedious as we need to open each file and look for an entry by an IP or other parameters. Instead of that you could use the below script to traverse all the log files and extract the presence of our search parameter (especially by an IP address) and produce the output as below(sometimes you may not see all the field populated) .We need to focus on the LogFile,LineNumber,Client IP .

TimeProtocolFileLineNumberClientIPUserUriStatusUserAgent
2026-08-10T03:13:59Autodiscover…LOG4312203.0.113.45user1/autodiscover/autodiscover.xml200
2026-08-10T03:14:22Mapi…LOG15234203.0.113.45user1/mapi/…200
2026-08-10T03:15:03Ews…LOG8721203.0.113.45user1/EWS/Exchange.asmx200

The sample script I used is (Source :ChatGPT)

$IP = “79.135.105.141”
$LogRoot = “C:\Program Files\Microsoft\Exchange Server\V15\Logging”

$Output = “C:\Temp\Exchange-IP-$($IP.Replace(‘.’,’_’)).csv”

#Create output directory if necessary

New-Item -ItemType Directory -Path (Split-Path $Output) -Force | Out-Null

$Results = foreach ($File in Get-ChildItem $LogRoot -Recurse -File) {

# Read the header to determine the Exchange log fields
$FieldsLine = Get-Content $File.FullName -TotalCount 20 |
Where-Object { $_ -match '^#Fields:' } |
Select-Object -First 1
if (-not $FieldsLine) {
continue
}
$Fields = ($FieldsLine -replace '^#Fields:\s*', '').Split(',')
# Find lines containing the IP
$Matches = Select-String -Path $File.FullName -Pattern $IP -SimpleMatch
foreach ($Match in $Matches) {
$Values = $Match.Line.Split(',')
$Record = [ordered]@{
Time = ""
Protocol = $File.Directory.Name
File = $File.Name
LineNumber = $Match.LineNumber
ClientIP = $IP
User = ""
Uri = ""
Status = ""
UserAgent = ""
}
for ($i = 0; $i -lt $Fields.Count -and $i -lt $Values.Count; $i++) {
$Field = $Fields[$i].Trim()
$Value = $Values[$i].Trim()
switch -Regex ($Field) {
'^date-time$|^timestamp$|^date$' {
$Record.Time = $Value
}
'client-ip|remote-ip|source-ip' {
$Record.ClientIP = $Value
}
'user|authenticated-user|user-name|username' {
$Record.User = $Value
}
'uri|url' {
$Record.Uri = $Value
}
'status|http-status' {
$Record.Status = $Value
}
'user-agent' {
$Record.UserAgent = $Value
}
}
}
[PSCustomObject]$Record
}

}

$Results |

Sort-Object Time |

Export-Csv -Path $Output -NoTypeInformation -Encoding UTF8

Write-Host “”
Write-Host “Search complete.”
Write-Host “Matches found: $($Results.Count)”
Write-Host “CSV: $Output”

August 11, 2026 at 11:55 am Leave a comment


Archives

Categories

Follow Hope you like it.. on WordPress.com

Blog Stats

  • 96,859 hits