PowerShell : loguer l’activité réseau des process Windows
Je vous ai parlé de Salwa, doctorante à l’université de Lorient dont la thèse porte sur la cybersécurité des équipements connectés industriels. Je lui ai fourni toute une liste d’outils pour monitorer les process sous Windows. Je lui ai promis l’écriture d’un script en PowerShell, afin de loguer l’activité réseau des process sous Windows. Ça tombe bien : la semaine prochaine, je donne une formation de 3 jours sur le PowerShell ! J’avais besoin de me refaire un peu la main.
Activer l’audit de l’accès aux objets
La condition pour que le script présenté ci-dessous fonctionne est d’auditer l’accès aux objets, à partir de la console gpedit.msc :
Configuration ordinateur > Paramètre Windows > Paramètres de sécurité > Stratégies locales > Stratégie d'audit > Auditer l'accès aux objets
Dès lors, le journal de sécurité – dans le journal d’événements accessibles à partir de la console eventvwr.msc – consigne l’activité du pare-feu Windows, à la condition qu’il soit activé ! Les événements à tracer sont le 5156 pour un paquet accepté et le 5157 pour un paquet refusé.
Loguer l’activité réseau des process par un script PowerShell
Les deux paramètres de ce script sont le nombre de lignes – $rows – à remonter lors de la 1ère exécution de la cmdlet Get-EventLog et la fréquence – $timer – de lecture du journal. Le script est une boucle infinie qui envoie dans un fichier CSV – par défaut c:\windows\processnetwork.log – selon la valeur de $timer, la date, le process, le statut (bloqué/pas bloqué), la direction du paquet, les ports et adresses sortants et entrants.
$path=$env:SystemRoot+"\processnetwork.log" #Liste des protocoles indexés par leur numéro $protocols=@{'0'='HOPOPT';'1'='ICMP';'2'='IGMP';'3'='GGP';'4'='IP-in-IP';'5'='ST';'6'='TCP';'7'='CBT';'8'='EGP';'9'='IGP';'10'='BBN-RCC-MON';'11'='NVP-II';'12'='PUP';'13'='ARGUS';'14'='EMCON';'15'='XNET';'16'='CHAOS';'17'='UDP';'18'='MUX';'19'='DCN-MEAS';'20'='HMP';'21'='PRM';'22'='XNS-IDP';'23'='TRUNK-1';'24'='TRUNK-2';'25'='LEAF-1';'26'='LEAF-2';'27'='RDP';'28'='IRTP';'29'='ISO-TP4';'30'='NETBLT';'31'='MFE-NSP';'32'='MERIT-INP';'33'='DCCP';'34'='3PC';'35'='IDPR';'36'='XTP';'37'='DDP';'38'='IDPR-CMTP';'39'='TP++';'40'='IL';'41'='IPv6';'42'='SDRP';'43'='IPv6-Route';'44'='IPv6-Frag';'45'='IDRP';'46'='RSVP';'47'='GREs';'48'='DSR';'49'='BNA';'50'='ESP';'51'='AH';'52'='I-NLSP';'53'='SWIPE';'54'='NARP';'55'='MOBILE';'56'='TLSP';'57'='SKIP';'58'='IPv6-ICMP';'59'='IPv6-NoNxt';'60'='IPv6-Opts';'62'='CFTP';'64'='SAT-EXPAK';'65'='KRYPTOLAN';'66'='RVD';'67'='IPPC';'69'='SAT-MON';'70'='VISA';'71'='IPCU';'72'='CPNX';'73'='CPHB';'74'='WSN';'75'='PVP';'76'='BR-SAT-MON';'77'='SUN-ND';'78'='WB-MON';'79'='WB-EXPAK';'80'='ISO-IP';'81'='VMTP';'82'='SECURE-VMTP';'83'='VINES';'84'='TTP/IPTM';'85'='NSFNET-IGP';'86'='DGP';'87'='TCF';'88'='EIGRP';'89'='OSPF';'90'='Sprite-RPC';'91'='LARP';'92'='MTP';'93'='AX.25';'94'='OS';'95'='MICP';'96'='SCC-SP';'97'='ETHERIP';'98'='ENCAP';'100'='GMTP';'101'='IFMP';'102'='PNNI';'103'='PIM';'104'='ARIS';'105'='SCPS';'106'='QNX';'107'='A/N';'108'='IPComp';'109'='SNP';'110'='Compaq-Peer';'111'='IPX-in-IP';'112'='VRRP';'113'='PGM';'115'='L2TP';'116'='DDX';'117'='IATP';'118'='STP';'119'='SRP';'120'='UTI';'121'='SMP';'122'='SM';'123'='PTP';'124'='IS-IS over IPv4';'125'='FIRE';'126'='CRTP';'127'='CRUDP';'128'='SSCOPMCE';'129'='IPLT';'130'='SPS';'131'='PIPE';'132'='SCTP';'133'='FC';'134'='RSVP-E2E-IGNORE';'135'='Mobility Header';'136'='UDPLite';'137'='MPLS-in-IP';'138'='manet';'139'='HIP';'140'='Shim6';'141'='WESP';'142'='ROHC'} #Nombre de lignes sur lesquelles porte l'exécution du 1er Get-EventLog $rows=10000 #Intervalle d'exécution en secondes. Plus elle est longue, plus le nombre de lignes à analyser est importante #Un trop grand intervalle risque de faire perdre le processus $timer=5 #Pour extraire des Logs au delà de cette valeur $limite=Get-Date #Boucle infinie while($true) { #On attend en fonction de la valeur $timer Start-Sleep -Seconds $timer #On extrait les logs $logs=Get-EventLog -LogName Security -Newest $rows|Select EventId,TimeGenerated,CategoryNumber, Message|Where {$_.EventId -in 5156,5157 -and $_.CategoryNumber -eq 12810} #S'il y a quelque chose dans les logs, on traite If($logs) { #$max, $min servent à ajuster le nombre de lignes $max=($logs|Measure TimeGenerated -Maximum).Maximum $min=($logs|Measure TimeGenerated -Minimum).Minimum #Ajustement du nombre de lignes $temps=((Get-Date $max) - (Get-Date $min)).TotalSeconds If($temps -eq 0) { $temps=1 } $rows=[int]($rows/$temps*$timer/0.8) #Filtrage sur la limite $logs=$logs |Select TimeGenerated,EventId,Message| Where TimeGenerated -gt $limite #passe de limite à Max $limite=$max ForEach($log in $logs) { $datetime=Get-Date $log.TimeGenerated -format 'dd/MM/yyyy HH:mm:ss' #Statut pass/block fonction de la valeur de EventId 5156/5157 $statut=$log.EventId If($statut -eq 5156) { $statut='pass' } ElseIf($statut -eq 5157) { $statut='block' } $message=$log.Message #Récupération du nom de l'application à partir du corps du message $application='' If($message -match "Nom de l’application[^:]+:[ \t]+([^\r]+)[\r]") { $application=$Matches[1] } #Détermination de la direction du paquet : in/out $direction='' If($message -match "Direction[^:]+:[^%]+%%(1459[23])[\r]") { $direction=$Matches[1] If($direction -eq 14593) { $direction='out' } ElseIf($direction -eq 14592) { $direction='in' } } #Protocole indicé par le numéro déclaré dans le tableau associatif $protocols $protocole='' If($message -match "Protocole[^:]+:[^0-9]+([0-9]+)[\r]") { $protocole=$Matches[1] $protocole=$protocols["$protocole"] } #Port source $srcport='' If($message -match "Port source[^:]+:[^0-9]+([0-9]+)[\r]") { $srcport=$Matches[1] } #Port destination $dstport='' If($message -match "Port de destination[^:]+:[^0-9]+([0-9]+)[\r]") { $dstport=$Matches[1] } #Ip Source $srcip='' If($message -match "Adresse source[^:]+:[^0-9a-f:\.]+([0-9a-f:\.]+)[\r]") { $srcip=$Matches[1] } #Ip Destination $dstip='' If($message -match "Adresse de destination[^:]+:[^0-9a-f:\.]+([0-9a-f:\.]+)[\r]") { $dstip=$Matches[1] } #Ajout au fichier de log $row="$datetime`t$application`t$statut`t$direction`t$protocole`t$srcip`t$srcport`t$dstip`t$dstport" Add-Content -Path $path -value $row } } }