Kali · System Hardening

Termux Hub · Kali Linux

Kali System Hardening & Container Security Scripts

System hardening and container security — SSH brute-force defence, kernel parameter tuning, iptables and UFW rule compilation, USB autorun blocking, API key leak scanning and a read-only Docker container audit that flags privilege-escalation misconfigurations.

Kali · System Hardening — script list

ScriptCategoryWhat it does
process_anomaly_hunter.pyHardeningInspects `/proc` for unlinked binaries and odd execution paths.
shadow_file_integrity.pyHardeningAudits `/etc/shadow` permissions and ownership.
netstat_log_parser.pyHardeningDetects unprivileged ports bound to public interfaces.
systemd_service_auditor.pyHardeningFlags services running from non-standard or risky paths.
api_key_leak_scanner.pyHardeningRegex-scans code for hardcoded API keys and secrets.
subnet_ping_sweeper.pyNetwork SecurityRapid multi-threaded ping sweep for host discovery.
port_banner_grabber.pyNetwork SecurityService fingerprinting and banner grabbing for vulnerability mapping.
mac_address_spoofer.pyNetwork SecurityRandomises and assigns new MAC addresses to interfaces.
dns_zone_transfer_check.pyNetwork SecurityAttempts AXFR transfers to map internal DNS topology.
termux_environment_mapper.pyEnvironment SecurityAudits permissions and tools in mobile Termux environments.
ufw_rules_compiler.shHardeningCompiles net rules, clears dangling entries, hardens conntrack.
ssh_bruteforce_defense.shHardeningDynamically blacklists malicious IPs from auth logs.
kernel_parameter_tuner.shHardeningHardens kernel parameters against spoofing and redirects.
untrusted_ppa_purger.shHardeningVerifies repository signatures and purges untrusted sources.
auditd_report_aggregator.shHardeningCompiles core logs and snapshots into a locked report.
iptables_reset_secure.shHardeningApplies a strict default-drop iptables policy.
rogue_process_killer.shHardeningTerminates high-CPU background processes without a TTY.
cronjob_audit_reporter.shHardeningScans system/user cronjobs for suspicious persistence.
usb_autorun_blocker.shHardeningBlocks automated mounting and execution from USB devices.
kali_update_cleaner.shMaintenanceDeep maintenance: system updates and package-cache cleaning.
docker_container_audit.shContainer SecurityRead-only audit of containers for privileged mode, host namespaces, and risky mounts.

Code samples

kernel_parameter_tuner.sh — harden IPv4 sysctl values

#!/bin/bash
# SAFE_HELP_GUARD: non-destructive --help (exits before any state change).
if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
    echo "Usage: $(basename "$0") [options]"
    echo "This is a state-changing tool. --help makes no changes and exits."
    exit 0
fi

# Kernel Parameter Tuner
# Modifies system memory parameters to prevent routing spoof injection over network vectors.

echo "=== Kernel Parameter Tuner ==="

if [[ $EUID -ne 0 ]]; then
   echo "[!] This script must be run as root." 
   exit 1
fi

# Hardening IPv4 networking
echo "[*] Hardening network stack (IPv4)..."

# Ignore ICMP broadcasts
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1

# Ignore bogus ICMP errors
sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=1

# Do not accept IP source route packets
sysctl -w net.ipv4.conf.all.accept_source_route=0
sysctl -w net.ipv4.conf.default.accept_source_route=0

# Disable ICMP redirect acceptance
sysctl -w net.ipv4.conf.all.accept_redirects=0
sysctl -w net.ipv4.conf.default.accept_redirects=0

# Enable IP spoofing protection (Reverse Path Filtering)
sysctl -w net.ipv4.conf.all.rp_filter=1
sysctl -w net.ipv4.conf.default.rp_filter=1

# Log Martians (packets with impossible source addresses)
sysctl -w net.ipv4.conf.all.log_martians=1
sysctl -w net.ipv4.conf.default.log_martians=1

# Reload sysctl settings from config file
sysctl -p

echo "[+] Kernel network parameters have been hardened."

api_key_leak_scanner.py — scan for hardcoded secrets

#!/usr/bin/env python3
"""Scan a directory tree for hardcoded secrets and credentials.

The scanner walks a workspace, matches the contents of every text file against
a set of well-known credential signatures (generic API keys, Google API keys,
AWS access keys, Slack tokens and GitHub personal access tokens), and reports
each hit. It is intended to run locally and as a lightweight CI gate before
code is committed or pushed.

Exit codes:
    0 - scan completed and no potential secrets were found
    1 - scan completed and at least one potential secret was found
    2 - the scan could not run (for example, the target path does not exist)

Safety note:
    Matched secret material is never echoed to the console. Only a redacted
    context snippet is printed, so scanner output can be pasted into CI logs or
    bug reports without re-leaking the very credential it detected.
"""

import argparse
import os
import re
import sys
from pathlib import Path

# --- Configuration ----------------------------------------------------------

# Directories that never hold first-party source and are expensive or pointless
# to walk (VCS metadata, virtual environments, caches, vendored dependencies).
SKIP_DIRS = {
    ".git", ".hg", ".svn", ".tox", ".venv", "venv", "__pycache__", "node_modules",
}

# Binary and archive extensions that must not be read as text.
SKIP_EXTENSIONS = {
    ".png", ".jpg", ".jpeg", ".gif", ".ico", ".bmp", ".tiff",
    ".exe", ".dll", ".so", ".dylib", ".bin", ".o", ".a",
    ".pyc", ".pyo", ".class", ".jar",
    ".zip", ".gz", ".tgz", ".bz2", ".xz", ".tar", ".7z", ".rar", ".pdf",
}

# Files larger than this are skipped: they are almost never source code and
# reading them would waste memory. Keeps the scanner's footprint bounded.
MAX_FILE_BYTES = 5 * 1024 * 1024  # 5 MiB

# Named credential signatures. The *last* capturing group of each pattern is
# treated as the secret value so it can be redacted before anything is printed.
SECRET_PATTERNS = {
    "Generic API Key": re.compile(
        r"(?i)(api[_-]?key|apikey|auth[_-]?token|access[_-]?token)"
        r"[\s:=]+['\"]([a-zA-Z0-9]{16,})['\"]"
    ),
    "Google API Key": re.compile(r"(AIza[0-9A-Za-z\-_]{35})"),
    "AWS Access Key": re.compile(r"(AKIA[0-9A-Z]{16})"),
    "Slack Token": re.compile(r"(xox[baprs]-[0-9a-zA-Z]{10,48})"),
    "GitHub Personal Access Token": re.compile(r"(ghp_[a-zA-Z0-9]{36})"),
}

REDACTION_MARKER = "***REDACTED***"


def _secret_span(match):
    """Return the ``(start, end)`` offsets of the secret inside ``match``.

    The secret is the last non-empty capturing group, or the whole match when
    the pattern defines no capturing groups.
    """
    for index in range(match.re.groups, 0, -1):
        if match.group(index) is not None:
            return match.start(index), match.end(index)
    return match.start(0), match.end(0)


def mask_line(line, match):
    """Return ``line`` with the matched secret replaced by a fixed marker.

    The surrounding context is preserved so a reviewer can locate the leak, but
    the credential itself is never part of the returned string.
    """
    start, end = _secret_span(match)
    redacted = f"{line[:start]}{REDACTION_MARKER}{line[end:]}"
    return redacted.strip()


def _looks_binary(path):
    """Return True when the first block of ``path`` contains a NUL byte."""
    try:
        with path.open("rb") as probe:
            return b"\x00" in probe.read(1024)
    except OSError:
        # If we cannot even read the header, let the text pass below report it.
        return False


def scan_file(path):
    """Scan a single file and return a list of finding dictionaries.

    Each finding is ``{"name", "path", "line", "snippet"}`` where ``snippet``
    is redacted. Binary files, oversized files and unreadable files return an
    empty list instead of raising, so one bad file cannot abort a whole scan.

    Args:
        path: A :class:`pathlib.Path` to a regular file.

    Returns:
        A list of finding dictionaries (possibly empty).
    """
    findings = []
    path = Path(path)
    try:
        if path.suffix.lower() in SKIP_EXTENSIONS:
            return findings

        size = path.stat().st_size
        if size > MAX_FILE_BYTES:
            print(f"[!] Skipping large file ({size} bytes): {path}")
            return findings

        if _looks_binary(path):
            return findings

        with path.open("r", encoding="utf-8", errors="ignore") as handle:
            for line_no, line in enumerate(handle, start=1):
                for name, pattern in SECRET_PATTERNS.items():
                    for match in pattern.finditer(line):
                        findings.append({
                            "name": name,
                            "path": str(path),
                            "line": line_no,
                            "snippet": mask_line(line, match),
                        })
    except OSError as exc:
        print(f"[!] Could not read {path}: {exc}")
    return findings


def scan_directory(directory):
    """Recursively scan ``directory`` and return every finding.

    Skipped directories are pruned in place so :func:`os.walk` never descends
    into them.

    Args:
        directory: Root directory to walk (str or :class:`pathlib.Path`).

    Returns:
        A flat list of finding dictionaries across all scanned files.
    """
    root = Path(directory)
    findings = []
    for current, dirs, files in os.walk(root):
        dirs[:] = sorted(d for d in dirs if d not in SKIP_DIRS)
        for name in sorted(files):
            findings.extend(scan_file(Path(current) / name))
    return findings


def report(findings):
    """Print a human-readable report for ``findings``."""
    for finding in findings:
        print(f"[!] LEAK DETECTED [{finding['name']}] "
              f"{finding['path']}:{finding['line']}")
        print(f"    {finding['snippet']}")
    if not findings:
        print("[+] No hardcoded API keys or secrets detected.")
    else:
        print(f"[*] Scan complete. {len(findings)} potential leaks found.")


def main(argv=None):
    """Parse arguments, run the scan and return a process exit code."""
    parser = argparse.ArgumentParser(
        description="Scan a directory tree for hardcoded API keys and secrets.")
    parser.add_argument(
        "directory", nargs="?", default=".",
        help="directory to scan (default: current directory)")
    args = parser.parse_args(argv)

    target = Path(args.directory)
    print("=== API Key Leak Scanner ===")
    print(f"[*] Scanning directory: {target}")

    if not target.is_dir():
        print(f"[-] Error: {target} is not a directory.")
        return 2

    findings = scan_directory(target)
    report(findings)
    return 1 if findings else 0


if __name__ == "__main__":
    sys.exit(main())

Related pages

View the full toolkit on GitHub

Explore Termux Hub

Kali Toolkit

Toolkit home (145 scripts) Foundations Network recon Defensive monitoring Vulnerability scanning Enumeration System hardening

Termux tool guides

Apache Brutus Cloudflare Cool Commands Cpp Findomain Fsociety Geo Recon Ghost Eye Hacktronian Ipicker Javascript John Local Server Manjaro Naabu Ncat Nmap Nordvpn Onex Pydictor Python Quasar Recondog Subfinder Termux Banner Ubuntu Gui Wafw00F Web Recon

Learn

Home Termux cheatsheet Python JavaScript C++ Cool Termux commands About Termux Hub