A little more about graphs, or how to detect dependencies between your applications.
- Tutorial
Good time of day, colleagues. Recently, quite a lot of talk about the transfer of applications from physical infrastructures, read data centers, to the cloud. For example, in Microsoft Azure . Well, or in general, about any other transfer of one or several applications from one place to another. One of the biggest problems in such tasks is the need to find all external dependencies of the application. This does not mean dependencies in the code, but dependencies on external, in relation to the application, systems. As a matter of fact, sometimes we need to find with whom our proposal is talking, and who is talking to him. How to do this if we do not have a deployed SIEM, so to say means "SIEM for the poor." As a matter of fact, for systems on Windows there is the following sentence.
We need:
- Enable logging to the Windows Firewall on all machines one way or another associated with the application
- Download to PSQuickGraph module admin station
- Collect and analyze logs, build a connection graph
In the simplest form, log analysis looks like this. Terrible, in the forehead, but what can you do. In fact, I was even too lazy to write logic for a run through the logs, I just copied everything twice. But for our purposes, "roughly and to the forehead" will also go to show the idea.
$f = gc "C:\Temp\pfirewall_public.log"
$regex = '^(?<datetime>\d{4,4}-\d{2,2}-\d{2,2}\s\d{2}:\d{2}:\d{2})\s(?<action>\w+)\s(?<protocol>\w+)\s(?<srcip>\b(?:\d{1,3}\.){3}\d{1,3}\b)\s(?<dstip>\b(?:\d{1,3}\.){3}\d{1,3}\b)\s(?<srcport>\d{1,5})\s(?<dstport>\d{1,5})\s(?<size>\d+|-)\s(?<tcpflags>\d+|-)\s(?<tcpsyn>\d+|-)\s(?<tcpack>\d+|-)\s(?<tcpwin>\d+|-)\s(?<icmptype>\d+|-)\s(?<icmpcode>\d+|-)\s(?<info>\d+|-)\s(?<path>.+)$'
$log =
$f | % {
$_ -match $regex | Out-Null
if ($Matches) {
[PSCustomObject]@{
action = $Matches.action
srcip = [ipaddress]$Matches.srcip
dstport = $Matches.dstport
tcpflags = $Matches.tcpflags
dstip = [ipaddress]$Matches.dstip
info = $Matches.info
size = $Matches.size
protocol = $Matches.protocol
tcpack = $Matches.tcpac
srcport = $Matches.srcport
tcpsyn = $Matches.tcpsyn
datetime = [datetime]$Matches.datetime
icmptype = $Matches.icmptype
tcpwin = $Matches.tcpwin
icmpcode = $Matches.icmpcode
path = $Matches.path
}
}
}
$f = gc "C:\Temp\pfirewall_public2.log"
$log2 =
$f | % {
$_ -match $regex | Out-Null
if ($Matches) {
[PSCustomObject]@{
action = $Matches.action
srcip = [ipaddress]$Matches.srcip
dstport = $Matches.dstport
tcpflags = $Matches.tcpflags
dstip = [ipaddress]$Matches.dstip
info = $Matches.info
size = $Matches.size
protocol = $Matches.protocol
tcpack = $Matches.tcpac
srcport = $Matches.srcport
tcpsyn = $Matches.tcpsyn
datetime = [datetime]$Matches.datetime
icmptype = $Matches.icmptype
tcpwin = $Matches.tcpwin
icmpcode = $Matches.icmpcode
path = $Matches.path
}
}
}
$l = $log + $log2
$g = new-graph -Type BidirectionalGraph
$l | ? {$_.srcip -and $_.dstip} | % {
Add-Edge -From $_.srcip -To $_.dstip -Graph $g | out-null
}
Show-GraphLayout -Graph $g
As a matter of fact, in this example, we simply parse the Windows Firewall log using a regular expression, breaking it into objects - one object per line. God bless her with RAM, we won't die. In this example, we have two logs from two different machines. After parsing, we simply merge everything into one large array and search through it, adding vertices and edges of the graph. Well, as a result - we display it. So, approximately, it looks as a result:
I hope someone will come in handy.