diff --git a/lynis_report.pl b/lynis_report.pl index 0dd2c99..49ce539 100755 --- a/lynis_report.pl +++ b/lynis_report.pl @@ -150,7 +150,7 @@ if ($excel) { my $i = 0; # do the Excel thing.... my $wb = Excel::Writer::XLSX->new($output); - my $title_format = $wb->add_format(); + my $title_format = $wb->add_format( 'valign'=>'top', 'align'=>'left'); $title_format->set_size('32'); my $subtitle_format = $wb->add_format(); @@ -171,7 +171,7 @@ if ($excel) { ### Summary Sheet Data my $summary_ws = $wb->add_worksheet('Summary'); - $summary_ws->write('B2', "lynis Asset Report", $title_format); + $summary_ws->merge_range('A2:C2', "lynis Asset Report", $title_format); $summary_ws->write('B3', "created by "); $summary_ws->write_url('C3', "http://github.com/d4t4king/lynis_report.git", '', 'lynis_report'); $summary_ws->write('A4', "Host Findings:", $subtitle_format); @@ -387,12 +387,26 @@ if ($excel) { $sec_ws->write('A9', 'IDS/IPS tooling', $label_format); if (exists($lynis_report_data{'ids_ips_tooling'})) { if (ref($lynis_report_data{'ids_ips_tooling'}) eq 'ARRAY') { - $sec_ws->write('B9', join("\n", @{$lynis_report_data{'ids_ips_tooling'}})); + $sec_ws->write('B9', join("\n", @{$lynis_report_data{'ids_ips_tooling'}}), $merge_format); } else { - $sec_ws->write('B9', $lynis_report_data{'ids_ips_tooling'}); + $sec_ws->write('B9', $lynis_report_data{'ids_ips_tooling'}, $merge_format); } } else { - $sec_ws->write('B9', 'N/A'); + $sec_ws->write('B9', 'N/A', $merge_format); + } + if (exists($lynis_report_data{'fail2ban_config'})) { + $sec_ws->write('C9', 'fail2ban config file(s):', $label_format); + $sec_ws->write('D9', $lynis_report_data{'fail2ban_config'}, $merge_format); + } else { + $sec_ws->write('D9', 'N/A', $merge_format); + } + if (exists($lynis_report_data{'fail2ban_enabled_service[]'})) { + $sec_ws->write('E9', 'fail2ban enabled service(s):', $label_format); + if (ref($lynis_report_data{'fail2ban_enabled_service[]'}) eq 'ARRAY') { + $sec_ws->write('F9', join("\n", @{$lynis_report_data{'fail2ban_enabled_service[]'}}), $merge_format); + } else { + $sec_ws->write('F9', $lynis_report_data{'fail2ban_enabled_service[]'}, $merge_format); + } } $sec_ws->merge_range('A11:B11', 'real users:', $subsub_format); $sec_ws->merge_range('C11:D11', 'home directories:', $subsub_format); $sec_ws->write('A12', 'name', $label_format); $sec_ws->write('B12', 'uid', $label_format); @@ -438,11 +452,36 @@ if ($excel) { ### boot info my $boot_ws = $wb->add_worksheet('boot info'); $boot_ws->write('A1', "boot info:", $title_format); + $boot_ws->write('A2', 'UEFI booted:', $label_format); $boot_ws->write('B2', $to_bool{$lynis_report_data{'boot_uefi_booted'}}); + $boot_ws->write('C2', 'UEFI booted secure:', $label_format); $boot_ws->write('D2', $to_bool{$lynis_report_data{'boot_uefi_booted_secure'}}); + $boot_ws->write('A3', 'default runlevel:', $label_format); $boot_ws->write('B3', $lynis_report_data{'linux_default_runlevel'}); + $boot_ws->write('C3', 'boot service tool:', $label_format); $boot_ws->write('D3', $lynis_report_data{'boot_service_tool'}); + $i = 5; + if (exists($lynis_report_data{'boot_service[]'})) { + $boot_ws->write("A$i", "services started at boot:", $subsub_format); $i++; + if (ref($lynis_report_data{'boot_service[]'}) eq 'ARRAY') { + foreach my $bs ( sort @{$lynis_report_data{'boot_service[]'}} ) { + $boot_ws->write("A$i", $bs); $i++; + } + } else { + $boot_ws->write("A$i", $lynis_report_data{'boot_service[]'}); + } + } ### kernel inso my $kernel_ws = $wb->add_worksheet('kernel info'); $kernel_ws->write('A1', "kernel info:", $title_format); - + $i = 5; + if (exists($lynis_report_data{'loaded_kernel_module[]'})) { + $kernel_ws->write("A$i", "loaded kernel modules:", $subsub_format); $i++; + if (ref($lynis_report_data{'loaded_kernel_module[]'}) eq 'ARRAY') { + foreach my $mod ( sort @{$lynis_report_data{'loaded_kernel_module[]'}} ) { + $kernel_ws->write("A$i", $mod); $i++; + } + } else { + $kernel_ws->write("A$i", $lynis_report_data{'loaded_kernel_module[]'}); + } + } ### filesystem/journalling info my $fs_ws = $wb->add_worksheet('filesystem info'); $fs_ws->write('A1', "filesystem info:", $title_format); @@ -477,10 +516,11 @@ if ($excel) { $i++; } - my @indexes = qw( lynis_version lynis_tests_done license_key report_version test_category test_group installed_packages binaries_count installed_packages_array report_datetime_start report_datetime_end hostid hostid2 hostname domainname resolv_conf_domain resolv_conf_search_domain[] os os_fullname os_version framework_grsecurity framework_selinux memory_size memory_units cpu_pae cpu_nx linux_version vm uptime_in_seconds uptime_in_days locate_db available_shell[] binary_paths open_empty_log_file[] os_kernel_version ); - my @idx2 = qw( cronjob[] log_rotation_tool log_directory[] log_rotation_config_found network_ipv4_address[] network_ipv6_address[] network_interface[] ipv6_mode ipv6_only warning[] suggestion[] network_listen_port[] usb_authorized_default_device[] network_mac_address[] default_gateway[] os_name lynis_update_available hardening_index plugin_directory plugins_enabled notebook open_logfile[] report_version_major report_version_minor valid_certificate[] min_password_class ); - my @idx3 = qw( firewall_installed firewall_software[] firewall_empty_ruleset firewall_active package_audit_tool_found package_audit_tool vulnerable_packages_found package_manager[] authentication_two_factor_enabled authentication_two_factor_required ldap_oam_enabled ldap_auth_enabled minimum_password_length password_max_days password_min_days max_password_retry pam_cracklib password_strength_tested auth_failed_logins_logged password_max_u_credit password_max_l_credit password_max_o_credit ldap_pam_enabled running_service[] pam_module[] nameserver[] ); - push @indexes, @idx2, @idx3; + my @indexes = qw( lynis_version lynis_tests_done license_key report_version test_category test_group installed_packages binaries_count installed_packages_array report_datetime_start report_datetime_end hostid hostid2 hostname domainname resolv_conf_domain resolv_conf_search_domain[] os os_fullname os_version framework_grsecurity framework_selinux memory_size memory_units cpu_pae cpu_nx linux_version vm uptime_in_seconds uptime_in_days locate_db available_shell[] binary_paths open_empty_log_file[] os_kernel_version os_kernel_version_full ); + my @idx2 = qw( cronjob[] log_rotation_tool log_directory[] log_rotation_config_found network_ipv4_address[] network_ipv6_address[] network_interface[] ipv6_mode ipv6_only warning[] suggestion[] network_listen_port[] usb_authorized_default_device[] network_mac_address[] default_gateway[] os_name lynis_update_available hardening_index plugin_directory plugins_enabled notebook open_logfile[] report_version_major report_version_minor valid_certificate[] min_password_class home_directory[] name_cache_used automation_tool_running[] real_user[] ); + my @idx3 = qw( firewall_installed firewall_software[] firewall_empty_ruleset firewall_active package_audit_tool_found package_audit_tool vulnerable_packages_found package_manager[] authentication_two_factor_enabled authentication_two_factor_required ldap_oam_enabled ldap_auth_enabled minimum_password_length password_max_days password_min_days max_password_retry pam_cracklib password_strength_tested auth_failed_logins_logged password_max_u_credit password_max_l_credit password_max_o_credit ldap_pam_enabled running_service[] pam_module[] nameserver[] password_max_digital_credit massword_max_other_credit ); + my @idx4 = qw( compiler_installed compiler[] ids_ips_tooling file_integrity_tool_installed file_integrity_tool[] automation_tool_present automation_tool_installed[] malware_scanner installed malware_scanner[] fail2ban_config fail2ban_enabled_service[] loaded_kernel_module[] linux_default_runlevel boot_service_tool boot_urfi_booted boot_uefi_booted_secure boot_service[] ); + push @indexes, @idx2, @idx3, @idx4; foreach my $idx ( sort @indexes ) { delete($lynis_report_data{$idx}); } @@ -1310,13 +1350,13 @@ END END foreach my $prog ( sort qw( redis ntp_daemon mysql ssh_daemon dhcp_client arpwatch audit_daemon postgresql linux_auditd nginx ) ) { if ((defined($lynis_report_data{$prog.'_running'})) and ($lynis_report_data{$prog.'_running'} ne "")) { - print OUT "\n\n\n\n\n\n$prog running:$to_bool{$lynis_report_data{$prog.'_running'}}\n"; + print OUT "\t\t\t\t\t$prog running:$to_bool{$lynis_report_data{$prog.'_running'}}\n"; } else { - print OUT "\n\n\n\n\n\n$prog running:$to_bool{0}\n"; + print OUT "\t\t\t\t\t$prog running:$to_bool{0}\n"; } } - print OUT "\t\t\t\t\t\n"; - print OUT "\t\t\t

daemon info:

\n"; + print OUT "\t\t\t\t\n"; + print OUT "\t\t\t\t

daemon info:

\n"; print OUT "\t\t\t\t\t\n"; if ((exists($lynis_report_data{'pop3_daemon'})) and ($lynis_report_data{'pop3_daemon'} ne "")) { print OUT "\t\t\t\t\t\t\n"; @@ -1349,7 +1389,7 @@ END print OUT "\t\t\t\t\t
pop3 daemon:$lynis_report_data{'pop3_daemon'}
\n"; if (exists($lynis_report_data{'running_service[]'})) { print OUT <Running services: +

running services:

END if (scalar(@{$lynis_report_data{'running_service[]'}}) < 25) { print OUT "\t\t\t\t\n"; } foreach my $svc ( @{$lynis_report_data{'running_service[]'}} ) { print OUT "\t\t\t\t\t