Kali Linux
Hardening
Timeline
Install security tools
/usr/share/seclists/ on this system, not /usr/share/wordlists/. rockyou.txt requires extraction: tar -xzf /usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt.tar.gzInstall everything Lynis flagged as missing in one command. This covers firewall, intrusion detection, file integrity, PAM modules, audit tools, and package management utilities.
# Core security tools
apt install ufw fail2ban auditd rkhunter \
libpam-pwquality libpam-tmpdir \
needrestart apt-listbugs apt-listchanges \
debsums apt-show-versions -y
# File integrity + accounting
apt install aide sysstat acct unattended-upgrades -y
Enable services
# Firewall — deny all incoming by default
ufw default deny incoming
ufw default allow outgoing
ufw enable
# Security services
systemctl enable auditd && systemctl start auditd
systemctl enable fail2ban && systemctl start fail2ban
systemctl enable apparmor && systemctl start apparmor
systemctl enable sysstat && systemctl start sysstat
systemctl enable psacct && systemctl start psacct
# Protect fail2ban config from upgrades
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
systemctl restart fail2ban
Kernel hardening (sysctl)
16 kernel parameters hardened covering memory protection, BPF JIT hardening, ptrace scope, network redirect blocking, and martian packet logging. Note: kernel.modules_disabled=1 intentionally skipped — breaks Kali drivers.
cat >> /etc/sysctl.conf << 'EOF'
# Kernel hardening
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
kernel.sysrq = 0
kernel.unprivileged_bpf_disabled = 1
kernel.yama.ptrace_scope = 1
dev.tty.ldisc_autoload = 0
fs.protected_fifos = 2
# Network hardening
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.core.bpf_jit_harden = 2
EOF
sysctl -p
sysctl -p again to re-apply.Authentication hardening
# PAM password strength (12 char min, complexity required)
cat > /etc/security/pwquality.conf << 'EOF'
minlen = 12
dcredit = -1
ucredit = -1
ocredit = -1
lcredit = -1
maxrepeat = 3
EOF
# Password aging
sed -i 's/^PASS_MAX_DAYS.*/PASS_MAX_DAYS\t90/' /etc/login.defs
sed -i 's/^PASS_MIN_DAYS.*/PASS_MIN_DAYS\t1/' /etc/login.defs
sed -i 's/^PASS_WARN_AGE.*/PASS_WARN_AGE\t7/' /etc/login.defs
# SHA512 hashing rounds & umask
echo "SHA_CRYPT_MIN_ROUNDS 65536" >> /etc/login.defs
echo "SHA_CRYPT_MAX_ROUNDS 655360" >> /etc/login.defs
echo "UMASK 027" >> /etc/login.defs
echo "umask 027" >> /etc/bash.bashrc
echo "umask 027" >> /etc/profile
# Session timeout (15 min)
echo "TMOUT=900" >> /etc/profile
echo "readonly TMOUT" >> /etc/profile
echo "export TMOUT" >> /etc/profile
# Apply expiry to accounts
chage --maxdays 90 --mindays 1 --warndays 7 root
chage --maxdays 90 --mindays 1 --warndays 7 kmrlbhr
Auditd rules
Audit rules covering identity changes, privilege escalation, SSH config, network config, cron jobs, and kernel module loading.
cat > /etc/audit/rules.d/hardening.rules << 'EOF'
-D
-b 8192
-f 1
# Identity changes
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/gshadow -p wa -k identity
-w /etc/sudoers -p wa -k sudoers
-w /etc/sudoers.d/ -p wa -k sudoers
# Privilege escalation
-w /var/log/auth.log -p wa -k auth
-w /bin/su -p x -k priv_esc
-w /usr/bin/sudo -p x -k priv_esc
# SSH & network
-w /etc/ssh/sshd_config -p wa -k ssh
-w /etc/hosts -p wa -k network
-w /etc/network/ -p wa -k network
# Cron
-w /etc/crontab -p wa -k cron
-w /etc/cron.d/ -p wa -k cron
# Kernel modules
-w /sbin/insmod -p x -k modules
-w /sbin/rmmod -p x -k modules
-w /sbin/modprobe -p x -k modules
EOF
augenrules --load
systemctl restart auditd
File integrity monitoring
Initialize AIDE with explicit SHA512 checksums. The database build takes 2–13 minutes depending on filesystem size.
# Override default checksum to SHA512 explicitly
sed -i 's/^Checksums = H/Checksums = sha512/' /etc/aide/aide.conf
grep "^Checksums" /etc/aide/aide.conf # verify
# Build database (~2-13 min)
aide -c /etc/aide/aide.conf --init
cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Verify database exists
ls -lh /var/lib/aide/aide.db
# Update definitions (may fail offline — ok)
rkhunter --update
# Build file properties baseline
rkhunter --propupd
Filesystem hardening
# Home directory permissions
chmod 750 /home /home/kmrlbhr
chmod 700 /root
# System account home dirs (found by checking getent passwd)
chmod 750 /usr/sbin /usr/games /var/cache/man
chmod 750 /var/mail /var/backups /run/sshd
chmod 750 /var/lib/misc /var/lib/colord
chmod 750 /var/lib/saned /var/lib/postgresql
chmod 750 /var/lib/openvpn/chroot
# Cron directory permissions
chmod 700 /etc/cron.d /etc/cron.daily /etc/cron.hourly
chmod 700 /etc/cron.weekly /etc/cron.monthly
chmod 600 /etc/crontab
chmod 750 /etc/sudoers.d
chmod 600 /etc/ssh/sshd_config
# Hide /proc from other users
echo "proc /proc proc defaults,hidepid=2 0 0" >> /etc/fstab
mount -o remount,hidepid=2 /proc
# debsums weekly cron job
sed -i 's/^CRON_CHECK=.*/CRON_CHECK=weekly/' /etc/default/debsums
Network & device hardening
cat >> /etc/modprobe.d/hardening.conf << 'EOF'
# Unused network protocols
install dccp /bin/false
install sctp /bin/false
install rds /bin/false
install tipc /bin/false
# Storage devices
install usb-storage /bin/false
install firewire-ohci /bin/false
EOF
# Remove immutable flag if set
chattr -i /etc/resolv.conf
cat > /etc/resolv.conf << 'EOF'
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 1.1.1.1
EOF
# Lock from being overwritten by NetworkManager/DHCP
chattr +i /etc/resolv.conf
Boot security
--unrestricted flag so normal booting still works without entering the GRUB password. Only editing boot entries requires authentication.# Step 1: Generate hash (interactive)
grub-mkpasswd-pbkdf2
# Copy the full hash that starts with grub.pbkdf2.sha512...
# Step 2: Add to GRUB
cat >> /etc/grub.d/40_custom << 'EOF'
set superusers="root"
password_pbkdf2 root <PASTE_YOUR_HASH_HERE>
EOF
# Step 3: Allow normal boot without password
sed -i 's/^CLASS=.*/CLASS="--class gnu-linux --class gnu --class os --unrestricted"/' \
/etc/grub.d/10_linux
# Step 4: Apply
update-grub
cat > /etc/issue << 'EOF'
WARNING: Unauthorized access to this system is prohibited.
All activity is monitored and logged. Disconnect immediately.
EOF
cp /etc/issue /etc/issue.net
Compiler hardening
Lynis checks as, cc, gcc, and clang — following symlinks to real binaries. The GNU assembler (as) was the final culprit along with mingw cross-compilers.
# Restrict cpp (follows symlink chain to real binary)
chmod o-rx /usr/bin/cpp
chmod o-rx /usr/bin/cpp-15
chmod o-rx /usr/bin/x86_64-linux-gnu-cpp-15
# Restrict as/assembler (Lynis treats as compiler)
chmod o-rx /usr/bin/as
chmod o-rx /usr/bin/x86_64-linux-gnu-as
# Restrict mingw cross-compilers
find /usr/bin -name "*mingw*cpp*" \
-o -name "*mingw*gcc*" | \
xargs chmod o-rx 2>/dev/null
find /etc/alternatives -name "*mingw*cpp*" \
-o -name "*mingw*gcc*" | \
xargs chmod o-rx 2>/dev/null
# Verify — should show r-x--- (750) for all
ls -la /usr/bin/as /usr/bin/cpp /usr/bin/x86_64-linux-gnu-as
Intentionally skipped
-
✗
kernel.modules_disabled=1 KRNL-6000
Setting to 1 after boot prevents loading any kernel modules. Breaks network adapters, USB devices, Kali drivers, and most offensive tools. Incompatible with pentesting. -
✗
Separate /home partition FILE-6310
Requires full disk repartitioning and OS reinstall. Not feasible on a working machine mid-engagement. -
✗
Separate /var partition FILE-6310
Same — requires reinstall. /var contains logs, databases, and package cache; moving it live risks corruption. -
—
External log host LOGG-2154
No remote syslog server available. Would require infrastructure setup outside scope of this engagement. -
—
Automation tooling TOOL-5002
Chef/Puppet/Ansible not relevant for a standalone pentest laptop.
Full checklist
Security services
- +UFW firewall (deny in / allow out)
- +fail2ban + jail.local
- +AppArmor MAC framework
- +auditd + comprehensive rules
- +rkhunter (baseline created)
- +AIDE + SHA512 database
- +sysstat + process accounting
- +unattended-upgrades
Kernel & network
- +kernel.dmesg_restrict=1
- +kernel.kptr_restrict=2
- +kernel.sysrq=0
- +kernel.yama.ptrace_scope=1
- +net BPF JIT harden=2
- +IP redirects blocked
- +Martian logging enabled
- +Reverse path filtering=1
Authentication
- +PAM pwquality (minlen=12)
- +libpam-tmpdir enabled
- +Password aging (90/1/7)
- +SHA512 hashing rounds 65536
- +Umask 027
- +Session timeout 900s
- +Account expiry set
- +sudoers.d permissions
System & boot
- +GRUB pbkdf2-sha512 password
- +Login banners set
- +USB storage disabled
- +FireWire disabled
- +dccp/sctp/rds/tipc blocked
- +/proc hidepid=2
- +Compilers root-only
- +Home dir perms fixed