From 1d25aa0850af769badfa22c4541eb4f53cadcc4d Mon Sep 17 00:00:00 2001 From: Guillaume Bougard Date: Thu, 4 Jul 2024 15:49:30 +0200 Subject: [PATCH] feat: Add support for Cortex XDR Antivirus on MacOSX --- Changes | 1 + .../Task/Inventory/MacOS/AntiVirus/Cortex.pm | 82 +++++++++++++++++++ .../Inventory/MacOS/AntiVirus/Defender.pm | 4 + .../antivirus/cortex-xdr-8.2.1.47908-info | 5 ++ .../cortex-xdr-8.2.1.47908-info-query | 5 ++ .../cortex-xdr-8.2.1.47908-runtime-query | 6 ++ t/tasks/inventory/macos/antivirus.t | 13 ++- 7 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 lib/GLPI/Agent/Task/Inventory/MacOS/AntiVirus/Cortex.pm create mode 100644 resources/macos/antivirus/cortex-xdr-8.2.1.47908-info create mode 100644 resources/macos/antivirus/cortex-xdr-8.2.1.47908-info-query create mode 100644 resources/macos/antivirus/cortex-xdr-8.2.1.47908-runtime-query diff --git a/Changes b/Changes index 2d071902e..e63c1384d 100644 --- a/Changes +++ b/Changes @@ -15,6 +15,7 @@ inventory: * fix #565: Add support for Cortex XDR Antivirus on windows. This is also an attempt to start antivirus support on Windows Server based on service detection. +* Add support for Cortex XDR Antivirus on MacOSX * fix #700: Add TacticalRMM Remote_Mgmt module for windows netdiscovery/netinventory: diff --git a/lib/GLPI/Agent/Task/Inventory/MacOS/AntiVirus/Cortex.pm b/lib/GLPI/Agent/Task/Inventory/MacOS/AntiVirus/Cortex.pm new file mode 100644 index 000000000..18b83e42d --- /dev/null +++ b/lib/GLPI/Agent/Task/Inventory/MacOS/AntiVirus/Cortex.pm @@ -0,0 +1,82 @@ +package GLPI::Agent::Task::Inventory::MacOS::AntiVirus::Cortex; + +use strict; +use warnings; + +use parent 'GLPI::Agent::Task::Inventory::Module'; + +use GLPI::Agent::Tools; + +my $command = '/Library/Application Support/PaloAltoNetworks/Traps/bin/cytool'; + +sub isEnabled { + return canRun($command); +} + +sub doInventory { + my (%params) = @_; + + my $inventory = $params{inventory}; + my $logger = $params{logger}; + + my $antivirus = _getCortex(logger => $logger); + if ($antivirus) { + $inventory->addEntry( + section => 'ANTIVIRUS', + entry => $antivirus + ); + + $logger->debug2("Added $antivirus->{NAME}".($antivirus->{VERSION}? " v$antivirus->{VERSION}":"")) + if $logger; + } +} + +sub _getCortex { + my (%params) = @_; + + my $antivirus = { + COMPANY => "Palo Alto Networks", + NAME => "Cortex XDR", + ENABLED => 0, + }; + + # Support file case for unittests if basefile is provided + if (empty($params{basefile})) { + $params{command} = "\"$command\" info"; + } else { + $params{file} = $params{basefile}."-info"; + } + my $version = getFirstMatch( + pattern => qr/^Cortex XDR .* ([0-9.]+)$/, + %params + ); + $antivirus->{VERSION} = $version if $version; + + # Support file case for unittests if basefile is provided + if (empty($params{basefile})) { + $params{command} = "\"$command\" info query"; + } else { + $params{file} = $params{basefile}."-info-query"; + } + my $base_version = getFirstMatch( + pattern => qr/^Content Version:\s+(\S+)$/i, + %params + ); + $antivirus->{BASE_VERSION} = $base_version if $base_version; + + # Support file case for unittests if basefile is provided + if (empty($params{basefile})) { + $params{command} = "\"$command\" runtime query"; + } else { + $params{file} = $params{basefile}."-runtime-query"; + } + my $status = getFirstMatch( + pattern => qr/^\s*pmd\s+\S+\s+\S+\s+(\S+)\s/i, + %params + ); + $antivirus->{ENABLED} = 1 if $status && $status =~ /^Running$/i; + + return $antivirus; +} + +1; diff --git a/lib/GLPI/Agent/Task/Inventory/MacOS/AntiVirus/Defender.pm b/lib/GLPI/Agent/Task/Inventory/MacOS/AntiVirus/Defender.pm index 572d74ee0..7f2dc2879 100644 --- a/lib/GLPI/Agent/Task/Inventory/MacOS/AntiVirus/Defender.pm +++ b/lib/GLPI/Agent/Task/Inventory/MacOS/AntiVirus/Defender.pm @@ -44,6 +44,10 @@ sub _getMSDefender { UPTODATE => 0, }; + # Support file case for unittests if basefile is provided + $params{file} = $params{basefile}.".json" + if exists($params{basefile}); + my $output = getAllLines(%params) or return; diff --git a/resources/macos/antivirus/cortex-xdr-8.2.1.47908-info b/resources/macos/antivirus/cortex-xdr-8.2.1.47908-info new file mode 100644 index 000000000..1ec9a25da --- /dev/null +++ b/resources/macos/antivirus/cortex-xdr-8.2.1.47908-info @@ -0,0 +1,5 @@ +Cortex XDR (R) supervisor tool 8.2.1.47908 +(c) Palo Alto Networks, Inc. All rights reserved + +General Cortex XDR information + diff --git a/resources/macos/antivirus/cortex-xdr-8.2.1.47908-info-query b/resources/macos/antivirus/cortex-xdr-8.2.1.47908-info-query new file mode 100644 index 000000000..a1f28f4ff --- /dev/null +++ b/resources/macos/antivirus/cortex-xdr-8.2.1.47908-info-query @@ -0,0 +1,5 @@ +Content Type: 1270 +Content Build: 79108 +Content Version: 1270-79108 +Event Log: 1 + diff --git a/resources/macos/antivirus/cortex-xdr-8.2.1.47908-runtime-query b/resources/macos/antivirus/cortex-xdr-8.2.1.47908-runtime-query new file mode 100644 index 000000000..30f262df3 --- /dev/null +++ b/resources/macos/antivirus/cortex-xdr-8.2.1.47908-runtime-query @@ -0,0 +1,6 @@ + Name PID User Status Command + cortex xdr 1055 User1 Running /Library/Application Support/PaloAltoNetworks/Traps/bin/cortex xdr.app/Contents/MacOS/cortex xdr + authorized 927 _traps_panw Running /Library/Application Support/PaloAltoNetworks/Traps/bin/authorized + pmd 909 root Running /Library/Application Support/PaloAltoNetworks/Traps/bin/pmd + kproc-ctrl 159 root Loaded com.paloaltonetworks.driver.kproc-ctrl + diff --git a/t/tasks/inventory/macos/antivirus.t b/t/tasks/inventory/macos/antivirus.t index 6290aad61..764926b10 100644 --- a/t/tasks/inventory/macos/antivirus.t +++ b/t/tasks/inventory/macos/antivirus.t @@ -27,6 +27,15 @@ my %av_tests = ( EXPIRATION => "2023-09-06", BASE_CREATION => "2023-05-03", }, + 'cortex-xdr-8.2.1.47908' => { + _module => "Cortex", + _funcion => "_getCortex", + COMPANY => "Palo Alto Networks", + NAME => "Cortex XDR", + ENABLED => 1, + VERSION => "8.2.1.47908", + BASE_VERSION => "1270-79108", + }, ); plan tests => @@ -40,8 +49,8 @@ foreach my $test (sort keys %av_tests) { $module->require(); my $funct_name = $module."::".(delete $av_tests{$test}->{_funcion}); my $function = \&{$funct_name}; - my $file = "resources/macos/antivirus/$test.json"; - my $antivirus = &{$function}(file => $file); + my $basefile = "resources/macos/antivirus/$test"; + my $antivirus = &{$function}(basefile => $basefile); cmp_deeply($antivirus, $av_tests{$test}, "$test: parsing"); lives_ok { $inventory->addEntry(section => 'ANTIVIRUS', entry => $antivirus);