502 lines
20 KiB
Bash
502 lines
20 KiB
Bash
#!/usr/bin/env bash
|
|
###############################################################################
|
|
# Targeted SCA Remediation — Based on sca-verify.sh diagnostic output
|
|
#
|
|
# Fixes all FAIL items from the diagnostic. Does NOT touch items that
|
|
# already PASS. Safe to re-run (idempotent).
|
|
#
|
|
# Usage: chmod +x sca-fix.sh && sudo ./sca-fix.sh
|
|
###############################################################################
|
|
set -euo pipefail
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
if [[ $EUID -ne 0 ]]; then echo "Run as root." >&2; exit 1; fi
|
|
|
|
banner() { printf '\n\e[1;36m>>> %s\e[0m\n' "$1"; }
|
|
|
|
ADMIN_USER="${ADMIN_USER:-chris}"
|
|
|
|
###############################################################################
|
|
banner "FIX 1: Filesystem module blacklist (35509) — config file MISSING"
|
|
###############################################################################
|
|
|
|
cat > /etc/modprobe.d/cis-filesystems.conf <<'EOF'
|
|
install afs /bin/false
|
|
install ceph /bin/false
|
|
install cifs /bin/false
|
|
install exfat /bin/false
|
|
install fat /bin/false
|
|
install fscache /bin/false
|
|
install fuse /bin/false
|
|
install gfs2 /bin/false
|
|
install nfs_common /bin/false
|
|
install nfsd /bin/false
|
|
install smbfs_common /bin/false
|
|
install cramfs /bin/false
|
|
install freevxfs /bin/false
|
|
install jffs2 /bin/false
|
|
install hfs /bin/false
|
|
install hfsplus /bin/false
|
|
install squashfs /bin/false
|
|
install udf /bin/false
|
|
|
|
blacklist afs
|
|
blacklist ceph
|
|
blacklist cifs
|
|
blacklist exfat
|
|
blacklist fat
|
|
blacklist fscache
|
|
blacklist fuse
|
|
blacklist gfs2
|
|
blacklist nfs_common
|
|
blacklist nfsd
|
|
blacklist smbfs_common
|
|
blacklist cramfs
|
|
blacklist freevxfs
|
|
blacklist jffs2
|
|
blacklist hfs
|
|
blacklist hfsplus
|
|
blacklist squashfs
|
|
blacklist udf
|
|
EOF
|
|
|
|
echo " ✓ /etc/modprobe.d/cis-filesystems.conf created"
|
|
|
|
###############################################################################
|
|
banner "FIX 2: Network protocol module blacklist (35604-35607) — config file MISSING"
|
|
###############################################################################
|
|
|
|
cat > /etc/modprobe.d/cis-network-protocols.conf <<'EOF'
|
|
install dccp /bin/false
|
|
install sctp /bin/false
|
|
install rds /bin/false
|
|
install tipc /bin/false
|
|
|
|
blacklist dccp
|
|
blacklist sctp
|
|
blacklist rds
|
|
blacklist tipc
|
|
EOF
|
|
|
|
echo " ✓ /etc/modprobe.d/cis-network-protocols.conf created"
|
|
|
|
###############################################################################
|
|
banner "FIX 3: USB storage (uses /bin/true, should be /bin/false)"
|
|
###############################################################################
|
|
|
|
cat > /etc/modprobe.d/cis-usb-storage.conf <<'EOF'
|
|
install usb-storage /bin/false
|
|
blacklist usb-storage
|
|
EOF
|
|
|
|
echo " ✓ /etc/modprobe.d/cis-usb-storage.conf created"
|
|
|
|
###############################################################################
|
|
banner "FIX 4: Rebuild initramfs with new module blacklists"
|
|
###############################################################################
|
|
|
|
update-initramfs -u
|
|
echo " ✓ initramfs rebuilt"
|
|
|
|
###############################################################################
|
|
banner "FIX 5: Sysctl — ip_forward and log_martians (35608, 35616)"
|
|
###############################################################################
|
|
|
|
# Docker overrides ip_forward at runtime. To keep it disabled while
|
|
# allowing Docker networking, we need to tell Docker not to touch it
|
|
# and handle forwarding via iptables only.
|
|
# However, if Docker is actively in use, disabling ip_forward breaks
|
|
# container networking. The pragmatic fix:
|
|
|
|
if command -v docker &>/dev/null; then
|
|
echo " Docker is installed. ip_forward=1 is required for container networking."
|
|
echo " This is a known conflict — document as compensating control."
|
|
echo " Creating /etc/sysctl.d/99-docker-override.conf for non-forwarding params only."
|
|
|
|
# Don't override ip_forward if Docker is present, but DO fix log_martians
|
|
cat > /etc/sysctl.d/99-docker-override.conf <<'EOF'
|
|
# Docker requires ip_forward=1 — accepted as compensating control
|
|
# These params are safe to enforce alongside Docker:
|
|
net.ipv4.conf.all.log_martians = 1
|
|
net.ipv4.conf.default.log_martians = 1
|
|
EOF
|
|
else
|
|
# No Docker — enforce everything
|
|
sysctl -w net.ipv4.ip_forward=0
|
|
fi
|
|
|
|
# Apply log_martians immediately regardless
|
|
sysctl -w net.ipv4.conf.all.log_martians=1
|
|
sysctl -w net.ipv4.conf.default.log_martians=1
|
|
sysctl --system > /dev/null 2>&1
|
|
|
|
echo " ✓ log_martians enabled"
|
|
echo " ✓ sysctl reloaded"
|
|
|
|
###############################################################################
|
|
banner "FIX 6: Purge nftables package (35626, 35634)"
|
|
###############################################################################
|
|
|
|
if dpkg -s nftables &>/dev/null; then
|
|
apt-get purge -y nftables
|
|
echo " ✓ nftables purged"
|
|
else
|
|
echo " ✓ nftables already absent"
|
|
fi
|
|
|
|
###############################################################################
|
|
banner "FIX 7: SSH config — merge drop-in into main config (35644-35661)"
|
|
###############################################################################
|
|
|
|
# Wazuh scans /etc/ssh/sshd_config directly and doesn't parse drop-in files.
|
|
# All settings PASS via sshd -T but FAIL in Wazuh because they're only in the drop-in.
|
|
# Fix: append drop-in contents to main config and remove the drop-in.
|
|
|
|
DROPIN="/etc/ssh/sshd_config.d/nist-hardening.conf"
|
|
MAIN="/etc/ssh/sshd_config"
|
|
|
|
if [[ -f "$DROPIN" ]]; then
|
|
# Remove any existing lines in main config that we're about to add
|
|
# (avoid duplicates)
|
|
while IFS= read -r line; do
|
|
# Skip comments and empty lines
|
|
[[ "$line" =~ ^#|^$ ]] && continue
|
|
param=$(echo "$line" | awk '{print $1}')
|
|
# Remove existing uncommented instances of this param from main config
|
|
sed -i "/^\s*${param}\b/d" "$MAIN" 2>/dev/null || true
|
|
done < "$DROPIN"
|
|
|
|
# Append the hardening config
|
|
echo "" >> "$MAIN"
|
|
echo "# ===== NIST 800-53 SSH Hardening (merged from drop-in) =====" >> "$MAIN"
|
|
cat "$DROPIN" >> "$MAIN"
|
|
|
|
# Remove the drop-in
|
|
rm -f "$DROPIN"
|
|
|
|
# Test and restart
|
|
if sshd -t; then
|
|
systemctl restart ssh
|
|
echo " ✓ SSH config merged into $MAIN, drop-in removed, SSH restarted"
|
|
else
|
|
echo " ERROR: sshd config test failed. Check $MAIN"
|
|
exit 1
|
|
fi
|
|
else
|
|
echo " ✓ No drop-in to merge (already in main config)"
|
|
fi
|
|
|
|
###############################################################################
|
|
banner "FIX 8: Password aging for root and nobody (35694, 35695, 35698)"
|
|
###############################################################################
|
|
|
|
# root — set aging but keep locked (no password login)
|
|
chage -M 60 -m 1 -W 14 -I 30 root
|
|
echo " ✓ root: max=60 min=1 warn=14 inactive=30"
|
|
|
|
# nobody — system account, set aging for compliance
|
|
chage -M 60 -m 1 -W 14 -I 30 nobody
|
|
echo " ✓ nobody: max=60 min=1 warn=14 inactive=30"
|
|
|
|
###############################################################################
|
|
banner "FIX 9: Journald MaxRetentionSec (35708)"
|
|
###############################################################################
|
|
|
|
JOURNALD_DROPIN="/etc/systemd/journald.conf.d/nist.conf"
|
|
|
|
if [[ -f "$JOURNALD_DROPIN" ]]; then
|
|
if ! grep -q 'MaxRetentionSec' "$JOURNALD_DROPIN"; then
|
|
echo "MaxRetentionSec=1month" >> "$JOURNALD_DROPIN"
|
|
echo " ✓ MaxRetentionSec added to drop-in"
|
|
fi
|
|
fi
|
|
|
|
# Also add to main config since Wazuh may only read the main file
|
|
JOURNALD_MAIN="/etc/systemd/journald.conf"
|
|
if ! grep -q '^\s*SystemMaxUse=' "$JOURNALD_MAIN"; then
|
|
# If the main config doesn't have our settings, add them
|
|
sed -i '/^\[Journal\]/a SystemMaxUse=1G\nSystemKeepFree=1G\nSystemMaxFileSize=100M\nMaxRetentionSec=1month' "$JOURNALD_MAIN"
|
|
echo " ✓ Journald settings added to main config for Wazuh"
|
|
else
|
|
if ! grep -q '^\s*MaxRetentionSec=' "$JOURNALD_MAIN"; then
|
|
sed -i '/^\[Journal\]/a MaxRetentionSec=1month' "$JOURNALD_MAIN"
|
|
echo " ✓ MaxRetentionSec added to main journald.conf"
|
|
fi
|
|
fi
|
|
|
|
systemctl restart systemd-journald
|
|
echo " ✓ journald restarted"
|
|
|
|
###############################################################################
|
|
banner "FIX 10: Log file permissions (35722)"
|
|
###############################################################################
|
|
|
|
# Fix dpkg.log and sysstat files
|
|
find /var/log -type f -exec chmod g-wx,o-rwx {} +
|
|
find /var/log -type d -exec chmod g-wx,o-rwx {} +
|
|
|
|
echo " ✓ /var/log permissions tightened"
|
|
|
|
# Prevent sysstat from creating world-readable files in the future
|
|
if [[ -f /etc/sysstat/sysstat ]]; then
|
|
# Set umask for sysstat
|
|
if ! grep -q 'umask' /etc/sysstat/sysstat; then
|
|
echo 'UMASK="0027"' >> /etc/sysstat/sysstat
|
|
fi
|
|
fi
|
|
|
|
# Also set default umask in rsyslog
|
|
if [[ -f /etc/rsyslog.d/99-nist-perms.conf ]]; then
|
|
if ! grep -q 'DirCreateMode' /etc/rsyslog.d/99-nist-perms.conf; then
|
|
echo '$DirCreateMode 0750' >> /etc/rsyslog.d/99-nist-perms.conf
|
|
echo '$Umask 0027' >> /etc/rsyslog.d/99-nist-perms.conf
|
|
fi
|
|
fi
|
|
|
|
echo " ✓ Future log file creation modes tightened"
|
|
|
|
###############################################################################
|
|
banner "FIX 11: Audit rules file (35731-35748) — rules file MISSING"
|
|
###############################################################################
|
|
|
|
# Rules are loaded (50 rules) but the file Wazuh scans doesn't exist.
|
|
# The rules seem to be in /etc/audit/rules.d/cis-nist.rules instead of
|
|
# nist-800-53.rules. Wazuh scans the rules.d directory, so we need to
|
|
# ensure the rules file is there with the correct content.
|
|
|
|
cat > /etc/audit/rules.d/nist-800-53.rules <<'AUDITRULES'
|
|
## ---- Remove any existing rules ----
|
|
-D
|
|
|
|
## ---- Buffer size ----
|
|
-b 8192
|
|
|
|
## ---- Failure mode ----
|
|
-f 1
|
|
|
|
## ---- Time changes (35734) ----
|
|
-a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change
|
|
-a always,exit -F arch=b32 -S adjtimex,settimeofday,clock_settime -k time-change
|
|
-w /etc/localtime -p wa -k time-change
|
|
|
|
## ---- User/group changes (35737) ----
|
|
-w /etc/passwd -p wa -k identity
|
|
-w /etc/group -p wa -k identity
|
|
-w /etc/shadow -p wa -k identity
|
|
-w /etc/gshadow -p wa -k identity
|
|
-w /etc/security/opasswd -p wa -k identity
|
|
|
|
## ---- Network configuration (35735) ----
|
|
-a always,exit -F arch=b64 -S sethostname,setdomainname -k network-config
|
|
-a always,exit -F arch=b32 -S sethostname,setdomainname -k network-config
|
|
-w /etc/hosts -p wa -k network-config
|
|
-w /etc/hostname -p wa -k network-config
|
|
-w /etc/netplan/ -p wa -k network-config
|
|
-w /etc/network/ -p wa -k network-config
|
|
-w /etc/networks -p wa -k network-config
|
|
|
|
## ---- Login/logout events (35741) ----
|
|
-w /var/log/lastlog -p wa -k logins
|
|
-w /var/log/faillog -p wa -k logins
|
|
-w /var/log/wtmp -p wa -k logins
|
|
-w /var/log/btmp -p wa -k logins
|
|
|
|
## ---- Session initiation (35740) ----
|
|
-w /var/run/utmp -p wa -k session
|
|
|
|
## ---- Sudo scope changes (35731) ----
|
|
-w /etc/sudoers -p wa -k scope
|
|
-w /etc/sudoers.d -p wa -k scope
|
|
|
|
## ---- Sudo log (35733) ----
|
|
-w /var/log/sudo.log -p wa -k actions
|
|
|
|
## ---- Actions as another user (35732) ----
|
|
-a always,exit -F arch=b64 -S execve -C euid!=uid -F auid!=unset -k user_emulation
|
|
-a always,exit -F arch=b32 -S execve -C euid!=uid -F auid!=unset -k user_emulation
|
|
|
|
## ---- Privileged commands ----
|
|
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -k privileged
|
|
-a always,exit -F arch=b32 -S execve -F euid=0 -F auid>=1000 -F auid!=4294967295 -k privileged
|
|
|
|
## ---- Unsuccessful file access (35736) ----
|
|
-a always,exit -F arch=b64 -S open,openat,creat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
|
|
-a always,exit -F arch=b64 -S open,openat,creat,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access
|
|
-a always,exit -F arch=b32 -S open,openat,creat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=4294967295 -k access
|
|
-a always,exit -F arch=b32 -S open,openat,creat,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=4294967295 -k access
|
|
|
|
## ---- DAC permission changes (35738) ----
|
|
-a always,exit -F arch=b64 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
|
|
-a always,exit -F arch=b64 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=4294967295 -k perm_mod
|
|
-a always,exit -F arch=b64 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod
|
|
-a always,exit -F arch=b32 -S chmod,fchmod,fchmodat -F auid>=1000 -F auid!=4294967295 -k perm_mod
|
|
-a always,exit -F arch=b32 -S chown,fchown,lchown,fchownat -F auid>=1000 -F auid!=4294967295 -k perm_mod
|
|
-a always,exit -F arch=b32 -S setxattr,lsetxattr,fsetxattr,removexattr,lremovexattr,fremovexattr -F auid>=1000 -F auid!=4294967295 -k perm_mod
|
|
|
|
## ---- File system mounts (35739) ----
|
|
-a always,exit -F arch=b64 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts
|
|
-a always,exit -F arch=b32 -S mount -F auid>=1000 -F auid!=4294967295 -k mounts
|
|
|
|
## ---- File deletion events (35742) ----
|
|
-a always,exit -F arch=b64 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=4294967295 -k delete
|
|
-a always,exit -F arch=b32 -S unlink,unlinkat,rename,renameat -F auid>=1000 -F auid!=4294967295 -k delete
|
|
|
|
## ---- Mandatory access control changes (35743) ----
|
|
-w /etc/apparmor/ -p wa -k MAC-policy
|
|
-w /etc/apparmor.d/ -p wa -k MAC-policy
|
|
|
|
## ---- chcon (35744) ----
|
|
-a always,exit -F path=/usr/bin/chcon -F perm=x -F auid>=1000 -F auid!=4294967295 -k perm_chng
|
|
|
|
## ---- setfacl (35745) ----
|
|
-a always,exit -F path=/usr/bin/setfacl -F perm=x -F auid>=1000 -F auid!=4294967295 -k perm_chng
|
|
|
|
## ---- chacl (35746) ----
|
|
-a always,exit -F path=/usr/bin/chacl -F perm=x -F auid>=1000 -F auid!=4294967295 -k perm_chng
|
|
|
|
## ---- usermod (35747) ----
|
|
-a always,exit -F path=/usr/sbin/usermod -F perm=x -F auid>=1000 -F auid!=4294967295 -k usermod
|
|
|
|
## ---- Kernel module loading (35748) ----
|
|
-a always,exit -F arch=b64 -S init_module,finit_module,delete_module,create_module,query_module -k kernel_modules
|
|
-a always,exit -F arch=b32 -S init_module,finit_module,delete_module,create_module,query_module -k kernel_modules
|
|
-w /sbin/insmod -p x -k kernel_modules
|
|
-w /sbin/rmmod -p x -k kernel_modules
|
|
-w /sbin/modprobe -p x -k kernel_modules
|
|
-w /bin/kmod -p x -k kernel_modules
|
|
|
|
## ---- Make configuration immutable ----
|
|
-e 2
|
|
AUDITRULES
|
|
|
|
chmod 640 /etc/audit/rules.d/nist-800-53.rules
|
|
|
|
# Remove old rules file if it exists and is different
|
|
if [[ -f /etc/audit/rules.d/cis-nist.rules ]]; then
|
|
rm -f /etc/audit/rules.d/cis-nist.rules
|
|
echo " ✓ Removed old cis-nist.rules"
|
|
fi
|
|
|
|
# Load the new rules
|
|
augenrules --load 2>/dev/null || true
|
|
systemctl restart auditd 2>/dev/null || true
|
|
|
|
echo " ✓ nist-800-53.rules created and loaded"
|
|
echo " Rules loaded: $(auditctl -l 2>/dev/null | wc -l)"
|
|
|
|
###############################################################################
|
|
banner "FIX 12: AIDE audit tool coverage (35760)"
|
|
###############################################################################
|
|
|
|
AIDE_CUSTOM="/etc/aide/aide.conf.d/99_nist_custom"
|
|
if [[ -f "$AIDE_CUSTOM" ]]; then
|
|
# Check if audit tools are already covered
|
|
if ! grep -q 'auditctl' "$AIDE_CUSTOM"; then
|
|
cat >> "$AIDE_CUSTOM" <<'EOF'
|
|
|
|
# CIS 4.1.4.11 - Audit tool integrity
|
|
/sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
EOF
|
|
echo " ✓ Audit tool integrity rules added to AIDE config"
|
|
else
|
|
echo " ✓ Audit tools already in AIDE config"
|
|
fi
|
|
else
|
|
# Create the file
|
|
cat > "$AIDE_CUSTOM" <<'EOF'
|
|
# NIST 800-53 SI-7: File integrity monitoring
|
|
/boot Full
|
|
/bin Full
|
|
/sbin Full
|
|
/lib Full
|
|
/lib64 Full
|
|
/usr/bin Full
|
|
/usr/sbin Full
|
|
/usr/lib Full
|
|
/etc Full
|
|
!/etc/mtab
|
|
!/etc/adjtime
|
|
!/var/log
|
|
!/var/spool
|
|
!/var/cache
|
|
|
|
# CIS 4.1.4.11 - Audit tool integrity
|
|
/sbin/auditctl p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/auditd p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/ausearch p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/aureport p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/autrace p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
/sbin/augenrules p+i+n+u+g+s+b+acl+xattrs+sha512
|
|
EOF
|
|
echo " ✓ AIDE custom config created with audit tool coverage"
|
|
fi
|
|
|
|
echo " NOTE: Run 'sudo aideinit -y -f' to rebuild the database (takes 10-15 min)"
|
|
|
|
###############################################################################
|
|
banner "FIX 13: at.allow — add admin user (35601)"
|
|
###############################################################################
|
|
|
|
if [[ -f /etc/at.allow ]]; then
|
|
if ! grep -q "$ADMIN_USER" /etc/at.allow; then
|
|
echo "$ADMIN_USER" >> /etc/at.allow
|
|
echo " ✓ $ADMIN_USER added to /etc/at.allow"
|
|
else
|
|
echo " ✓ $ADMIN_USER already in /etc/at.allow"
|
|
fi
|
|
fi
|
|
|
|
# Same for cron.allow
|
|
if [[ -f /etc/cron.allow ]]; then
|
|
if ! grep -q "$ADMIN_USER" /etc/cron.allow; then
|
|
echo "$ADMIN_USER" >> /etc/cron.allow
|
|
echo " ✓ $ADMIN_USER added to /etc/cron.allow"
|
|
fi
|
|
fi
|
|
|
|
###############################################################################
|
|
banner "COMPLETE"
|
|
###############################################################################
|
|
|
|
cat <<'DONE'
|
|
|
|
╔══════════════════════════════════════════════════════════════════╗
|
|
║ SCA Remediation Complete ║
|
|
╠══════════════════════════════════════════════════════════════════╣
|
|
║ ║
|
|
║ Fixed: ║
|
|
║ • Filesystem module blacklist file created ║
|
|
║ • Network protocol module blacklist file created ║
|
|
║ • USB storage module fixed (/bin/false) ║
|
|
║ • initramfs rebuilt with blacklists ║
|
|
║ • log_martians enabled at runtime ║
|
|
║ • nftables package purged ║
|
|
║ • SSH config merged from drop-in into main sshd_config ║
|
|
║ • Password aging set for root and nobody ║
|
|
║ • Journald MaxRetentionSec added ║
|
|
║ • Log file permissions tightened ║
|
|
║ • Full audit ruleset created in nist-800-53.rules ║
|
|
║ • AIDE audit tool integrity rules added ║
|
|
║ • at.allow / cron.allow updated ║
|
|
║ ║
|
|
║ Known exceptions (suppress in Wazuh): ║
|
|
║ • 35540 GRUB password (manual step) ║
|
|
║ • 35589 systemd-timesyncd (chrony is active) ║
|
|
║ • 35608 ip_forward=1 (Docker requires it) ║
|
|
║ • 35710 journal-upload (using Wazuh instead) ║
|
|
║ • 35720 remote syslog (using Wazuh instead) ║
|
|
║ • 35626-35639 firewall cross-checks (using UFW only) ║
|
|
║ ║
|
|
║ Still needed: ║
|
|
║ • Rebuild AIDE database: sudo aideinit -y -f ║
|
|
║ • Reboot to apply module blacklists ║
|
|
║ • Re-run sca-verify.sh to confirm fixes ║
|
|
║ • Re-run Wazuh SCA scan ║
|
|
║ ║
|
|
╚══════════════════════════════════════════════════════════════════╝
|
|
DONE |