Logs files are great things but as with a lot of things the hidden value of these resources is often hard to see at there face value. I had a very simple problem this week where i needed to know which users where using Outlook Anywhere and what their IPAddress where. For this the IIS logs could more then provide an answer for this but these log files and get quite large and contain a mix of different information not just Outlook http/rpc traffic.
One of the main challenges you have when looking at IIS logs files is that depending on who enabled logging the Fields and the order they are being logged in may differ. So a parser/script you write to work against one set of logs might not work against another server. To solve this problem is quite simple when a log file is created at the top of the log file on line 4 is written the field format for the file. So if you first read this line parse it into a Hashtable and index it by the fieldname we then know what the index array value will be when you go to read each line of the log file for the field you want to extract.
To make the script easy to use I've added a front end GUI component to make the script present a file select box to select the log file to work with. It then reads the file using get-content and filters it based on OutlookAnywhere log entries using a like filter on “*MSRPC*”. The script groups the results by IPAddress and UserName and builds a exportable collection that produces a csv file or the results of the scan with a simple list of OutlookAnywhere users and what IP address they came from. The cool thing about the script is that it can be easily adapted to scan for anything in a IIS log file eg say you wanted a list of people using a Iphone and their IPaddress.
I've put a download of the script here the script itself looks like
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
$exFileName = new-object System.Windows.Forms.openFileDialog
$exFileName.ShowHelp = $true
$exFileName.ShowDialog()
$fname = $exFileName.FileName
$mbcombCollection = @()
$FldHash = @{}
$usHash = @{}
$fieldsline = (Get-Content $fname)[3]
$fldarray = $fieldsline.Split(" ")
$fnum = -1
foreach ($fld in $fldarray){
$FldHash.add($fld,$fnum)
$fnum++
}
get-content $fname | Where-Object -FilterScript { $_ -ilike “*MSRPC*” } | %{
$lnum ++
if ($lnum -eq $rnma){ Write-Progress -Activity "Read Lines" -Status $lnum
$rnma = $rnma + 1000
}
$linarr = $_.split(" ")
$uid = $linarr[$FldHash["cs-username"]] + $linarr[$FldHash["c-ip"]]
if ($linarr[$FldHash["cs-username"]].length -gt 2){
if ($usHash.Containskey($uid) -eq $false){
$usrobj = "" | select UserName,IpAddress
$usrobj.UserName = $linarr[$FldHash["cs-username"]]
$usrobj.IpAddress = $linarr[$FldHash["c-ip"]]
$usHash.add($uid,$usrobj)
$mbcombCollection += $usrobj
}
}
}
$mbcombCollection | export-csv –encoding "unicode" -noTypeInformation c:\oareport.csv
One of the main challenges you have when looking at IIS logs files is that depending on who enabled logging the Fields and the order they are being logged in may differ. So a parser/script you write to work against one set of logs might not work against another server. To solve this problem is quite simple when a log file is created at the top of the log file on line 4 is written the field format for the file. So if you first read this line parse it into a Hashtable and index it by the fieldname we then know what the index array value will be when you go to read each line of the log file for the field you want to extract.
To make the script easy to use I've added a front end GUI component to make the script present a file select box to select the log file to work with. It then reads the file using get-content and filters it based on OutlookAnywhere log entries using a like filter on “*MSRPC*”. The script groups the results by IPAddress and UserName and builds a exportable collection that produces a csv file or the results of the scan with a simple list of OutlookAnywhere users and what IP address they came from. The cool thing about the script is that it can be easily adapted to scan for anything in a IIS log file eg say you wanted a list of people using a Iphone and their IPaddress.
I've put a download of the script here the script itself looks like
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")
$exFileName = new-object System.Windows.Forms.openFileDialog
$exFileName.ShowHelp = $true
$exFileName.ShowDialog()
$fname = $exFileName.FileName
$mbcombCollection = @()
$FldHash = @{}
$usHash = @{}
$fieldsline = (Get-Content $fname)[3]
$fldarray = $fieldsline.Split(" ")
$fnum = -1
foreach ($fld in $fldarray){
$FldHash.add($fld,$fnum)
$fnum++
}
get-content $fname | Where-Object -FilterScript { $_ -ilike “*MSRPC*” } | %{
$lnum ++
if ($lnum -eq $rnma){ Write-Progress -Activity "Read Lines" -Status $lnum
$rnma = $rnma + 1000
}
$linarr = $_.split(" ")
$uid = $linarr[$FldHash["cs-username"]] + $linarr[$FldHash["c-ip"]]
if ($linarr[$FldHash["cs-username"]].length -gt 2){
if ($usHash.Containskey($uid) -eq $false){
$usrobj = "" | select UserName,IpAddress
$usrobj.UserName = $linarr[$FldHash["cs-username"]]
$usrobj.IpAddress = $linarr[$FldHash["c-ip"]]
$usHash.add($uid,$usrobj)
$mbcombCollection += $usrobj
}
}
}
$mbcombCollection | export-csv –encoding "unicode" -noTypeInformation c:\oareport.csv