����JFIF��x�x����'
Server IP : 78.140.185.180 / Your IP : 18.218.161.96 Web Server : LiteSpeed System : Linux cpanel13.v.fozzy.com 4.18.0-513.11.1.lve.el8.x86_64 #1 SMP Thu Jan 18 16:21:02 UTC 2024 x86_64 User : builderbox ( 1072) PHP Version : 7.3.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /usr/lib64/nagios/plugins/extra/ |
Upload File : |
#!/usr/bin/env perl use extreme; use LWP::UserAgent; use YAML::XS qw(LoadFile); use JSON::XS; use utf8; use File::Slurp; use File::Basename; use Getopt::Long; use Encode; binmode( STDOUT, ':utf8' ); my ( $d_words, $c_words, $wl, $opt_h ); GetOptions( "h|help" => \$opt_h, 'domain_words=s' => \$d_words, 'content_words=s' => \$c_words, 'wl=s' => \$wl, ); $opt_h = 1 if !$d_words || !$c_words; if ($opt_h) { my $help_text = <<'END'; Usage: %s --domain_words word1,word2 --content_words word1,word2 --wl whitelist_name Search specified words in domain name using --domain_words and on main web-page using --content_words for every domain on server END printf( $help_text, $0 ); exit; } $d_words =~ s/,/|/g; $c_words =~ s/,/|/g; $d_words =~ s/\s//g; $c_words =~ s/\s//g; $d_words = decode_utf8($d_words); $c_words = decode_utf8($c_words); my $domain_regex = qr{($d_words|$c_words)}i; my $content_regex = qr{\b$c_words\b}i; my $WL_DIR = '/etc/icinga2/plinc'; my $WL_FILE = "$WL_DIR/${wl}_wl"; unless ( -e $WL_FILE ) { open my $fh, ">", $WL_FILE; close $fh; } my @wl_items = read_file( $WL_FILE, chomp => 1 ) if -f $WL_FILE; my $ua = LWP::UserAgent->new( timeout => 10, agent => 'Mozilla/5.0', ssl_opts => { verify_hostname => 0 }, protocols_allowed => [ 'http', 'https' ] ); $ua->add_handler( request_prepare => \&request_prepare_cb ); my $domains_owner = get_domains_owner(); my $exit_code = 0; my @incidents; for my $domain ( keys $domains_owner->%* ) { next if $domain =~ /in-addr.arpa$|^$|\*/; next if $domain ~~ @wl_items; next if $domains_owner->{$domain} ~~ @wl_items; if ( $domain =~ /$domain_regex/ ) { push @incidents, "$domains_owner->{$domain}: $domain - $1"; next; } my $result = check_abuse_pattern($domain); if ($result) { push @incidents, "$domains_owner->{$domain}: $domain - $result"; $exit_code = 1; } } @incidents ? say join( "\n", sort @incidents ) : say 'OK'; exit $exit_code; ##### SUBS sub get_domains_owner { my %domains_owner; # cpanel if ( -d '/var/cpanel' ) { my $userdata_dir = '/var/cpanel/userdata'; for my $user_path (</var/cpanel/users/*>) { my $user = basename($user_path); next if -f "/var/cpanel/suspended/$user"; next if $user eq 'billing'; my $userfile = "$userdata_dir/$user/main"; next if !-f $userfile; my $yaml_data = LoadFile $userfile; map { $domains_owner{$_} = $user } $yaml_data->{main_domain}, keys $yaml_data->{addon_domains}->%*, $yaml_data->{parked_domains}->@*, grep { not $_ ~~ [ values $yaml_data->{addon_domains}->%* ] } $yaml_data->{sub_domains}->@*; } } # isp if ( -f '/usr/local/mgr5/sbin/mgrctl' ) { my $domains_info_raw = `/usr/local/mgr5/sbin/mgrctl -o json -m ispmgr webdomain`; my $domains_info = decode_json($domains_info_raw)->{doc}{elem}; map { $domains_owner{ $_->{name}{'$orig'} || $_->{name}{'$'} } = $_->{owner}{'$'} } grep { $_->{active}{'$'} eq 'on' } $domains_info->@*; } # da if ( -d '/usr/local/directadmin' ) { my $prefix = '/usr/local/directadmin/data/users'; for my $user_path ( glob( "$prefix" . '/*' ) ) { my $user = basename($user_path); my $suspended = map /^suspended=yes/, read_file("$prefix/$user/user.conf"); next if $suspended; next if $user eq 'billing'; chomp( my @user_domains = read_file("$prefix/$user/domains.list") ); map { $domains_owner{$_} = $user } @user_domains; } } if ( !%domains_owner ) { say "Can't find any domain to check, something goes wrong..."; exit 1; } return \%domains_owner; } sub check_abuse_pattern { my $domain = shift; # use ::domain as workaround to not pass it as header my $res = $ua->get( "http://$domain", '::domain' => $domain ); return if !$res->is_success; # decoded content may be undef if content_charset not recognized my $data = $res->decoded_content || $res->content; my @matches = $data =~ /$content_regex/g; return scalar @matches . " matches: $matches[0]" if @matches; } # check if redirect leads to another domain to prevent false-positive detects sub request_prepare_cb { my ( $request, $ua, $handler ) = @_; my $domain = $request->header('::domain'); return if !$domain; die if $request->uri->host !~ m/$domain/; }