Sabtu, 08 September 2012

Less Thrashing; Better Queries (Part IV)

I will just keep running with this series until I get sick of [System.Diagnostics.Eventing...].

The code below  compares an exported list of  "Security Audit Events for Windows 7 and Windows Server 2008 R2" with a grouped list of the last 10K events from the Security Log. This is a quick way to look at all your security events ordered by count and an appended "Message Summary".


# Working 3:57 PM 9/8/2012
# PS 3.0 Beta

$Security= get-winevent -ea 0  -LogName Security -MaxEvents 10000
$a=$Security | group -property ID -noelement | sort -desc -property count
[array[]]$b=import-csv .\Windows7.csv
[array[]]$c=0..((($B."Event ID").count) - 1) | % -process {
 foreach ($ID in $a.name) {if ($ID -eq $B[$PSItem]."Event ID") `
  {write "$($B[$PSItem]."Event ID") : $($B[$PSItem]."Message Summary")"}}}
$a
$c




PS C:\ps1> $Security=get-winevent -max 10000 Security
PS C:\ps1> $a=$Security | group -property ID -noelement | sort -desc -property count
PS C:\ps1> [array[]]$b=import-csv .\Windows7.csv
PS C:\ps1> [array[]]$c=0..((($B."Event ID").count) - 1) | % -process {
>> foreach ($ID in $a.name) {if ($ID -eq $B[$PSItem]."Event ID") `
>> {write "$($B[$PSItem]."Event ID") : $($B[$PSItem]."Message Summary")"}}}
>> $a
>> $c
>>

Count Name
----- ----
 7683 5156
 2125 5158
  121 4688
   45 5157
    8 4624
    7 4672
    3 5154
    2 4776
    2 4634
    1 4801
    1 4800
    1 4625
    1 4648
4624 : An account was successfully logged on.
4625 : An account failed to log on.
4634 : An account was logged off.
4648 : A logon was attempted using explicit credentials.
4672 : Special privileges assigned to new logon.
4688 : A new process has been created.
4776 : The domain controller attempted to validate the credentials for an account.
4800 : The workstation was locked.
4801 : The workstation was unlocked.
5154 : The Windows Filtering Platform has permitted an application or service to listen on a port for incoming connections.
5156 : The Windows Filtering Platform has allowed a connection.
5157 : The Windows Filtering Platform has blocked a connection.
5158 : The Windows Filtering Platform has permitted a bind to a local port.

Kamis, 06 September 2012

Less Thrashing; More Sorting Queries (Part IIl)


The cruft below demonstrates (somewhat) how to effectively interrogate  70k events from Windows  with PS 3.0. It presumes you are using 'auditpol' to your advantage. When querying that many events, I keep a check on memory in the title bar with this function:


function Global:set-titleMemoryStats {

# With 3.0 Runspace
$set_title=

{

function Global:Set-title {
$PSID=([System.Diagnostics.Process]::GetCurrentProcess()).Id
$MemStats=ps -id $PSID | Select `
@{Name='ThreadCount';Expression={($_.Threads).count}}, `
@{Name='WorkSetMB';Expression={[int](($_.WorkingSet64)/1MB)}}, `
@{Name='VirMemMB';Expression={[int](($_.VirtualMemorySize64)/1MB)}}, `
@{Name='PriMemMB';Expression={[int](($_.PrivateMemorySize64)/1MB)}}, `
@{Name='PagedMemMB';Expression={[int](($_.PagedMemorySize64)/1MB)}}, `
@{Name='NonPagedMemKB';Expression={[int](($_.NonPagedSystemMemorySize64)/1KB)}}

$Title=write "Last_Title_Stats: Time: $([datetime]::now) Version: $((get-host).Version.Major) SessionHours: $([int]([datetime]::now - (ps -id $psid).Starttime).totalhours) Memory: $($Memstats) GC_MB: $([int]([GC]::gettotalmemory(1)/1MB))"
[console]::set_title($Title)
}

while(1) {set-title;sleep -s 5}

}


$ST_Runspace = [PowerShell]::Create().AddScript($set_title)
$Begin_Set_Title = $ST_Runspace.BeginInvoke()

# To stop all of this...
# $ST_Runspace.runspace
# $Stop_Set_Title = $ST_Runspace.Stop()
# $Dispose_Set_Title = $ST_Runspace.Dispose()

}







On with the demonstration.  The filterhashtable parameter will allow function with one array per query. (e.g. 'ID=@(5156..5158)'). However, we could select out specific IDs for each log included. I will leave it to the reader to decide which security audit subcategories ('auditpol /get /category:*') are imortant. I am focusing on 5156, 5157, 5158 (e.g. 'Filtering Platform Connection', 'Filtering Platform Policy Change'). Here is the complete list of security events from Microsoft

After some experimentation, I use the following PSObject based query to increase the query speed. Honestly, I am not sure why it works so well.:

function Global:Search-EventLog
{
    [CmdletBinding(SupportsPaging = $true)]
    param(
$maxSecurity=5000,
$maxSystem=1000,
$maxApplication=1000
 )

$Elements=New-Object PSObject -Property @{
Security_515X=get-winevent -ea 0 -max $maxSecurity -filterhashtable @{logname='Security';ID=@(5156..5158)}
System=get-winevent -ea 0 -max $maxSystem -filterhashtable @{logname='System'}
Application=get-winevent -ea 0 -max $maxApplication -filterhashtable @{logname='Application'}
}

if ($All_Events) {rv -ea 0 All_Events}
$global:Events= foreach ($element in $Elements) {$element}
[array]$HAElements="Security_515X","System","Application"
foreach ($element in $HAElements){$All_Events+=$Events.$element}
$Global:EventLog=$All_Events | Sort -desc -property TimeCreated
}


#70K events in 5 min 14 seconds!
measure-command {Search-EventLog 50000 10000 10000}


Days              : 0
Hours             : 0
Minutes           : 5
Seconds           : 14
Milliseconds      : 790
Ticks             : 3147907742
TotalDays         : 0.00364341173842593
TotalHours        : 0.0874418817222222
TotalMinutes      : 5.24651290333333
TotalSeconds      : 314.7907742
TotalMilliseconds : 314790.7742

# Now we find the IDs and sort them by count.
$EventLog | group -property ID -noelement | Sort -desc -property Count

Count Name
----- ----
24669 5156
23893 5158
 7167 7036
 2331 257
 2070 0
 1651 1035
 1438 5157
  743 1
...

# Now we sort them by ProviderName.
$EventLog | group -property ProviderName -noelement | Sort -desc -property Count | ft -auto -wrap

Count Name
----- ----
50000 Microsoft-Windows-Security-Auditing
 7972 Service Control Manager
 2501 MsiInstaller
 2352 SampleCollector
 1182 gupdate
  345 Windows Error Reporting
  342 Microsoft-Windows-Security-SPP
  317 Microsoft-Windows-CAPI2
  315 Microsoft-Windows-Kernel-General
  309 gusvc
  289 Microsoft-Windows-Kernel-Power
  278 Microsoft-Windows-Power-Troubleshooter
  257 VSS
  250 Microsoft-Windows-RestartManager
  248 ESENT
  235 Microsoft Antimalware
  173 Microsoft-Windows-WMI
  153 Microsoft-Windows-WindowsUpdateClient
  134 System Restore
  129 Microsoft-Windows-DNS-Client
  125 Microsoft-Windows-Winlogon
 ...

# Sorted Count of Events Per Provider
$EventLog | ? {$_.ProviderName -eq "Microsoft-Windows-Security-Auditing"} | group -property ID -noelement | Sort -desc -property Count | ft -auto -wrap

Count Name
----- ----
24669 5156
23893 5158
 1438 5157

# We want to look at the Event IDs for one specific provider.
$EventLog | ? {$_.ProviderName -eq "Service Control Manager"} | group -property ID -noelement | Sort -desc -property Count | ft -auto -wrap

Count Name
----- ----
 7161 7036
  398 7040
  286 7042
   95 7011
   18 7045
    5 7039
    3 7030
    3 7009
    2 7000
    1 7034


# Okay! Just the unique messages from all events for the "Service Control Manager" provider:
[array[]]$a=$EventLog | ? {$_.ProviderName -eq "Service Control Manager"} | group -property ID -noelement | Sort -desc -property Count
 $a.Name | Sort -desc
7045
7042
7040
7039
7036
7034
7030
7011
7009
7000
[array[]]$b=$a.Name | Sort -desc
$c=foreach ($i in $b) {$EventLog | ? {$_.ID -eq "$i"} | Select -unique | group -property Message -noelement}
$c | ft -auto -wrap

Count Name
----- ----
    1 A service was installed in the system.

      Service Name:  Google Software Updater
      Service File Name:  "C:\Program Files (x86)\Google\Common\Google Updater\GoogleUpdaterService.exe"
      Service Type:  user mode service
      Service Start Type:  disabled
      Service Account:  LocalSystem
    1 The TCP/IP NetBIOS Helper service was successfully sent a stop control.

       The reason specified was: 0x40030011 [Operating System: Network Connectivity (Planned)]

       Comment: None
    1 The start type of the Windows Modules Installer service was changed from auto start to demand start.
    1 A service process other than the one launched by the Service Control Manager connected when starting the Google Update Service (gupdate) service.  The Service
      Control Manager launched process 8096 and process 8324 connected instead.

        Note that if this service is configured to start under a debugger, this behavior is expected.
    1 The Google Update Service (gupdate) service entered the stopped state.
    1 The Eventlog to Syslog service terminated unexpectedly.  It has done this 1 time(s).
    1 The PST Service service is marked as an interactive service.  However, the system is configured to not allow interactive services.  This service may not function
      properly.
    1 A timeout (30000 milliseconds) was reached while waiting for a transaction response from the VcmIAlzMgr service.
    1 A timeout was reached (30000 milliseconds) while waiting for the Windows Error Reporting Service service to connect.
    1 The Windows Search service failed to start due to the following error:
      The service did not respond to the start or control request in a timely fashion.



# Some methods to display query event IDs from regular expressions (see 'man about_regular_expressions')


$EL_4xxx=$EventLog | ? {$_.ID -match '^4...'}
$EL_4xxx | ft -auto -wrap TimeCreated,ID,RecordID,ProviderName, `
@{Name="Message[100]"; Expression={($_.Message).substring(0,100)}}


TimeCreated             Id RecordId ProviderName                      Message[100]
-----------             -- -------- ------------                      ------------
7/12/2012 11:41:31 AM 4000    87634 Microsoft-Windows-WLAN-AutoConfig
...

[array[]]$a=$EL_4xxx | Select TimeCreated,ID,RecordID,ProviderName, `
@{Name="Message[100]"; Expression={($_.Message).substring(0,100)}}
$a.'Message[100]'| sls 'certificate'

Successful auto update of disallowed certificate list with effective date: Thursday, June 21, 2012 4
Successful auto update of third-party root certificate:: Subject:
Successful auto property update of third-party root certificate:: Subject:
Successful auto update of third-party root certificate:: Subject:
...

$EL_1xxx=$EventLog | ? {$_.ID -match '^1...'}
$EL_1xxx | ft -auto -wrap TimeCreated,ID,RecordID,ProviderName, `
@{Name="Message[100]"; Expression={($_.Message).substring(0,100)}}


TimeCreated            Id RecordId ProviderName                                Message[100]
-----------            -- -------- ------------                                ------------
9/5/2012 3:32:06 PM 10000    92858 Microsoft-Windows-DriverFrameworks-UserMode A driver package which uses user-mode driver framework version 1.9.0 is being installed
                                                                               on device US

...

$EL_8xxx=$EventLog | ? {$_.ID -match '^8...'}
$EL_8xxx | ft -auto -wrap TimeCreated,ID,RecordID,ProviderName, `
@{Name="Message[100]"; Expression={($_.Message).substring(0,100)}}

TimeCreated            Id RecordId ProviderName   Message[100]
-----------            -- -------- ------------   ------------
8/25/2012 9:08:21 PM 8194    32462 System Restore Successfully created restore point (Process = C:\Windows\system32\svchost.exe -k netsvcs; Descriptio
...

Rabu, 05 September 2012

Encryption Is Not the Answer to Security Problems

I just read Cyber Fail: Why can't the government keep hackers out? Because the public is afraid of letting it, an article in the new Foreign Policy National Security channel. I've Tweeted on Mr Arquilla's articles before, but this new one published today offers a solution to security problems that just won't work.

Consider these excerpts:

Back in President Bill Clinton's first term, the "clipper chip" concept was all about improving the security of private communications. Americans were to enjoy the routine ability to send strongly encoded messages to each other that criminals and snoops would not be able to hack, making cyberspace a lot safer.

I see two errors in this section. First, having lived through that time, and having read Steven Levy's excellent book Crypto: How the Code Rebels Beat the Government Saving Privacy in the Digital Age, I disagree with Mr Arquilla's statement. The Clipper Chip was the government's last attempt to keep tight control of encryption, not "improve the security of private communications."

Second, Mr Arquilla implies that encryption = "making cyberspace a lot safer." That fallacy appears later in the article.

Sadly, industry leaders have never emphasized the value of strong crypto sufficiently either. There are many reasons for this neglect -- the most likely being that encouraging ubiquitous use of strong crypto could weaken sales of the firewalls and anti-viral products that form so much of the cybersecurity business model.

Here is my key issue with this article. An enterprise could encrypt every single piece of information at rest or in transit, and intruders would still win.

The fundamental reality of cryptography in the enterprise is that users and applications must be able to access data in unencrypted form in order to use it.

In other words, if a user can access data, so can an intruder.

Cryptography certainly frustrates some bad guys, such as amateurs who eavesdrop on encrypted communications, or thieves who swipe mobile devices, or intruders who remove encrypted files without bothering to obtain the material necessary to decrypt it.

However, cryptography will not stop your Web app from suffering SQL injection, nor will it keep Java from being exploited by a client-side attack.

The article concludes in part by saying:

But ways ahead do exist. There is a regulatory role: to mandate better security from the chip-level out -- something that Sen. Joseph Lieberman's Cybersecurity Act would only have made voluntary.

This sounds like an advertisement for a chip maker. I've heard their lobbyists use the same terms on Capitol Hill. "Mandating security" at the "chip level" would be as effective as FISMA -- a waste of time.

Mr Arquilla does make a few points I agree with, such as:

[W]e should treat cybersecurity as a foreign-policy issue, not just a domestic one. For if countries, and even some networks, can find a way to agree to norms that discourage cyberwar-making against civilian infrastructure -- much as the many countries that can make chemical and biological weapons have signed conventions against doing so -- then it is just possible that the brave new virtual world will be a little less conflict prone.

However, do not be fooled into thinking that encryption is the answer to our security problems.

Senin, 03 September 2012

Bejtlich Interviewed on This Week in Defense News

Last week Vago Muradian from This Week in Defense News with Vago Muradian interviewed me for his show. You can see the online version here.

The online version is about two minutes longer than the broadcast version. We recorded the extra material separately and the video staff added it in the middle of the session. They were so smooth I didn't originally notice the change!

Vago asked questions about how companies can defend themselves from digital threats. He wanted to know more about state-sponsored intrusions and how to differentiate among different types of threat actors.

In the extra session Vago and I talked about recent SEC activities and how to tell if your organization has been victimized by a targeted attacker.

There's a possibility Vago will invite me back to participate on a panel discussing digital security. I look forward to that if it happens!

If you have any questions on the video, please post a comment and I'll answer. Thank you.

Kamis, 30 Agustus 2012

My Role in Information Warfare during the Yugoslav Wars

This morning I read a Tweet from @AirForceAssoc reminding me that:

Today in Airpower History, August 30, 1995: NATO and U.S. aircraft began airstrikes on Serbian ground positions in Bosnia-Herzegovina to support the U.N. Operation Deliberate Force. The airstrikes, with a Bosnian-Croatian ground attack, convinced the Serbs to accept peace terms in late 1995.

I'm not particularly fond of commemorating airpower campaigns, but the Tweet did remind me of the small part I played in the Yugoslav Wars of the 1990s. Many Americans remember the 1990s, and especially the Clinton presidency, as a "quiet decade" between the first Gulf War led by President GHW Bush and the so-called "Global War on Terror" led by President GW Bush. Instead of a quiet decade, I remember a an exceptionally busy time for the Air Force, including some of the first "information operations" that combined digital and physical effects.

In fact, fifteen years ago, almost to the week I believe, I volunteered to deploy from San Antonio to Joint Analysis Center (JAC) Molesworth in the UK. They needed intelligence support in the targeting shop, so as an Air Force intel officer I fit the bill. I decided to volunteer to go to the UK over the holidays (through early January) at a time of my "choice," rather than wait for the inevitable call to deploy to the desert, where US forces were still conducting counter-Iraqi operations.

Besides other targeting duties, the most interesting aspect of the shop was a requirement we received concerning a counter-propaganda campaign. Serbian Radio Television (SRT) was broadcasting fairly vile and false information to undermine the peace process. The Stabilization Force (SFOR) commander asked the JAC for options to shut down SRT transmissions, i.e., how to conduct "offensive counterinformation" operations against the Serbs.

We did some technical analysis of the SRT communication infrastructure and determined that if a certain set of transmission towers were "out of commission," that would end the broadcast problem. Part of the shop thought 500 lb bombs would be the best answer. Others thought we should apply a nondestructive approach and simply seize the towers by surrounding them with troops and tanks.

The photo in this post, attributed to the 55th Combat Camera Company, tells you what happened the morning of 1 October, 1997. SFOR seized four towers (Hill 619 in Duga Njiva is depicted), effectively terminating the SRT propaganda campaign. SFOR didn't destroy anything, but it conducted an information warfare operation to achieve the desired objective -- control of adversary mass communication.

If you'd like to read more about the history and theory of this operation, please see Physical Attack Information Operations in Bosnia: Counterinformation in a Peace Enforcement Environment by Major Arthur N. Tulak. I haven't yet read Memory, the media and NATO: information intervention in Bosnia-Hercegovina by Monroe Price, but it also discusses the same operation.

Sabtu, 25 Agustus 2012

Less Thrashing; More Queries (Part II)

These are more advanced event queries than my last post. Creating queries as psobject properties improves query speeds.More intra-message searches as calculated properties are included below.

$Elements=New-Object PSObject -Property @{

Security_515X=get-winevent -ea 0 -max 50000 -filterhashtable @{logname='Security';ID=@(5156..5158)}
System=get-winevent -ea 0 -max 10000 -filterhashtable @{logname='System'}
Application=get-winevent -ea 0 -max 10000 -filterhashtable @{logname='Application'}
}

if ($All_Events) {rv -ea 0 All_Events}

$global:Events= foreach ($element in $Elements) {$element}
[array]$HAElements="Security_515X","System","Application"
foreach ($element in $HAElements){$All_Events+=$Events.$element}
$a=$All_Events | Sort -desc -property TimeCreated


PS C:\> measure-command -expression {
>>
>> $Elements=New-Object PSObject -Property @{
>> Security_515X=get-winevent -ea 0 -max 50000 -filterhashtable @{logname='Security';ID=@(5156..5158)}
>> System=get-winevent -ea 0 -max 10000 -filterhashtable @{logname='System'}
>> Application=get-winevent -ea 0 -max 10000 -filterhashtable @{logname='Application'}
>> }
>>
>> if ($All_Events) {rv -ea 0 All_Events}
>> $global:Events= foreach ($element in $Elements) {$element}
>> [array]$HAElements="Security_515X","System","Application"
>> foreach ($element in $HAElements){$All_Events+=$Events.$element}
>> $a=$All_Events | Sort -desc -property TimeCreated
>> }
>>


Days              : 0

Hours             : 0
Minutes           : 5
Seconds           : 10
Milliseconds      : 163
Ticks             : 3101636859
TotalDays         : 0.00358985747569444
TotalHours        : 0.0861565794166667
TotalMinutes      : 5.169394765
TotalSeconds      : 310.1636859
TotalMilliseconds : 310163.6859


PS C:\> $All_Events.count

70000
PS C:\> $Elements | gm


   TypeName: System.Management.Automation.PSCustomObject


Name          MemberType   Definition

----          ----------   ----------
Equals        Method       bool Equals(System.Object obj)
GetHashCode   Method       int GetHashCode()
GetType       Method       type GetType()
ToString      Method       string ToString()
Application   NoteProperty System.Object[] Application=System.Object[]
Security_515X NoteProperty System.Object[] Security_515X=System.Object[]
System        NoteProperty System.Object[] System=System.Object[]


PS C:\> $Elements.Application.count

10000
PS C:\> $Elements.Security_515X.count
50000
PS C:\> $Elements.System.count
10000

Parsing ports and Addresses from the message log for security events: 5156,5157,5158 

(e.g.:
C:\Windows\system32>auditpol /get /subcategory:"Filtering Platform Policy Change"
System audit policy
Category/Subcategory                      Setting
Policy Change
  Filtering Platform Policy Change        Success and Failure
)

is a still a little cludgey here:


$a[0..100] | Select  TimeCreated,ID,ProviderName, `

@{Name='Ext_Message';Expression={($_.Message | findstr "Address Source Port")}} `
| ft -auto -wrap


TimeCreated            Id ProviderName                        Ext_Message
-----------            -- ------------                        -----------
8/25/2012 9:48:33 AM 7036 Service Control Manager
8/25/2012 9:47:37 AM 5156 Microsoft-Windows-Security-Auditing {    Source Address:        192.168.0.11,     Source Port:        2672,     Destination Address:    199.47.217.146,     Destination
                                                              Port:        80}
8/25/2012 9:47:37 AM 5156 Microsoft-Windows-Security-Auditing {    Source Address:        192.168.0.11,     Source Port:        2672,     Destination Address:    199.47.217.146,     Destination
                                                              Port:        80}
8/25/2012 9:47:37 AM 5156 Microsoft-Windows-Security-Auditing {    Source Address:        192.168.0.11,     Source Port:        2672,     Destination Address:    199.47.217.146,     Destination
                                                              Port:        80}

This is more concise:  

     
$a[0..100] | Select  TimeCreated,ID,ProviderName, `
@{Name='Ext_Message';Expression={($_.Message | findstr "Address Source Port") `
-replace("Source Address:","") -replace("Destination Address:","") `
-replace("Source Port:","") -replace("Destination Port:","") }} `
| ft -auto -wrap  

TimeCreated            Id ProviderName                        Ext_Message

-----------            -- ------------                        -----------
8/25/2012 9:48:33 AM 7036 Service Control Manager
8/25/2012 9:47:37 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             2672,         199.47.217.146,             80}
8/25/2012 9:47:37 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             2672,         199.47.217.146,             80}
8/25/2012 9:47:37 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             2672,         199.47.217.146,             80}
8/25/2012 9:47:24 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             17500,         255.255.255.255,             17500}
8/25/2012 9:47:12 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             137,         192.168.0.255,             137}
8/25/2012 9:47:00 AM 7036 Service Control Manager
8/25/2012 9:47:00 AM 7036 Service Control Manager
8/25/2012 9:46:58 AM 5158 Microsoft-Windows-Security-Auditing {            ::,             2680}
8/25/2012 9:46:58 AM 5156 Microsoft-Windows-Security-Auditing {            ::1,             445,         ::1,             2680}
8/25/2012 9:46:58 AM 5156 Microsoft-Windows-Security-Auditing {            ::1,             2680,         ::1,             445}
8/25/2012 9:46:54 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             17500,         255.255.255.255,             17500}
8/25/2012 9:46:42 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             2672,         199.47.217.146,             80}
8/25/2012 9:46:42 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             2672,         199.47.217.146,             80}
8/25/2012 9:46:42 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             2672,         199.47.217.146,             80}
8/25/2012 9:46:24 AM 5156 Microsoft-Windows-Security-Auditing {            192.168.0.11,             17500,         255.255.255.255,             17500}                                                    
...

08/26/2012: I've updated this post with the use of 'normalize()' to remove brackets.


Here are some methods to parse through the 70K log entries looking for connections:


$a[0..100] | Select ID,ProviderName,TimeCreated, `

@{Name="Message[10]"; Expression={($_.Message)[0,1]}}, `
@{Name="SourceAddress"; Expression={(($_.Message | findstr /C:"Source Address:").replace("Source Address:","")).Normalize()}}, `
@{Name="DestinationAddress"; Expression={(($_.Message | findstr /C:"Destination Address:").replace("Destination Address:","")).Normalize()}} `
| ft  -auto -wrap


This use of the for command let the users roll through log fifty events at a time:

for ($i = 0;; $i += 50) {$a[$i..($i+50)] | ft -auto ID,ProviderName,TimeCreated,Message;pause}


for ($i = 0;; $i += 50) {$a[$i..($i+50)]| `

ft -auto -wrap ID,TimeCreated,@{Name="Ext_Message"; Expression={(($_.Message | findstr "Address Source Port")).Normalize()}};
pause;
}

This last one cleans it up and separates Source and Destination into different fields:


for ($i = 0;; $i += 50) {$a[$i..($i + 50)] | 
ft -auto -wrap TimeCreated,ID,ProviderName, `
@{Name="SourceAddress";Expression={(($_.Message | findstr /C:'Source Address:').replace("Source Address:","")).Normalize()}}, `
@{Name="DestinationAddress";Expression={(($_.Message | findstr /C:'Destination Address:').replace("Destination Address:","")).Normalize()}};
pause;
}

 Id ProviderName                        TimeCreated          SourceAddress            DestinationAddress

  -- ------------                        -----------          -------------            ------------------
7036 Service Control Manager             8/25/2012 9:48:33 AM
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:47:37 AM             192.168.0.11         199.47.217.146
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:47:37 AM             192.168.0.11         199.47.217.146
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:47:37 AM             192.168.0.11         199.47.217.146
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:47:24 AM             192.168.0.11         255.255.255.255
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:47:12 AM             192.168.0.11         192.168.0.255
7036 Service Control Manager             8/25/2012 9:47:00 AM
7036 Service Control Manager             8/25/2012 9:47:00 AM
5158 Microsoft-Windows-Security-Auditing 8/25/2012 9:46:58 AM             ::
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:46:58 AM             ::1                  ::1
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:46:58 AM             ::1                  ::1
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:46:54 AM             192.168.0.11         255.255.255.255
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:46:42 AM             192.168.0.11         199.47.217.146
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:46:42 AM             192.168.0.11         199.47.217.146
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:46:42 AM             192.168.0.11         199.47.217.146
5156 Microsoft-Windows-Security-Auditing 8/25/2012 9:46:24 AM             192.168.0.11         255.255.255.255

...


Now we will do some quick analysis courtesy of the 'group-object' command:


$SearchResult= $a | Select ID,RecordID,TimeCreated, `
@{Name='SourceAddress';Expression={(($_.Message | findstr /C:'Source Address:').replace("Source Address:","")).Normalize()}}, `
@{Name='DestinationAddress';Expression={(($_.Message | findstr /C:'Destination Address:').replace("Destination Address:","")).Normalize()}}

$SearchResult | group -property ID -noelement | Sort -desc -property Count


Count Name

----- ----
 2565 5158
 2369 5156
  898 1035
  751 7036
   66 5157
   56 1
   33 7042
   32 7040
   29 257
   27 42
   27 0
...

$SearchResult | Select SourceAddress,DestinationAddress | Sort -unique -desc -property SourceAddress,DestinationAddress


SourceAddress                                                                                       DestinationAddress

-------------                                                                                       ------------------
            fe80::ffff:ffff:fffe                                                                            ff02::2
            fe80::ffff:ffff:fffe                                                                            ff02::16
            fe80::cddc:ceef:b717:a5ac                                                                       ff02::1:3
            fe80::46:eb0:3f57:fff4                                                                          ff02::2
            fe80::3069:3e11:3f57:fff4                                                                       ff02::2
            fe80::3069:3e11:3f57:fff4                                                                       ff02::16
            fe80::1468:390c:3f57:fff4                                                                       ff02::2
            fe80::1468:390c:3f57:fff4                                                                       ff02::16
            255.255.255.255                                                                                 0.0.0.0
            239.255.255.250                                                                                 127.0.0.1
            224.0.0.252                                                                                     192.168.0.11
            224.0.0.22                                                                                      192.168.0.11
            199.47.216.177                                                                                  192.168.0.11
            192.168.0.11                                                                                    98.138.49.43
            192.168.0.11                                                                                    98.137.49.1
            192.168.0.11                                                                                    98.124.156.54
            192.168.0.11                                                                                    96.17.239.144
            192.168.0.11                                                                                    96.17.237.177


$SearchResult | group -property SourceAddress,DestinationAddress -noelement | Sort -desc -property Count | ft -auto


Count Name

----- ----
 2170             0.0.0.0
 2000
  617             192.168.0.11,         192.168.0.1
  113             192.168.0.11
  110             192.168.0.11,         199.47.217.146
  109             ::
   99             127.0.0.1
   89             192.168.0.11,         255.255.255.255
   81             192.168.0.11,         192.168.0.255
   74             ::1
   50             239.255.255.250,         127.0.0.1
   48             192.168.0.11,         12.129.210.71
   48             192.168.0.11,         184.73.175.201
   44             192.168.0.11,         224.0.0.252
   33             192.168.0.11,         224.0.0.22
   28             192.168.0.11,         173.192.226.196
   27             192.168.0.11,         96.17.237.177
   26             255.255.255.255,         0.0.0.0
   23             192.168.0.11,         64.94.107.64
....
#Note: Using Normalize() doesn't help me here...
[array[]]$Tuple=($SearchResult | group -property SourceAddress,DestinationAddress -noelement | Sort -desc -property Count | Select Name) -replace(",","") -replace("  ","")
[array[]]$Tuple=$Tuple.replace("@{Name=","") -replace("}","")

$Tuple[0..100]

                        0.0.0.0

                        192.168.0.11            192.168.0.1

                        192.168.0.11
                        192.168.0.11            199.47.217.146
                        ::
                        127.0.0.1
                        192.168.0.11            255.255.255.255
                        192.168.0.11            192.168.0.255
                        ::1
                        239.255.255.250                 127.0.0.1
                        192.168.0.11            12.129.210.71
                        192.168.0.11            184.73.175.201
                        192.168.0.11            224.0.0.252
                        192.168.0.11            224.0.0.22
                        192.168.0.11            173.192.226.196
                        192.168.0.11            96.17.237.177
                        255.255.255.255                 0.0.0.0
                        192.168.0.11            64.94.107.64
                        224.0.0.252             192.168.0.11
                        192.168.0.11            174.137.34.100
                        192.168.0.11            239.255.255.250
                        192.168.0.11            23.3.68.139
                        127.0.0.1               127.0.0.1
                        192.168.0.11            173.192.226.197
                        192.168.0.11            184.73.247.29
                        192.168.0.11            199.47.216.177
                        0.0.0.0                 255.255.255.255

...