diff --git a/pandora_server/util/plugin/wizard_snmp_module.pl b/pandora_server/util/plugin/wizard_snmp_module.pl new file mode 100755 index 0000000000..ae1d739864 --- /dev/null +++ b/pandora_server/util/plugin/wizard_snmp_module.pl @@ -0,0 +1,308 @@ +#!/usr/bin/perl +# +################################################################################ +# +# SNMP wizard module +# +# Requirements: +# Net::SNMP +# Crypt::DES +# Digest::SHA1 +# +# (c) Enrique Martin Garcia +# +# 2020/03/10 +# +################################################################################ + +use strict; +use warnings; + +use POSIX qw(strftime); + +use Encode; +use Encode::Locale; +use Getopt::Long; +use Net::SNMP; + +my $HELP=<" -version "" [SNMP] [SNMPv3] -oidList "," -operation "" + +-host Target host +-version SNMP version (1, 2c, 3) + +-oidList Comma separated OIDs used +-operation Aritmetic operation to get data. + Macros _oN_ will be changed by OIDs in list. + Example: (_o1_ * 100) / _o2_ + +[SNMP] + -community Community (only version 1 and 2c) + -port Target UDP port (Default 161) + +[SNMPv3] + -user Username + -authMethod Authentication method (MD5, SHA) + -authPass Authentication password + -privMethod Privacy method (DES, AES) + -privPass Privacy password + -secLevel Security level (noAuthNoPriv, authNoPriv, authPriv) + +Example: $0 -host 192.168.80.43 -community public -version 1 -oidlist "1.3.6.1.2.1.2.2.1.10.1,1.3.6.1.2.1.2.2.1.16.1" -operation "_o1_ + _o2_" + +EO_HELP + +# +# FUNCTIONS +############## + +sub new_snmp_target { + my ($config) = @_; + my $target; + my $error; + + if ($config->{'version'} ne '3'){ + ($target, $error) = Net::SNMP->session( + -hostname => $config->{'host'}, + -port => $config->{'port'}, + -version => $config->{'version'}, + -timeout => $config->{'timeout'}, + -translate => 0, + -community => $config->{'community'} + ); + }else{ + if ($config->{'sec_level'} =~ /^noAuthNoPriv$/i){ + ($target, $error) = Net::SNMP->session( + -hostname => $config->{'host'}, + -port => $config->{'port'}, + -version => $config->{'version'}, + -timeout => $config->{'timeout'}, + -translate => 0, + -username => $config->{'user'} + ); + }elsif ($config->{'sec_level'} =~ /^authNoPriv$/i){ + ($target, $error) = Net::SNMP->session( + -hostname => $config->{'host'}, + -port => $config->{'port'}, + -version => $config->{'version'}, + -timeout => $config->{'timeout'}, + -translate => 0, + -username => $config->{'user'}, + -authpassword => $config->{'auth_pass'}, + -authprotocol => $config->{'auth_method'} + ); + }elsif ($config->{'sec_level'} =~ /^authPriv$/i){ + ($target, $error) = Net::SNMP->session( + -hostname => $config->{'host'}, + -port => $config->{'port'}, + -version => $config->{'version'}, + -timeout => $config->{'timeout'}, + -translate => 0, + -username => $config->{'user'}, + -authpassword => $config->{'auth_pass'}, + -authprotocol => $config->{'auth_method'}, + -privpassword => $config->{'priv_pass'}, + -privprotocol => $config->{'priv_method'} + ); + } + } + + + return ($target, $error); +} + +sub snmp_walk { + my ($target, $oid) = @_; + my $result = {}; + + my $walk = $target->get_table( + -baseoid => $oid, + ); + + if (defined($walk)){ + $result = $walk; + } + + return $result; +} + +sub snmp_get { + my ($target, $oid) = @_; + my $result = ''; + + my $get = $target->get_request( + -varbindlist => [$oid], + ); + + if (defined($get)){ + $result = $get->{$oid}; + } + + return $result; +} + +# +# MAIN +############## + +@ARGV = map { decode(locale => $_, 1) } @ARGV if -t STDIN; +binmode STDOUT, ":encoding(console_out)" if -t STDOUT; +binmode STDERR, ":encoding(console_out)" if -t STDERR; + +my %Param = (); +GetOptions( + \%Param, + # General + 'community=s', + 'version=s', + 'host=s', + 'port=s', + 'timeout=s', + # Version 3 + 'user=s', + 'authMethod=s', + 'authPass=s', + 'privMethod=s', + 'privPass=s', + 'secLevel=s', + # Operation + 'oidList=s', + 'operation=s', + # Help option + 'Help', +); + +if ($Param{Help}){ + print $HELP; + exit 0; +} + +my $config; + +# General parameters +$config->{'community'} = $Param{community} || ''; +$config->{'version'} = $Param{version} || ''; +$config->{'host'} = $Param{host} || ''; +$config->{'port'} = $Param{port} || '161'; +$config->{'timeout'} = $Param{timeout} || '2'; + +# Version 3 parameters +$config->{'auth_method'} = $Param{authMethod} || ''; +$config->{'user'} = $Param{user} || ''; +$config->{'auth_pass'} = $Param{authPass} || ''; +$config->{'priv_method'} = $Param{privMethod} || ''; +$config->{'priv_pass'} = $Param{privPass} || ''; +$config->{'sec_level'} = $Param{secLevel} || ''; + +$config->{'auth_method'} = uc($config->{'auth_method'}); +$config->{'priv_method'} = uc($config->{'priv_method'}); + +# Operation +my $operation = $Param{operation} || ''; + +# OIDs +my @oid_list = split /,/, $Param{oidList} || ''; + +# Verify parameters +if (!$config->{'host'} || !$config->{'version'} || !$operation || !@oid_list){ + print $HELP; + print "Host, version, OID list and operation are required.\n"; + exit 1; +} + +if ($config->{'version'} ne '1' && $config->{'version'} ne '2c' && $config->{'version'} ne '3'){ + print $HELP; + print "Invalid SNMP version provided.\n"; + exit 1; +} + +if ($config->{'version'} eq '1' || $config->{'version'} eq '2c'){ + if (!$config->{'community'}){ + print $HELP; + print "SNMP community required for version 1 or 2c.\n"; + exit 1; + } +} + +if ($config->{'version'} eq '3'){ + if ($config->{'sec_level'} =~ /^noAuthNoPriv$/i){ + if (!$config->{'user'}){ + print $HELP; + print "Username required for SNMP version 3 and security level 'noAuthNoPriv'.\n"; + exit 1; + } + }elsif ($config->{'sec_level'} =~ /^authNoPriv$/i){ + if (!$config->{'user'} && !$config->{'auth_pass'} && !$config->{'auth_method'}){ + print $HELP; + print "Username, authentication password and authentication method required for SNMP version 3 and security level 'authNoPriv'.\n"; + exit 1; + } + }elsif ($config->{'sec_level'} =~ /^authPriv$/i){ + if (!$config->{'user'} && !$config->{'auth_pass'} && !$config->{'auth_method'} && !$config->{'priv_pass'} && !$config->{'priv_method'}){ + print $HELP; + print "Username, authentication password, authentication method, privacy password and privacy method required for SNMP version 3 and security level 'authPriv'.\n"; + exit 1; + } + }else{ + print $HELP; + print "Invalid SNMP security level provided for version 3.\n"; + exit 1; + } + + if ($config->{'auth_method'} && $config->{'auth_method'} ne 'MD5' && $config->{'auth_method'} ne 'SHA'){ + print $HELP; + print "Invalid SNMP authentication method provided for version 3.\n"; + exit 1; + } + + if ($config->{'priv_method'} && $config->{'priv_method'} ne 'DES' && $config->{'priv_method'} ne 'AES'){ + print $HELP; + print "Invalid SNMP privacy method provided for version 3.\n"; + exit 1; + } +} + +# Verify operation (avoid code injection) +my @operation = split //, lc($operation); + +foreach my $op (@operation){ + if ($op !~ /\d/ && $op ne ' ' && $op ne '(' && $op ne ')' && $op ne '_' && $op ne '-' && $op ne '+' && $op ne '*' && $op ne '/' && $op ne 'o'){ + print $HELP; + print "Specified operation has invalid characters: " . $op . "\n"; + exit 1; + } +} + +# Create SNMP target +my ($target, $error) = new_snmp_target($config); + +if (!$target){ + print $error . "\n"; + exit 1; +} + +# Get OIDs values +my $oid_values = {}; +my $i = 1; +foreach my $oid (@oid_list){ + $oid_values->{'_o' . $i . '_'} = snmp_get($target, $oid); + $i++; +} + +# Change operation macros with values +$i = 1; +foreach my $k (keys %{$oid_values}){ + my $oid_macro = '_o' . $i . '_'; + my $value = $oid_values->{$oid_macro}; + $operation =~ s/$oid_macro/$value/g; + $i++; +} + +# Get operation result +my $result = eval $operation; +if (defined($result)){ + print $result . "\n"; +} \ No newline at end of file diff --git a/pandora_server/util/plugin/wizard_snmp_process.pl b/pandora_server/util/plugin/wizard_snmp_process.pl new file mode 100755 index 0000000000..c510de1171 --- /dev/null +++ b/pandora_server/util/plugin/wizard_snmp_process.pl @@ -0,0 +1,282 @@ +#!/usr/bin/perl +# +################################################################################ +# +# SNMP wizard process +# +# Requirements: +# Net::SNMP +# Crypt::DES +# Digest::SHA1 +# +# (c) Enrique Martin Garcia +# +# 2020/03/10 +# +################################################################################ + +use strict; +use warnings; + +use POSIX qw(strftime); + +use Encode; +use Encode::Locale; +use Getopt::Long; +use Net::SNMP; + +my $HELP=<" -version "" [SNMP] [SNMPv3] -process "" + +-host Target host +-version SNMP version (1, 2c, 3) + +-process Process name to check if is running (case sensitive) + +[SNMP] + -community Community (only version 1 and 2c) + -port Target UDP port (Default 161) + +[SNMPv3] + -user Username + -authMethod Authentication method (MD5, SHA) + -authPass Authentication password + -privMethod Privacy method (DES, AES) + -privPass Privacy password + -secLevel Security level (noAuthNoPriv, authNoPriv, authPriv) + +Example: $0 -host 192.168.80.43 -community public -version 1 -process "httpd" + +EO_HELP + +# +# FUNCTIONS +############## + +sub new_snmp_target { + my ($config) = @_; + my $target; + my $error; + + if ($config->{'version'} ne '3'){ + ($target, $error) = Net::SNMP->session( + -hostname => $config->{'host'}, + -port => $config->{'port'}, + -version => $config->{'version'}, + -timeout => $config->{'timeout'}, + -translate => 0, + -community => $config->{'community'} + ); + }else{ + if ($config->{'sec_level'} =~ /^noAuthNoPriv$/i){ + ($target, $error) = Net::SNMP->session( + -hostname => $config->{'host'}, + -port => $config->{'port'}, + -version => $config->{'version'}, + -timeout => $config->{'timeout'}, + -translate => 0, + -username => $config->{'user'} + ); + }elsif ($config->{'sec_level'} =~ /^authNoPriv$/i){ + ($target, $error) = Net::SNMP->session( + -hostname => $config->{'host'}, + -port => $config->{'port'}, + -version => $config->{'version'}, + -timeout => $config->{'timeout'}, + -translate => 0, + -username => $config->{'user'}, + -authpassword => $config->{'auth_pass'}, + -authprotocol => $config->{'auth_method'} + ); + }elsif ($config->{'sec_level'} =~ /^authPriv$/i){ + ($target, $error) = Net::SNMP->session( + -hostname => $config->{'host'}, + -port => $config->{'port'}, + -version => $config->{'version'}, + -timeout => $config->{'timeout'}, + -translate => 0, + -username => $config->{'user'}, + -authpassword => $config->{'auth_pass'}, + -authprotocol => $config->{'auth_method'}, + -privpassword => $config->{'priv_pass'}, + -privprotocol => $config->{'priv_method'} + ); + } + } + + + return ($target, $error); +} + +sub snmp_walk { + my ($target, $oid) = @_; + my $result = {}; + + my $walk = $target->get_table( + -baseoid => $oid, + ); + + if (defined($walk)){ + $result = $walk; + } + + return $result; +} + +sub snmp_get { + my ($target, $oid) = @_; + my $result = ''; + + my $get = $target->get_request( + -varbindlist => [$oid], + ); + + if (defined($get)){ + $result = $get->{$oid}; + } + + return $result; +} + +# +# MAIN +############## + +@ARGV = map { decode(locale => $_, 1) } @ARGV if -t STDIN; +binmode STDOUT, ":encoding(console_out)" if -t STDOUT; +binmode STDERR, ":encoding(console_out)" if -t STDERR; + +my %Param = (); +GetOptions( + \%Param, + # General + 'community=s', + 'version=s', + 'host=s', + 'port=s', + 'timeout=s', + # Version 3 + 'user=s', + 'authMethod=s', + 'authPass=s', + 'privMethod=s', + 'privPass=s', + 'secLevel=s', + # Process + 'process=s', + # Help option + 'Help', +); + +if ($Param{Help}){ + print $HELP; + exit 0; +} + +my $config; + +# General parameters +$config->{'community'} = $Param{community} || ''; +$config->{'version'} = $Param{version} || ''; +$config->{'host'} = $Param{host} || ''; +$config->{'port'} = $Param{port} || '161'; +$config->{'timeout'} = $Param{timeout} || '2'; + +# Version 3 parameters +$config->{'auth_method'} = $Param{authMethod} || ''; +$config->{'user'} = $Param{user} || ''; +$config->{'auth_pass'} = $Param{authPass} || ''; +$config->{'priv_method'} = $Param{privMethod} || ''; +$config->{'priv_pass'} = $Param{privPass} || ''; +$config->{'sec_level'} = $Param{secLevel} || ''; + +$config->{'auth_method'} = uc($config->{'auth_method'}); +$config->{'priv_method'} = uc($config->{'priv_method'}); + +# Operation +my $process = $Param{process} || ''; + +# Verify parameters +if (!$config->{'host'} || !$config->{'version'} || !$process){ + print $HELP; + print "Host, version and process are required.\n"; + exit 1; +} + +if ($config->{'version'} ne '1' && $config->{'version'} ne '2c' && $config->{'version'} ne '3'){ + print $HELP; + print "Invalid SNMP version provided.\n"; + exit 1; +} + +if ($config->{'version'} eq '1' || $config->{'version'} eq '2c'){ + if (!$config->{'community'}){ + print $HELP; + print "SNMP community required for version 1 or 2c.\n"; + exit 1; + } +} + +if ($config->{'version'} eq '3'){ + if ($config->{'sec_level'} =~ /^noAuthNoPriv$/i){ + if (!$config->{'user'}){ + print $HELP; + print "Username required for SNMP version 3 and security level 'noAuthNoPriv'.\n"; + exit 1; + } + }elsif ($config->{'sec_level'} =~ /^authNoPriv$/i){ + if (!$config->{'user'} && !$config->{'auth_pass'} && !$config->{'auth_method'}){ + print $HELP; + print "Username, authentication password and authentication method required for SNMP version 3 and security level 'authNoPriv'.\n"; + exit 1; + } + }elsif ($config->{'sec_level'} =~ /^authPriv$/i){ + if (!$config->{'user'} && !$config->{'auth_pass'} && !$config->{'auth_method'} && !$config->{'priv_pass'} && !$config->{'priv_method'}){ + print $HELP; + print "Username, authentication password, authentication method, privacy password and privacy method required for SNMP version 3 and security level 'authPriv'.\n"; + exit 1; + } + }else{ + print $HELP; + print "Invalid SNMP security level provided for version 3.\n"; + exit 1; + } + + if ($config->{'auth_method'} && $config->{'auth_method'} ne 'MD5' && $config->{'auth_method'} ne 'SHA'){ + print $HELP; + print "Invalid SNMP authentication method provided for version 3.\n"; + exit 1; + } + + if ($config->{'priv_method'} && $config->{'priv_method'} ne 'DES' && $config->{'priv_method'} ne 'AES'){ + print $HELP; + print "Invalid SNMP privacy method provided for version 3.\n"; + exit 1; + } +} + +# Create SNMP target +my ($target, $error) = new_snmp_target($config); + +if (!$target){ + print $error . "\n"; + exit 1; +} + +# Get all running processes +my $processes = snmp_walk($target, '.1.3.6.1.2.1.25.4.2.1.2'); + +my $result = 0; + +# Search process name +foreach my $k (keys %{$processes}){ + if ($processes->{$k} eq $process){ + $result = 1; + last; + } +} + +print $result . "\n"; \ No newline at end of file diff --git a/pandora_server/util/plugin/wizard_wmi_module.pl b/pandora_server/util/plugin/wizard_wmi_module.pl new file mode 100755 index 0000000000..3cb1661da9 --- /dev/null +++ b/pandora_server/util/plugin/wizard_wmi_module.pl @@ -0,0 +1,176 @@ +#!/usr/bin/perl +# +################################################################################ +# +# WMI wizard module +# +# Requirements: +# wmic +# +# (c) Enrique Martin Garcia +# +# 2020/03/10 +# +################################################################################ + +use strict; +use warnings; + +use POSIX qw(strftime); + +use Encode; +use Encode::Locale; +use Getopt::Long; + +use Data::Dumper; + +my $HELP=<"] -host "" [-namespace ""] -user "" -pass "" -wmiClass "" -fieldsList "" [-queryFilter ""] -operation "" + +-wmicPath Path to wmic command (Default: /usr/bin/wmic) + +-host Target host +-namespace WMI namespace +-user Windows username ([domain/]username) +-pass User password + +-wmiClass WMI class for query (Example: Win32_OperatingSystem) +-fieldsList Comma separated class fields list (Example: TotalVisibleMemorySize,FreePhysicalMemory) +-queryFilter WMI query class filter (Example: DeviceID = 3 AND DeviceType = 1) + +-operation Aritmetic operation to get data. + Macros _fN_ will be changed by fields in list. + Example: ((_f1_ - _f2_) * 100) / _f1_ + +Example: $0 -host "192.168.80.43" -user "pandora/Administrator" -pass "PandoraFMS1234" -wmiClass "Win32_OperatingSystem" -fieldsList "TotalVisibleMemorySize,FreePhysicalMemory" -operation "((_f1_ - _f2_) * 100) / _f1_" + +EO_HELP + +# +# MAIN +############## + +@ARGV = map { decode(locale => $_, 1) } @ARGV if -t STDIN; +binmode STDOUT, ":encoding(console_out)" if -t STDOUT; +binmode STDERR, ":encoding(console_out)" if -t STDERR; + +my %Param = (); +GetOptions( + \%Param, + # General + 'wmicPath=s', + 'host=s', + 'namespace=s', + 'user=s', + 'pass=s', + # Query + 'wmiClass=s', + 'fieldsList=s', + 'queryFilter=s', + # Operation + 'operation=s', + # Help option + 'Help', +); + +if ($Param{Help}){ + print $HELP; + exit 0; +} + +my $config; + +# General parameters +$config->{'wmicPath'} = $Param{wmicPath} || '/usr/bin/wmic'; +$config->{'host'} = $Param{host} || ''; +$config->{'namespace'} = $Param{namespace} || ''; +$config->{'user'} = $Param{user} || ''; +$config->{'pass'} = $Param{pass} || ''; + +# Query parameters +$config->{'wmiClass'} = $Param{wmiClass} || ''; +$config->{'queryFilter'} = $Param{queryFilter} || ''; +$config->{'fieldsList'} = $Param{fieldsList} || ''; + +# Operation +my $operation = $Param{operation} || ''; + +# Fields +my @fields_list = split /,/, $config->{'fieldsList'} || ''; + +# Verify parameters +if (!$config->{'host'} || !$config->{'user'} || !$config->{'pass'} || !$config->{'wmiClass'} || !@fields_list || !$operation){ + print $HELP; + print "Host, user, password, WMI class, fields list and operation are required.\n"; + exit 1; +} + +# Verify operation (avoid code injection) +my @operation = split //, lc($operation); + +foreach my $op (@operation){ + if ($op !~ /\d/ && $op ne ' ' && $op ne '(' && $op ne ')' && $op ne '_' && $op ne '-' && $op ne '+' && $op ne '*' && $op ne '/' && $op ne 'f'){ + print $HELP; + print "Specified operation has invalid characters: " . $op . "\n"; + exit 1; + } +} + +# Build WMI query +my $wmi_query = 'SELECT ' . $config->{'fieldsList'} . ' FROM ' . $config->{'wmiClass'} . ($config->{'queryFilter'} ? ' WHERE ' . $config->{'queryFilter'} : ''); + +# Build wmic command +my $wmi_command = $config->{'wmicPath'} . ' -U ' . $config->{'user'} . '%' . $config->{'pass'} . ($config->{'namespace'} ? ' --namespace="' . $config->{'namespace'} . '"' : '') . ' //' . $config->{'host'} . ' "' . $wmi_query . '"'; + +# Run wmic and parse output +my $output = `$wmi_command 2>/dev/null`; + +my @data = split("\n", $output); + +if ($data[0] ne 'CLASS: ' . $config->{'wmiClass'}){ + print $output; + exit 1; +} + +# Parse fields positions +my @fields_pos; + +my $i = 0; +foreach my $field (split /\|/, $data[1]){ + my $x = 1; + foreach my $f (@fields_list){ + $f =~ s/^\s*//; + $f =~ s/\s*$//; + if (lc($field) eq lc($f)){ + $fields_pos[$i] = $x; + } + $x++; + } + $i++; +} + +# Get fields values +my $fields_values = {}; +$i = 0; +foreach my $field_value (split /\|/, $data[2]){ + $fields_values->{'_f' . $fields_pos[$i] . '_'} = $field_value; + $i++; +} + +# Change operation macros with values +$i = 1; +foreach my $k (keys %{$fields_values}){ + my $field_macro = '_f' . $i . '_'; + my $value = $fields_values->{$field_macro}; + $operation =~ s/$field_macro/$value/g; + $i++; +} + +# Get operation result +my $result = eval $operation; +if (defined($result)){ + print $result . "\n"; +} \ No newline at end of file