Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- # eBPF Malicious Activity Monitor
- #
- # This script uses eBPF to monitor system activities in real-time for detecting
- # suspicious behaviors that could indicate malware. It traces syscalls, file operations,
- # network connections, and process creation with minimal overhead.
- #
- # Options:
- # 1. Monitor suspicious file operations
- # 2. Monitor suspicious network activities
- # 3. Monitor process creation chains
- # 4. Monitor privilege escalation attempts
- # 5. Detect library injection
- # 6. Monitor system call anomalies
- # 7. Detect container escape attempts
- # 8. Monitor suspicious kernel module loading
- # 9. Track file execution flow
- # 10. Monitor suspicious memory access patterns
- # 11. Track command execution
- # 12. DNS monitoring for data exfiltration
- # 13. Detect abnormal process behavior
- # 14. Monitor data access patterns
- # 15. Generate activity report
- # 16. Exit
- # Check for required tools
- check_required_tools() {
- missing_tools=()
- command -v bpftrace >/dev/null 2>&1 || missing_tools+=("bpftrace")
- command -v bpftool >/dev/null 2>&1 || missing_tools+=("bpftool")
- if [ ${#missing_tools[@]} -gt 0 ]; then
- echo "The following required tools are missing:"
- for tool in "${missing_tools[@]}"; do
- echo "- $tool"
- done
- echo "Install bpftrace and bpftool packages first."
- return 1
- fi
- # Check kernel version, need 4.18+ for good eBPF support
- kernel_version=$(uname -r | cut -d. -f1,2)
- if (( $(echo "$kernel_version < 4.18" | bc -l) )); then
- echo "Warning: Kernel version $kernel_version may have limited eBPF support."
- echo "Recommended kernel version is 4.18 or higher."
- fi
- return 0
- }
- # Function to display menu
- show_menu() {
- clear
- echo "===== eBPF Malicious Activity Monitor ====="
- echo "1. Monitor suspicious file operations"
- echo "2. Monitor suspicious network activities"
- echo "3. Monitor process creation chains"
- echo "4. Monitor privilege escalation attempts"
- echo "5. Detect library injection"
- echo "6. Monitor system call anomalies"
- echo "7. Detect container escape attempts"
- echo "8. Monitor suspicious kernel module loading"
- echo "9. Track file execution flow"
- echo "10. Monitor suspicious memory access patterns"
- echo "11. Track command execution"
- echo "12. DNS monitoring for data exfiltration"
- echo "13. Detect abnormal process behavior"
- echo "14. Monitor data access patterns"
- echo "15. Generate activity report"
- echo "16. Exit"
- echo "==========================================="
- echo "Enter your choice [1-16]: "
- }
- # Function to monitor suspicious file operations
- monitor_file_operations() {
- echo "Monitoring suspicious file operations using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/file_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/fs.h>
- #include <linux/path.h>
- // Sensitive directories to monitor
- BEGIN
- {
- printf("Monitoring suspicious file operations...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "FILE OPERATION");
- }
- // Monitor file opens in sensitive locations
- tracepoint:syscalls:sys_enter_openat
- {
- $filename = str(args->filename);
- // Check for access to sensitive files and directories
- if (
- strncmp($filename, "/etc/passwd", 11) == 0 ||
- strncmp($filename, "/etc/shadow", 11) == 0 ||
- strncmp($filename, "/etc/ssh", 8) == 0 ||
- strncmp($filename, "/etc/sudoers", 12) == 0 ||
- strncmp($filename, "/etc/crontab", 12) == 0 ||
- strncmp($filename, "/etc/cron.d", 10) == 0 ||
- strncmp($filename, "/var/run/utmp", 13) == 0 ||
- strncmp($filename, "/var/log", 8) == 0 ||
- strncmp($filename, "/proc", 5) == 0 ||
- strncmp($filename, "/dev/mem", 8) == 0 ||
- strncmp($filename, "/boot", 5) == 0 ||
- strncmp($filename, "/lib/modules", 12) == 0 ||
- strncmp($filename, "/root", 5) == 0
- )
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d OPEN %s (flags: %d)\n",
- comm, pid, uid, $filename, args->flags);
- }
- // Check for access to hidden files/directories in /tmp, /var/tmp, or /dev/shm
- if (
- (strncmp($filename, "/tmp/", 5) == 0 ||
- strncmp($filename, "/var/tmp/", 9) == 0 ||
- strncmp($filename, "/dev/shm/", 9) == 0) &&
- strncmp(basename($filename), ".", 1) == 0
- )
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d OPEN HIDDEN FILE %s (flags: %d)\n",
- comm, pid, uid, $filename, args->flags);
- }
- }
- // Monitor file modifications (write) in sensitive locations
- tracepoint:syscalls:sys_enter_write
- {
- $fd = args->fd;
- $count = args->count;
- // Only track writes that might be significant (avoid small writes)
- if ($count > 10) {
- @writes[pid, comm] = $fd;
- }
- }
- // Monitor file creation
- tracepoint:syscalls:sys_enter_creat,
- tracepoint:syscalls:sys_enter_mkdir
- {
- $filename = str(args->filename);
- // Check for creation in sensitive locations
- if (
- strncmp($filename, "/etc/", 5) == 0 ||
- strncmp($filename, "/bin/", 5) == 0 ||
- strncmp($filename, "/sbin/", 6) == 0 ||
- strncmp($filename, "/lib/", 5) == 0 ||
- strncmp($filename, "/lib64/", 7) == 0 ||
- strncmp($filename, "/usr/bin/", 9) == 0 ||
- strncmp($filename, "/usr/sbin/", 10) == 0 ||
- strncmp($filename, "/boot/", 6) == 0
- )
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CREATE %s\n",
- comm, pid, uid, $filename);
- }
- // Check for suspicious file creation (hidden files or suspicious extensions)
- if (
- (strncmp(basename($filename), ".", 1) == 0) ||
- (strncmp($filename + strlen($filename) - 3, ".so", 3) == 0) ||
- (strncmp($filename + strlen($filename) - 2, ".o", 2) == 0) ||
- (strncmp($filename + strlen($filename) - 3, ".ko", 3) == 0)
- )
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d SUSPICIOUS CREATE %s\n",
- comm, pid, uid, $filename);
- }
- }
- // Monitor chmod
- tracepoint:syscalls:sys_enter_chmod,
- tracepoint:syscalls:sys_enter_fchmod
- {
- $mode = args->mode;
- // Monitor suspicious permissions (setuid/setgid, world-writable)
- if (($mode & 06000) || ($mode & 0002)) {
- time("%H:%M:%S.%f ");
- if (probe == "tracepoint:syscalls:sys_enter_chmod") {
- printf("%-16s %-10d %-8d CHMOD %s mode:%o\n",
- comm, pid, uid, str(args->filename), $mode);
- } else {
- printf("%-16s %-10d %-8d FCHMOD fd:%d mode:%o\n",
- comm, pid, uid, args->fd, $mode);
- }
- }
- }
- // Monitor file deletion
- tracepoint:syscalls:sys_enter_unlink,
- tracepoint:syscalls:sys_enter_unlinkat,
- tracepoint:syscalls:sys_enter_rmdir
- {
- $filename = probe == "tracepoint:syscalls:sys_enter_unlink" ?
- str(args->pathname) :
- (probe == "tracepoint:syscalls:sys_enter_rmdir" ?
- str(args->pathname) :
- str(args->pathname));
- // Check for deletion of sensitive logs or config files
- if (
- strncmp($filename, "/var/log", 8) == 0 ||
- strncmp($filename, "/etc/", 5) == 0 ||
- strncmp($filename, "/root/.bash_history", 19) == 0 ||
- strncmp($filename, "/home/", 6) == 0
- )
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d DELETE %s\n",
- comm, pid, uid, $filename);
- }
- }
- END
- {
- printf("Suspicious file monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/file_monitor.bt
- # Clean up
- rm -f /tmp/file_monitor.bt
- }
- # Function to monitor suspicious network activities
- monitor_network_activities() {
- echo "Monitoring suspicious network activities using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/network_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/socket.h>
- #include <net/sock.h>
- BEGIN
- {
- printf("Monitoring suspicious network activities...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "NETWORK ACTIVITY");
- // Initialize common suspicious ports table
- @suspicious_ports[21] = "FTP";
- @suspicious_ports[22] = "SSH";
- @suspicious_ports[23] = "Telnet";
- @suspicious_ports[25] = "SMTP";
- @suspicious_ports[445] = "SMB";
- @suspicious_ports[1080] = "SOCKS";
- @suspicious_ports[1433] = "MSSQL";
- @suspicious_ports[1434] = "MSSQL";
- @suspicious_ports[3306] = "MySQL";
- @suspicious_ports[3389] = "RDP";
- @suspicious_ports[4444] = "Metasploit";
- @suspicious_ports[5432] = "PostgreSQL";
- @suspicious_ports[5900] = "VNC";
- @suspicious_ports[5901] = "VNC";
- @suspicious_ports[6379] = "Redis";
- @suspicious_ports[8080] = "HTTP Alt";
- @suspicious_ports[9050] = "Tor";
- @suspicious_ports[9051] = "Tor";
- }
- // Track outgoing connections
- tracepoint:syscalls:sys_enter_connect
- {
- $sa = (struct sockaddr *)args->uservaddr;
- if ($sa->sa_family == AF_INET || $sa->sa_family == AF_INET6) {
- @connect_attempts[pid, comm] = 1;
- }
- }
- // Detect successful outbound connections
- tracepoint:syscalls:sys_exit_connect
- /args->ret >= 0 && @connect_attempts[pid, comm]/
- {
- delete(@connect_attempts[pid, comm]);
- $sockaddr = (struct sockaddr_in *)curtask->mm->arg_start;
- $dport = ($sockaddr->sin_port >> 8) | (($sockaddr->sin_port << 8) & 0xff00);
- $daddr = ntop($sockaddr->sin_addr.s_addr);
- // Check for suspicious destination ports
- $port_info = @suspicious_ports[$dport];
- if ($port_info != 0) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CONNECT %s:%d [%s]\n",
- comm, pid, uid, $daddr, $dport, str($port_info));
- }
- // Log all connections to non-standard web ports
- if ($dport != 80 && $dport != 443 && $dport < 1024) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CONNECT %s:%d [Non-standard port]\n",
- comm, pid, uid, $daddr, $dport);
- }
- // Track high-volume connections
- @connections[comm, pid, $dport] = count();
- if (@connections[comm, pid, $dport] > 10) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d HIGH VOLUME CONNECTIONS to port %d (%d connections)\n",
- comm, pid, uid, $dport, @connections[comm, pid, $dport]);
- }
- }
- // Track listening sockets
- tracepoint:syscalls:sys_enter_bind
- {
- $sa = (struct sockaddr *)args->umyaddr;
- if ($sa->sa_family == AF_INET || $sa->sa_family == AF_INET6) {
- $sockaddr = (struct sockaddr_in *)$sa;
- $port = ($sockaddr->sin_port >> 8) | (($sockaddr->sin_port << 8) & 0xff00);
- // Check if non-root user is binding to privileged port
- if ($port < 1024 && uid != 0) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d BIND TO PRIVILEGED PORT %d [Non-root user]\n",
- comm, pid, uid, $port);
- }
- // Monitor non-standard ports
- if ($port > 10000) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d BIND TO HIGH PORT %d\n",
- comm, pid, uid, $port);
- }
- }
- }
- // Monitor raw socket creation (often used for packet sniffing)
- tracepoint:syscalls:sys_enter_socket
- /args->type == SOCK_RAW/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d RAW SOCKET CREATION [Possible sniffing]\n",
- comm, pid, uid);
- }
- // Monitor DNS queries for potential data exfiltration
- tracepoint:syscalls:sys_enter_sendto,
- tracepoint:syscalls:sys_enter_sendmsg
- /comm == "dig" || comm == "nslookup" || comm == "host" || comm == "ping" || comm == "drill"/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d DNS QUERY\n",
- comm, pid, uid);
- }
- // Monitor suspicious data uploads (large writes to network sockets)
- tracepoint:syscalls:sys_enter_sendto,
- tracepoint:syscalls:sys_enter_sendmsg,
- tracepoint:syscalls:sys_enter_write
- {
- $fd = args->fd;
- $info = nsid == 0 ? "" : "->";
- // Check if fd is a socket and data size is large
- if (args->count > 102400) { // 100KB threshold
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d LARGE DATA TRANSFER %d bytes\n",
- comm, pid, uid, args->count);
- }
- }
- END
- {
- clear(@suspicious_ports);
- clear(@connect_attempts);
- clear(@connections);
- printf("Network monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/network_monitor.bt
- # Clean up
- rm -f /tmp/network_monitor.bt
- }
- # Function to monitor process creation chains
- monitor_process_chains() {
- echo "Monitoring process creation chains using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/process_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- BEGIN
- {
- printf("Monitoring process creation chains...\n");
- printf("%-24s %-10s %-16s %-16s %-8s %s\n", "TIME", "PID", "PARENT", "PROCESS", "UID", "COMMAND");
- }
- // Trace process creation (execve)
- tracepoint:syscalls:sys_enter_execve
- {
- $filename = str(args->filename);
- $parent_pid = curtask->parent->pid;
- $parent_comm = curtask->parent->comm;
- time("%H:%M:%S.%f ");
- printf("%-10d %-16s %-16s %-8d %s",
- pid, comm, $parent_comm, uid, $filename);
- // Print first 3 arguments if available
- $argptr = args->argv;
- if ($argptr) {
- $arg = str(*(char **)$argptr);
- if ($arg) {
- printf(" %s", $arg);
- $argptr += 8;
- $arg = str(*(char **)$argptr);
- if ($arg) {
- printf(" %s", $arg);
- $argptr += 8;
- $arg = str(*(char **)$argptr);
- if ($arg) {
- printf(" %s", $arg);
- }
- }
- }
- }
- printf("\n");
- // Track process ancestry chain for detection
- @ancestry[pid] = $parent_pid;
- // Track shell spawning shells (possible lateral movement or privilege escalation)
- if (($parent_comm == "bash" || $parent_comm == "sh" || $parent_comm == "dash" ||
- $parent_comm == "zsh" || $parent_comm == "ksh" || $parent_comm == "fish") &&
- (comm == "bash" || comm == "sh" || comm == "dash" ||
- comm == "zsh" || comm == "ksh" || comm == "fish")) {
- printf("WARNING: Shell spawning shell detected! %s (%d) -> %s (%d)\n",
- $parent_comm, $parent_pid, comm, pid);
- }
- // Track suspicious process chains (web server -> shell)
- if (($parent_comm == "apache2" || $parent_comm == "nginx" || $parent_comm == "httpd") &&
- (comm == "bash" || comm == "sh" || comm == "dash" || comm == "perl" ||
- comm == "python" || comm == "php" || comm == "ruby")) {
- printf("WARNING: Web server spawning shell! %s (%d) -> %s (%d)\n",
- $parent_comm, $parent_pid, comm, pid);
- }
- // Track suspicious tool execution
- if (comm == "nc" || comm == "netcat" || comm == "ncat" || comm == "socat" ||
- comm == "wireshark" || comm == "tcpdump" || comm == "nmap" ||
- comm == "ssh-keygen" || comm == "hydra" || comm == "john" ||
- comm == "hashcat" || comm == "mimikatz") {
- printf("WARNING: Suspicious tool execution: %s\n", comm);
- }
- // Track suspicious command line parameters
- if (strstr(str(args->argv[0]), "base64") != 0 ||
- strstr(str(args->argv[0]), "-e /dev/tcp/") != 0 ||
- strstr(str(args->argv[0]), "wget") != 0 ||
- strstr(str(args->argv[0]), "curl") != 0 ||
- strstr(str(args->argv[0]), "nc -e") != 0 ||
- strstr(str(args->argv[0]), "bash -i") != 0 ||
- strstr(str(args->argv[0]), "bash -c") != 0) {
- printf("WARNING: Suspicious command parameters detected: %s\n", str(args->argv[0]));
- }
- }
- // Detect short-lived processes (potential for "living off the land" attacks)
- tracepoint:sched:sched_process_exit
- {
- $start_time = curtask->start_time / 1000000000;
- $current_time = nsecs / 1000000000;
- $duration = $current_time - $start_time;
- // Only alert for processes that run for less than a second
- // and are not common short-lived commands
- if ($duration < 1 &&
- comm != "ls" && comm != "id" && comm != "ps" &&
- comm != "cat" && comm != "grep" && comm != "date" &&
- comm != "uname" && comm != "echo" && comm != "which") {
- time("%H:%M:%S.%f ");
- printf("SHORT LIVED PROCESS: %-16s (PID: %-6d, Duration: %.3f seconds)\n",
- comm, pid, $duration);
- }
- }
- END
- {
- clear(@ancestry);
- printf("Process creation monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/process_monitor.bt
- # Clean up
- rm -f /tmp/process_monitor.bt
- }
- # Function to monitor privilege escalation attempts
- monitor_privilege_escalation() {
- echo "Monitoring privilege escalation attempts using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/privesc_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- BEGIN
- {
- printf("Monitoring privilege escalation attempts...\n");
- printf("%-24s %-16s %-10s %-8s %-8s %s\n", "TIME", "COMM", "PID", "UID", "EUID", "ACTIVITY");
- }
- // Monitor privilege changes
- tracepoint:syscalls:sys_enter_setuid,
- tracepoint:syscalls:sys_enter_setreuid,
- tracepoint:syscalls:sys_enter_setresuid,
- tracepoint:syscalls:sys_enter_setfsuid
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d %-8d SET*UID SYSCALL\n",
- comm, pid, uid, euid);
- }
- // Monitor sudo/su executions
- tracepoint:syscalls:sys_enter_execve
- /(strncmp(str(args->filename), "/usr/bin/sudo", 13) == 0) ||
- (strncmp(str(args->filename), "/bin/sudo", 9) == 0) ||
- (strncmp(str(args->filename), "/usr/bin/su", 11) == 0) ||
- (strncmp(str(args->filename), "/bin/su", 7) == 0) ||
- (strncmp(str(args->filename), "/usr/bin/pkexec", 15) == 0) ||
- (strncmp(str(args->filename), "/usr/bin/gksudo", 15) == 0)/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d %-8d PRIVILEGE ESCALATION TOOL: %s",
- comm, pid, uid, euid, str(args->filename));
- // Print first argument if available
- $argptr = args->argv + 8; // Skip the command name
- $arg = str(*(char **)$argptr);
- if ($arg) {
- printf(" %s", $arg);
- }
- printf("\n");
- }
- // Monitor capabilities changes
- tracepoint:syscalls:sys_enter_capset
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d %-8d CAPABILITIES CHANGE\n",
- comm, pid, uid, euid);
- }
- // Monitor SUID/SGID file executions
- tracepoint:syscalls:sys_enter_execve
- {
- $filestat = curtask->fs->pwd->d_path;
- if (curtask->status < 0x10000000) { // Has SUID/SGID
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d %-8d SUID/SGID EXECUTION: %s\n",
- comm, pid, uid, euid, str(args->filename));
- }
- // Check euid change during execution
- if (uid != euid) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d %-8d EFFECTIVE UID CHANGE during execution\n",
- comm, pid, uid, euid);
- }
- }
- // Track file permission changes to set SUID/SGID
- tracepoint:syscalls:sys_enter_chmod,
- tracepoint:syscalls:sys_enter_fchmod,
- tracepoint:syscalls:sys_enter_fchmodat
- {
- $mode = args->mode;
- // Check for SUID/SGID bit setting
- if ($mode & 06000) {
- time("%H:%M:%S.%f ");
- if (probe == "tracepoint:syscalls:sys_enter_chmod") {
- printf("%-16s %-10d %-8d %-8d ADDING SUID/SGID TO FILE: %s (mode:%o)\n",
- comm, pid, uid, euid, str(args->filename), $mode);
- } else if (probe == "tracepoint:syscalls:sys_enter_fchmodat") {
- printf("%-16s %-10d %-8d %-8d ADDING SUID/SGID TO FILE AT: %s (mode:%o)\n",
- comm, pid, uid, euid, str(args->filename), $mode);
- } else {
- printf("%-16s %-10d %-8d %-8d ADDING SUID/SGID TO FD: %d (mode:%o)\n",
- comm, pid, uid, euid, args->fd, $mode);
- }
- }
- }
- // Monitor kernel module parameters for privilege escalation
- kprobe:security_kernel_module_request
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d %-8d KERNEL MODULE REQUEST\n",
- comm, pid, uid, euid);
- }
- // Monitor processes trying to read sensitive credential files
- tracepoint:syscalls:sys_enter_openat
- /(strncmp(str(args->filename), "/etc/passwd", 11) == 0) ||
- (strncmp(str(args->filename), "/etc/shadow", 11) == 0) ||
- (strncmp(str(args->filename), "/etc/sudoers", 12) == 0) ||
- (strncmp(str(args->filename), "/etc/group", 10) == 0) ||
- (strncmp(str(args->filename), "/proc/self/mem", 14) == 0)/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d %-8d ACCESS TO SENSITIVE CREDENTIAL FILE: %s\n",
- comm, pid, uid, euid, str(args->filename));
- }
- END
- {
- printf("Privilege escalation monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/privesc_monitor.bt
- # Clean up
- rm -f /tmp/privesc_monitor.bt
- }
- # Function to detect library injection
- detect_library_injection() {
- echo "Detecting library injection using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/library_injection.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- #include <linux/fs.h>
- BEGIN
- {
- printf("Monitoring for library injection...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "ACTIVITY");
- }
- // Monitor dlopen calls
- uprobe:/usr/lib*/libdl.so*:dlopen
- {
- $library_path = str(arg0);
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d DLOPEN: %s\n",
- comm, pid, uid, $library_path);
- // Track suspicious library paths
- if (strncmp($library_path, "/tmp/", 5) == 0 ||
- strncmp($library_path, "/dev/shm/", 9) == 0 ||
- strncmp($library_path, "/var/tmp/", 9) == 0 ||
- strncmp($library_path, "/proc/", 6) == 0 ||
- strncmp($library_path, "./", 2) == 0) {
- printf("WARNING: Loading library from suspicious location: %s\n", $library_path);
- }
- // Track libraries being loaded by unusual processes
- if (comm != "java" && comm != "python" &&
- comm != "perl" && comm != "ruby" &&
- comm != "php" && comm != "node" &&
- comm != "systemd" && comm != "firefox" &&
- comm != "chrome" && comm != "apache2" &&
- comm != "nginx") {
- @unusual_loaders[comm, $library_path] = count();
- }
- }
- // Monitor mmap with PROT_EXEC
- tracepoint:syscalls:sys_enter_mmap
- /args->prot & 0x4/ // PROT_EXEC
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d MMAP WITH EXEC PERMISSION: size=%lu\n",
- comm, pid, uid, args->len);
- // Track processes creating executable memory
- @exec_mmap[comm, pid] = count();
- // Alert if a process creates many executable memory regions
- if (@exec_mmap[comm, pid] > 10) {
- printf("WARNING: Process creating many executable memory regions: %s (PID: %d)\n",
- comm, pid);
- }
- }
- // Monitor mprotect calls that add execute permission
- tracepoint:syscalls:sys_enter_mprotect
- /args->prot & 0x4/ // PROT_EXEC
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d MPROTECT ADDING EXEC PERMISSION: addr=%lx size=%lu\n",
- comm, pid, uid, args->addr, args->len);
- // Track processes modifying memory to be executable
- @exec_mprotect[comm, pid] = count();
- // Alert if a process modifies permissions to executable many times
- if (@exec_mprotect[comm, pid] > 5) {
- printf("WARNING: Process frequently modifying memory to executable: %s (PID: %d)\n",
- comm, pid);
- }
- }
- // Monitor process ptrace attach (could be used for code injection)
- tracepoint:syscalls:sys_enter_ptrace
- /args->request == 16/ // PTRACE_ATTACH
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d PTRACE ATTACH to PID %d\n",
- comm, pid, uid, args->pid);
- printf("WARNING: Process using ptrace to attach to another process. Possible injection attempt.\n");
- }
- // Monitor LD_PRELOAD environment variable in execve
- tracepoint:syscalls:sys_enter_execve
- {
- $envp = args->envp;
- // Check environment variables for LD_PRELOAD
- while ($envp != 0 && $envp != NULL) {
- $env = str(*(char **)$envp);
- if ($env != 0 && $env != NULL) {
- if (strncmp($env, "LD_PRELOAD=", 11) == 0) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d LD_PRELOAD DETECTED: %s\n",
- comm, pid, uid, $env);
- printf("WARNING: Process using LD_PRELOAD. Possible library injection.\n");
- }
- }
- $envp += 8; // Move to the next env var (64-bit pointer size)
- }
- }
- // Track creation of shared objects in suspicious locations
- tracepoint:syscalls:sys_enter_openat
- /(args->flags & 0x40) || (args->flags & 0x241)/ // O_CREAT or combination of O_WRONLY|O_CREAT|O_TRUNC
- {
- $filename = str(args->filename);
- if (strstr($filename, ".so") != 0) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CREATING SHARED OBJECT: %s\n",
- comm, pid, uid, $filename);
- if (strncmp($filename, "/tmp/", 5) == 0 ||
- strncmp($filename, "/dev/shm/", 9) == 0 ||
- strncmp($filename, "/var/tmp/", 9) == 0) {
- printf("WARNING: Creating shared object in suspicious location.\n");
- }
- }
- }
- // Report unusual combinations
- interval:s:10
- {
- printf("\n=== Unusual Library Loading Summary (10-sec interval) ===\n");
- print(@unusual_loaders);
- clear(@unusual_loaders);
- printf("\n=== Executable Memory Activity Summary (10-sec interval) ===\n");
- printf("Processes creating many executable memory regions:\n");
- print(@exec_mmap);
- clear(@exec_mmap);
- printf("Processes modifying memory to be executable:\n");
- print(@exec_mprotect);
- clear(@exec_mprotect);
- printf("=======================================================\n\n");
- }
- END
- {
- clear(@unusual_loaders);
- clear(@exec_mmap);
- clear(@exec_mprotect);
- printf("Library injection monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/library_injection.bt
- # Clean up
- rm -f /tmp/library_injection.bt
- }
- # Function to monitor system call anomalies
- monitor_syscall_anomalies() {
- echo "Monitoring system call anomalies using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/syscall_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- BEGIN
- {
- printf("Monitoring system call anomalies...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "SYSCALL");
- // Initialize rare syscall list
- @rare_syscalls[270] = "rare"; // pivot_root
- @rare_syscalls[124] = "rare"; // adjtimex
- @rare_syscalls[148] = "rare"; // uselib
- @rare_syscalls[203] = "rare"; // swapon
- @rare_syscalls[156] = "rare"; // swapoff
- @rare_syscalls[157] = "rare"; // sysctl
- @rare_syscalls[135] = "rare"; // sysfs
- @rare_syscalls[142] = "rare"; // quotactl
- @rare_syscalls[186] = "rare"; // ioperm
- @rare_syscalls[153] = "rare"; // iopl
- @rare_syscalls[94] = "rare"; // lstat
- @rare_syscalls[80] = "rare"; // chroot
- }
- // Track process system call patterns
- tracepoint:raw_syscalls:sys_enter
- {
- $syscall = args->id;
- // Increment syscall count for the process
- @process_syscalls[pid, comm, $syscall] = count();
- // Detect rare or suspicious syscalls
- if (@rare_syscalls[$syscall]) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d RARE SYSCALL: %d\n",
- comm, pid, uid, $syscall);
- }
- // Detect suspicious sequences
- // First, store the current syscall
- @last_syscall[pid] = $syscall;
- }
- // Track process system call exit
- tracepoint:raw_syscalls:sys_exit
- {
- $syscall = @last_syscall[pid];
- $ret = args->ret;
- // Track failed sensitive syscalls
- if ($ret < 0 &&
- ($syscall == 59 || // execve
- $syscall == 62 || // kill
- $syscall == 57 || // fork
- $syscall == 56 || // clone
- $syscall == 105 || // setuid
- $syscall == 106 || // setgid
- $syscall == 2 || // open
- $syscall == 257 || // openat
- $syscall == 80)) { // chroot
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d FAILED SENSITIVE SYSCALL: %d (ret: %d)\n",
- comm, pid, uid, $syscall, $ret);
- // Increment failed sensitive syscall count
- @failed_sensitive[pid, comm, $syscall] = count();
- // Alert on multiple failures (potential brute force)
- if (@failed_sensitive[pid, comm, $syscall] > 3) {
- printf("WARNING: Multiple failed sensitive syscalls - possible brute force: %s (PID: %d)\n",
- comm, pid);
- }
- }
- }
- // Detect processes with unusual syscall patterns
- interval:s:10
- {
- printf("\n=== Syscall Pattern Analysis (10-sec interval) ===\n");
- // Rare combinations of syscalls that could indicate unusual behavior
- $open_count = @process_syscalls[pid, comm, 2] + @process_syscalls[pid, comm, 257]; // open/openat
- $exec_count = @process_syscalls[pid, comm, 59]; // execve
- $socket_count = @process_syscalls[pid, comm, 41] + @process_syscalls[pid, comm, 42] +
- @process_syscalls[pid, comm, 43] + @process_syscalls[pid, comm, 44] +
- @process_syscalls[pid, comm, 45]; // socket ops
- // Check for unusual patterns
- if ($open_count > 100 && $exec_count > 5) {
- printf("WARNING: Process with high file access and execution: %s (PID: %d)\n",
- comm, pid);
- }
- if ($socket_count > 20 && $open_count > 50) {
- printf("WARNING: Process with high network and file activity: %s (PID: %d)\n",
- comm, pid);
- }
- printf("Top 10 processes by syscall volume:\n");
- print(@process_syscall_volume);
- printf("Failed sensitive syscalls:\n");
- print(@failed_sensitive);
- clear(@failed_sensitive);
- printf("==================================================\n\n");
- }
- END
- {
- clear(@rare_syscalls);
- clear(@process_syscalls);
- clear(@last_syscall);
- clear(@failed_sensitive);
- printf("System call anomaly monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/syscall_monitor.bt
- # Clean up
- rm -f /tmp/syscall_monitor.bt
- }
- # Function to detect container escape attempts
- detect_container_escape() {
- echo "Detecting container escape attempts using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/container_escape.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- #include <linux/nsproxy.h>
- #include <linux/mount.h>
- BEGIN
- {
- printf("Monitoring for container escape attempts...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "ACTIVITY");
- }
- // Track mount namespace changes
- tracepoint:syscalls:sys_enter_mount
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d MOUNT: %s -> %s (flags: %d)\n",
- comm, pid, uid, str(args->source), str(args->target), args->flags);
- // Detect mounting host devices or sensitive host directories
- if (strncmp(str(args->source), "/dev/", 5) == 0 ||
- strncmp(str(args->source), "/proc/", 6) == 0 ||
- strncmp(str(args->source), "/sys/", 5) == 0) {
- printf("WARNING: Possible container escape attempt - mounting host device: %s\n",
- str(args->source));
- }
- }
- // Track unshare/clone with namespace changes
- tracepoint:syscalls:sys_enter_unshare,
- tracepoint:syscalls:sys_enter_clone
- {
- $flags = args->flags;
- // CLONE_NEWNS, CLONE_NEWUTS, CLONE_NEWIPC, CLONE_NEWPID, CLONE_NEWNET, CLONE_NEWUSER
- if ($flags & 0x00020000 || $flags & 0x04000000 || $flags & 0x08000000 ||
- $flags & 0x20000000 || $flags & 0x40000000 || $flags & 0x10000000) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d NAMESPACE CHANGE: flags=0x%lx\n",
- comm, pid, uid, $flags);
- }
- }
- // Track setns syscall (changing namespaces)
- tracepoint:syscalls:sys_enter_setns
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d SETNS: fd=%d, type=0x%x\n",
- comm, pid, uid, args->fd, args->type);
- printf("WARNING: Process changing namespace. Possible container escape attempt.\n");
- }
- // Track pivot_root (often used in container escapes)
- tracepoint:syscalls:sys_enter_pivot_root
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d PIVOT_ROOT: new=%s, old=%s\n",
- comm, pid, uid, str(args->new_root), str(args->put_old));
- printf("WARNING: pivot_root syscall detected. Possible container escape attempt.\n");
- }
- // Track container breakout tools
- tracepoint:syscalls:sys_enter_execve
- {
- $filename = str(args->filename);
- if (strncmp($filename, "/proc/self/exe", 14) == 0 ||
- strstr($filename, "docker") ||
- strstr($filename, "runc") ||
- strstr($filename, "containerd") ||
- strstr($filename, "ctr")) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CONTAINER TOOL EXECUTION: %s\n",
- comm, pid, uid, $filename);
- }
- // Check for programs that are often used in container escapes
- if (strstr($filename, "nsenter") ||
- strstr($filename, "unshare") ||
- strstr($filename, "capsh")) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d SUSPICIOUS CONTAINER TOOL: %s\n",
- comm, pid, uid, $filename);
- printf("WARNING: Process using tools commonly associated with container escapes.\n");
- }
- }
- // Track attempts to access container engine socket
- tracepoint:syscalls:sys_enter_connect
- {
- $sockaddr = (struct sockaddr_un *)args->uservaddr;
- if ($sockaddr->sa_family == AF_UNIX) {
- $path = str($sockaddr->sun_path);
- if (strstr($path, "/var/run/docker.sock") ||
- strstr($path, "/run/docker.sock") ||
- strstr($path, "/run/containerd/") ||
- strstr($path, "/var/run/crio/")) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CONTAINER SOCKET ACCESS: %s\n",
- comm, pid, uid, $path);
- printf("WARNING: Process attempting to access container engine socket.\n");
- }
- }
- }
- // Track accesses to cgroup files which could be used for container escapes
- tracepoint:syscalls:sys_enter_openat
- {
- $filename = str(args->filename);
- if (strncmp($filename, "/proc/self/cgroup", 17) == 0 ||
- strncmp($filename, "/proc/self/mountinfo", 20) == 0 ||
- strncmp($filename, "/proc/*/cgroup", 14) == 0 ||
- strncmp($filename, "/sys/fs/cgroup/", 15) == 0) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CGROUP ACCESS: %s\n",
- comm, pid, uid, $filename);
- }
- }
- // Track capability changes which could indicate privilege escalation within container
- tracepoint:syscalls:sys_enter_capset
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CAPABILITY CHANGE\n", comm, pid, uid);
- if (uid != 0) {
- printf("WARNING: Non-root user attempting to change capabilities.\n");
- }
- }
- // Track ptrace operations that could be used for container escapes
- tracepoint:syscalls:sys_enter_ptrace
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d PTRACE: request=%ld, pid=%d\n",
- comm, pid, uid, args->request, args->pid);
- if (args->request == 12 || args->request == 13) { // PTRACE_GETREGS, PTRACE_SETREGS
- printf("WARNING: Process attempting to read/modify registers of another process.\n");
- }
- }
- END
- {
- printf("Container escape monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/container_escape.bt
- # Clean up
- rm -f /tmp/container_escape.bt
- }
- # Function to monitor suspicious kernel module loading
- monitor_kernel_modules() {
- echo "Monitoring suspicious kernel module loading using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/module_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- #include <linux/module.h>
- BEGIN
- {
- printf("Monitoring suspicious kernel module loading...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "ACTIVITY");
- }
- // Track init_module and finit_module syscalls
- tracepoint:syscalls:sys_enter_init_module
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d LOAD KERNEL MODULE: size=%lu\n",
- comm, pid, uid, args->len);
- // Non-root users shouldn't be loading modules
- if (uid != 0) {
- printf("WARNING: Non-root user attempting to load kernel module!\n");
- }
- }
- tracepoint:syscalls:sys_enter_finit_module
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d LOAD KERNEL MODULE via fd: %d flags: %s\n",
- comm, pid, uid, args->fd, str(args->uargs));
- // Non-root users shouldn't be loading modules
- if (uid != 0) {
- printf("WARNING: Non-root user attempting to load kernel module!\n");
- }
- }
- // Track module deletion
- tracepoint:syscalls:sys_enter_delete_module
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d DELETE KERNEL MODULE: %s flags: %d\n",
- comm, pid, uid, str(args->name), args->flags);
- // Non-root users shouldn't be deleting modules
- if (uid != 0) {
- printf("WARNING: Non-root user attempting to delete kernel module!\n");
- }
- }
- // Track kmod executions (often used to load modules)
- tracepoint:syscalls:sys_enter_execve
- /(strncmp(str(args->filename), "/sbin/insmod", 13) == 0) ||
- (strncmp(str(args->filename), "/sbin/modprobe", 15) == 0) ||
- (strncmp(str(args->filename), "/bin/kmod", 10) == 0)/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d KERNEL MODULE TOOL: %s",
- comm, pid, uid, str(args->filename));
- // Print first argument if available
- $argptr = args->argv + 8; // Skip the command name
- $arg = str(*(char **)$argptr);
- if ($arg) {
- printf(" %s", $arg);
- }
- printf("\n");
- // Check for module names that might be suspicious
- if (strstr($arg, "hide") ||
- strstr($arg, "rootkit") ||
- strstr($arg, "intercept") ||
- strstr($arg, "hook") ||
- strstr($arg, "stealth")) {
- printf("WARNING: Loading module with suspicious name: %s\n", $arg);
- }
- }
- // Track accesses to the module-related files and directories
- tracepoint:syscalls:sys_enter_openat
- /(strncmp(str(args->filename), "/lib/modules/", 13) == 0) ||
- (strncmp(str(args->filename), "/sys/module/", 12) == 0)/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d MODULE FILE ACCESS: %s\n",
- comm, pid, uid, str(args->filename));
- }
- // Monitor direct /dev/mem and /dev/kmem access (could be used for module injection)
- tracepoint:syscalls:sys_enter_open,
- tracepoint:syscalls:sys_enter_openat
- /(strncmp(str(args->filename), "/dev/mem", 8) == 0) ||
- (strncmp(str(args->filename), "/dev/kmem", 9) == 0) ||
- (strncmp(str(args->filename), "/dev/port", 9) == 0)/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d DIRECT MEMORY ACCESS: %s\n",
- comm, pid, uid, str(args->filename));
- printf("WARNING: Process attempting direct memory access. Possible module injection technique.\n");
- }
- // Track suspicious file creation in module directories
- tracepoint:syscalls:sys_enter_creat,
- tracepoint:syscalls:sys_enter_open,
- tracepoint:syscalls:sys_enter_openat
- /((args->flags & 0x40) || (args->flags & 0x241)) && // O_CREAT or O_WRONLY|O_CREAT|O_TRUNC
- (strncmp(str(args->filename), "/lib/modules/", 13) == 0)/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CREATING FILE IN MODULE DIRECTORY: %s\n",
- comm, pid, uid, str(args->filename));
- printf("WARNING: Creating file in kernel module directory.\n");
- }
- // Track access to kernel symbols (often used by rootkits)
- tracepoint:syscalls:sys_enter_open,
- tracepoint:syscalls:sys_enter_openat
- /(strncmp(str(args->filename), "/proc/kallsyms", 14) == 0) ||
- (strncmp(str(args->filename), "/boot/System.map", 16) == 0)/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d KERNEL SYMBOL ACCESS: %s\n",
- comm, pid, uid, str(args->filename));
- }
- // Monitor for module related sysctls
- tracepoint:syscalls:sys_enter_sysctl
- {
- $name = args->name;
- if ($name != 0 && $name != NULL) {
- if (strncmp(str($name), "kernel.modules_disabled", 23) == 0 ||
- strncmp(str($name), "kernel.tainted", 15) == 0) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d MODULE SYSCTL ACCESS: %s\n",
- comm, pid, uid, str($name));
- }
- }
- }
- END
- {
- printf("Kernel module monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/module_monitor.bt
- # Clean up
- rm -f /tmp/module_monitor.bt
- }
- # Function to track file execution flow
- track_file_execution() {
- echo "Tracking file execution flow using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/execution_flow.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- #include <linux/fs.h>
- BEGIN
- {
- printf("Tracking file execution flow...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "ACTIVITY");
- }
- // Track execve syscalls for program execution
- tracepoint:syscalls:sys_enter_execve
- {
- $filename = str(args->filename);
- $parent_pid = curtask->parent->pid;
- $parent_comm = curtask->parent->comm;
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d EXEC: %s (Parent: %s [%d])\n",
- comm, pid, uid, $filename, $parent_comm, $parent_pid);
- // Track execution chain
- @exec_chain[pid] = $parent_pid;
- @exec_program[pid] = $filename;
- // Check for suspicious execution patterns
- // Web server executing shells
- if (($parent_comm == "apache" || $parent_comm == "apache2" ||
- $parent_comm == "httpd" || $parent_comm == "nginx" ||
- $parent_comm == "php-fpm" || $parent_comm == "uwsgi") &&
- (strstr($filename, "/bin/sh") || strstr($filename, "/bin/bash") ||
- strstr($filename, "/bin/dash") || strstr($filename, "/usr/bin/perl") ||
- strstr($filename, "/usr/bin/python"))) {
- printf("WARNING: Web server executing shell - possible web compromise!\n");
- }
- // Database server executing shells
- if (($parent_comm == "mysqld" || $parent_comm == "postgres" ||
- $parent_comm == "oracle" || $parent_comm == "mongodb") &&
- (strstr($filename, "/bin/sh") || strstr($filename, "/bin/bash") ||
- strstr($filename, "/bin/dash"))) {
- printf("WARNING: Database server executing shell - possible SQL injection!\n");
- }
- // Suspicious execution from temporary directories
- if (strncmp($filename, "/tmp/", 5) == 0 ||
- strncmp($filename, "/var/tmp/", 9) == 0 ||
- strncmp($filename, "/dev/shm/", 9) == 0) {
- printf("WARNING: Executing file from temporary directory: %s\n", $filename);
- }
- // Suspicious command line tools
- if (strstr($filename, "/usr/bin/curl") ||
- strstr($filename, "/usr/bin/wget") ||
- strstr($filename, "/usr/bin/nc") ||
- strstr($filename, "/bin/nc") ||
- strstr($filename, "/usr/bin/netcat") ||
- strstr($filename, "/usr/bin/ncat")) {
- // Print first 3 arguments if available
- printf("Command arguments: ");
- $argptr = args->argv;
- if ($argptr) {
- $argptr += 8; // Skip the command name
- for ($i = 0; $i < 3; $i++) {
- $arg = str(*(char **)$argptr);
- if ($arg) {
- printf("%s ", $arg);
- $argptr += 8;
- } else {
- break;
- }
- }
- printf("\n");
- }
- }
- }
- // Track execution of scripts
- tracepoint:syscalls:sys_enter_execve
- /(strstr(str(args->filename), ".sh") ||
- strstr(str(args->filename), ".py") ||
- strstr(str(args->filename), ".pl") ||
- strstr(str(args->filename), ".rb") ||
- strstr(str(args->filename), ".php"))/
- {
- $filename = str(args->filename);
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d SCRIPT EXEC: %s\n",
- comm, pid, uid, $filename);
- // Open and read the beginning of the script to detect shebang
- // This is a simplification; in real eBPF code, you would need
- // a more complex approach to read file contents
- }
- // Track chmod +x operations (making files executable)
- tracepoint:syscalls:sys_enter_chmod
- {
- $filename = str(args->filename);
- $mode = args->mode;
- // Check if executable bits are being set
- if ($mode & 0111) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d CHMOD +x: %s (mode: %o)\n",
- comm, pid, uid, $filename, $mode);
- // Check for suspicious locations
- if (strncmp($filename, "/tmp/", 5) == 0 ||
- strncmp($filename, "/var/tmp/", 9) == 0 ||
- strncmp($filename, "/dev/shm/", 9) == 0) {
- printf("WARNING: Making file executable in suspicious location: %s\n", $filename);
- }
- }
- }
- // Track execution exit and build execution chains
- tracepoint:sched:sched_process_exit
- /@exec_program[pid]/
- {
- $parent_pid = @exec_chain[pid];
- $program = @exec_program[pid];
- // Track short-lived programs
- $duration = (nsecs - curtask->start_time) / 1000000; // ms
- if ($duration < 100) { // Less than 100ms
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d SHORT-LIVED EXECUTION: %s (Duration: %d ms)\n",
- comm, pid, uid, $program, $duration);
- }
- // Clean up our tracking
- delete(@exec_chain[pid]);
- delete(@exec_program[pid]);
- }
- // Periodically report on execution chains
- interval:s:30
- {
- printf("\n=== Execution Chain Summary (30-sec interval) ===\n");
- printf("Active execution chains (PID -> Parent PID):\n");
- print(@exec_chain);
- printf("===============================================\n\n");
- }
- END
- {
- clear(@exec_chain);
- clear(@exec_program);
- printf("Execution flow tracking stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/execution_flow.bt
- # Clean up
- rm -f /tmp/execution_flow.bt
- }
- # Function to monitor suspicious memory access patterns
- monitor_memory_patterns() {
- echo "Monitoring suspicious memory access patterns using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/memory_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- BEGIN
- {
- printf("Monitoring suspicious memory access patterns...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "ACTIVITY");
- }
- // Track memory mapping operations with execute permission
- tracepoint:syscalls:sys_enter_mmap
- /args->prot & 0x4/ // PROT_EXEC
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d MMAP WITH EXEC PERMISSION: size=%lu\n",
- comm, pid, uid, args->len);
- // Track anonymous executable mappings (no file descriptor)
- if (args->fd == -1) {
- printf("WARNING: Anonymous executable memory mapping - possible shellcode injection\n");
- }
- // Track processes creating many executable memory regions
- @exec_mmap[comm, pid] = count();
- }
- // Track memory protection changes that add execute permission
- tracepoint:syscalls:sys_enter_mprotect
- /args->prot & 0x4/ // PROT_EXEC
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d MPROTECT ADDING EXEC PERMISSION: addr=%lx size=%lu\n",
- comm, pid, uid, args->addr, args->len);
- // Track processes modifying permissions to make memory executable
- @exec_mprotect[comm, pid] = count();
- // Alert on modifications of large memory regions
- if (args->len > 1048576) { // 1MB
- printf("WARNING: Large memory region made executable - possible code injection\n");
- }
- }
- // Track memory mapping from file descriptors (loading shared libraries)
- tracepoint:syscalls:sys_enter_mmap
- /args->fd >= 0/
- {
- // We would track file mappings here
- // This would require correlating fd with file paths
- // Full implementation would need to track open() calls and store fd->path mapping
- }
- // Track process memory writing
- tracepoint:syscalls:sys_enter_process_vm_writev
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d PROCESS_VM_WRITEV: pid=%d\n",
- comm, pid, uid, args->pid);
- printf("WARNING: Process writing to another process memory - possible code injection\n");
- }
- // Track access to /proc/pid/mem (direct process memory access)
- tracepoint:syscalls:sys_enter_open,
- tracepoint:syscalls:sys_enter_openat
- {
- $filename = str(args->filename);
- if (strstr($filename, "/proc/") && strstr($filename, "/mem")) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d DIRECT PROCESS MEMORY ACCESS: %s\n",
- comm, pid, uid, $filename);
- printf("WARNING: Process accessing another process memory directly\n");
- }
- }
- // Track ptrace operations that could be used for memory manipulation
- tracepoint:syscalls:sys_enter_ptrace
- /args->request == 4 || args->request == 5/ // PTRACE_POKETEXT, PTRACE_POKEDATA
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d PTRACE MEMORY WRITE: pid=%d\n",
- comm, pid, uid, args->pid);
- printf("WARNING: Process writing to another process memory via ptrace\n");
- }
- // Track suspicious msync patterns (flushing memory modifications to disk)
- tracepoint:syscalls:sys_enter_msync
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d MSYNC: addr=%lx len=%lu flags=%d\n",
- comm, pid, uid, args->start, args->len, args->flags);
- }
- // Track processes consuming high memory
- tracepoint:syscalls:sys_enter_brk,
- tracepoint:syscalls:sys_enter_mmap
- {
- @mem_ops[pid, comm] = count();
- }
- // Report on memory patterns periodically
- interval:s:10
- {
- printf("\n=== Memory Access Pattern Summary (10-sec interval) ===\n");
- printf("Processes creating executable memory regions:\n");
- print(@exec_mmap);
- printf("\nProcesses modifying memory to be executable:\n");
- print(@exec_mprotect);
- printf("\nProcesses with high memory allocation activity:\n");
- print(@mem_ops);
- printf("======================================================\n\n");
- // Alert on processes with both high mmap and mprotect counts
- $mmap_threshold = 5;
- $mprotect_threshold = 3;
- if (@exec_mmap[comm, pid] > $mmap_threshold && @exec_mprotect[comm, pid] > $mprotect_threshold) {
- printf("ALERT: Process %s (%d) shows patterns consistent with shellcode injection!\n",
- comm, pid);
- }
- // Clear counters after reporting
- clear(@mem_ops);
- }
- END
- {
- clear(@exec_mmap);
- clear(@exec_mprotect);
- clear(@mem_ops);
- printf("Memory pattern monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/memory_monitor.bt
- # Clean up
- rm -f /tmp/memory_monitor.bt
- }
- # Function to track command execution
- track_command_execution() {
- echo "Tracking command execution using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/command_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- BEGIN
- {
- printf("Tracking command execution...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "COMMAND");
- }
- // Track execve syscalls for command execution
- tracepoint:syscalls:sys_enter_execve
- {
- $filename = str(args->filename);
- $parent_pid = curtask->parent->pid;
- $parent_comm = curtask->parent->comm;
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d EXEC: %s",
- comm, pid, uid, $filename);
- // Print command line arguments
- $argptr = args->argv;
- printf(" ARGS: ");
- $count = 0;
- if ($argptr) {
- while ($count < 8) { // Limit to 8 arguments for display
- $arg = str(*(char **)$argptr);
- if ($arg != NULL && $arg != 0) {
- printf("%s ", $arg);
- $argptr += 8;
- $count++;
- } else {
- break;
- }
- }
- }
- printf("\n");
- // Track suspicious commands
- // Network commands
- if (strstr($filename, "/usr/bin/curl") ||
- strstr($filename, "/usr/bin/wget") ||
- strstr($filename, "/usr/bin/nc") ||
- strstr($filename, "/bin/nc") ||
- strstr($filename, "/usr/bin/netcat") ||
- strstr($filename, "/usr/bin/ssh") ||
- strstr($filename, "/usr/bin/sftp") ||
- strstr($filename, "/usr/bin/ftp") ||
- strstr($filename, "/usr/bin/scp")) {
- printf("NETWORK COMMAND DETECTED\n");
- }
- // Data encoding/compression commands
- if (strstr($filename, "/usr/bin/base64") ||
- strstr($filename, "/usr/bin/gzip") ||
- strstr($filename, "/usr/bin/bzip2") ||
- strstr($filename, "/usr/bin/xz") ||
- strstr($filename, "/usr/bin/tar") ||
- strstr($filename, "/usr/bin/zip") ||
- strstr($filename, "/usr/bin/7z")) {
- printf("DATA ENCODING/COMPRESSION COMMAND DETECTED\n");
- }
- // System information gathering commands
- if (strstr($filename, "/usr/bin/uname") ||
- strstr($filename, "/bin/hostname") ||
- strstr($filename, "/usr/bin/id") ||
- strstr($filename, "/usr/bin/whoami") ||
- strstr($filename, "/bin/ip") ||
- strstr($filename, "/bin/netstat") ||
- strstr($filename, "/usr/bin/ss") ||
- strstr($filename, "/usr/bin/ps") ||
- strstr($filename, "/usr/bin/top") ||
- strstr($filename, "/usr/bin/htop")) {
- printf("SYSTEM INFORMATION GATHERING COMMAND DETECTED\n");
- }
- // File access commands
- if (strstr($filename, "/bin/cat") ||
- strstr($filename, "/usr/bin/head") ||
- strstr($filename, "/usr/bin/tail") ||
- strstr($filename, "/usr/bin/less") ||
- strstr($filename, "/usr/bin/more") ||
- strstr($filename, "/bin/grep") ||
- strstr($filename, "/usr/bin/find") ||
- strstr($filename, "/usr/bin/locate")) {
- printf("FILE ACCESS COMMAND DETECTED\n");
- // Check if accessing sensitive files (via arguments)
- $argptr = args->argv + 8; // Skip the command name
- $arg = str(*(char **)$argptr);
- if ($arg) {
- if (strstr($arg, "/etc/passwd") ||
- strstr($arg, "/etc/shadow") ||
- strstr($arg, "/etc/ssh") ||
- strstr($arg, "/home/") ||
- strstr($arg, "/root/") ||
- strstr($arg, "/.ssh/") ||
- strstr($arg, "/var/log/")) {
- printf("WARNING: Accessing sensitive files: %s %s\n", $filename, $arg);
- }
- }
- }
- // Crypto/key commands
- if (strstr($filename, "/usr/bin/ssh-keygen") ||
- strstr($filename, "/usr/bin/gpg") ||
- strstr($filename, "/usr/bin/openssl")) {
- printf("CRYPTO/KEY OPERATION COMMAND DETECTED\n");
- }
- // Suspicious shell one-liners (using perl, python, ruby, etc. for one-liners)
- if ((strstr($filename, "/usr/bin/perl") ||
- strstr($filename, "/usr/bin/python") ||
- strstr($filename, "/usr/bin/ruby") ||
- strstr($filename, "/usr/bin/php")) &&
- (strstr(str(args->argv[1]), "-e") ||
- strstr(str(args->argv[1]), "-c"))) {
- printf("WARNING: Potential malicious one-liner detected!\n");
- }
- // Check if bash/sh is executing commands from standard input/pipe
- if ((strstr($filename, "/bin/bash") ||
- strstr($filename, "/bin/sh") ||
- strstr($filename, "/bin/dash")) &&
- (strstr(str(args->argv[1]), "-c"))) {
- printf("BASH/SH EXECUTING COMMAND STRING\n");
- }
- }
- // Track bash command history
- kprobe:add_history
- {
- time("%H:%M:%S.%f ");
- $cmd = str(arg0);
- printf("%-16s %-10d %-8d BASH HISTORY: %s\n",
- comm, pid, uid, $cmd);
- // Check for suspicious commands in bash history
- if (strstr($cmd, "wget ") ||
- strstr($cmd, "curl ") ||
- strstr($cmd, "nc ") ||
- strstr($cmd, "netcat ") ||
- strstr($cmd, "chmod +x") ||
- strstr($cmd, "base64 ") ||
- strstr($cmd, "python -c") ||
- strstr($cmd, "perl -e") ||
- strstr($cmd, "ruby -e") ||
- strstr($cmd, "php -r") ||
- strstr($cmd, ">/dev/tcp/") ||
- strstr($cmd, "mkfifo") ||
- strstr($cmd, "/dev/null 2>&1")) {
- printf("WARNING: Suspicious command in bash history: %s\n", $cmd);
- }
- }
- // Track command execution chains
- tracepoint:syscalls:sys_enter_execve
- {
- // Build command execution chain
- $parent_pid = curtask->parent->pid;
- $parent_comm = curtask->parent->comm;
- // Update command chain for this PID
- @cmd_chain[pid] = $parent_pid;
- @cmd_name[pid] = $filename;
- // Check for suspicious chains/patterns
- $grandparent_pid = @cmd_chain[$parent_pid];
- $grandparent_comm = comm; // This is a simplification; we'd need to track this separately
- // Detect web server -> shell -> download/network tool chain
- if (($grandparent_comm == "apache2" || $grandparent_comm == "nginx" || $grandparent_comm == "php-fpm") &&
- ($parent_comm == "sh" || $parent_comm == "bash" || $parent_comm == "dash") &&
- (strstr($filename, "wget") || strstr($filename, "curl") || strstr($filename, "nc"))) {
- printf("WARNING: Possible webshell detected! Command chain: %s -> %s -> %s\n",
- $grandparent_comm, $parent_comm, comm);
- }
- }
- // Report on command executions periodically
- interval:s:30
- {
- printf("\n=== Command Execution Summary (30-sec interval) ===\n");
- printf("Most active command sources:\n");
- print(@cmd_source);
- clear(@cmd_source);
- printf("================================================\n\n");
- }
- END
- {
- clear(@cmd_chain);
- clear(@cmd_name);
- clear(@cmd_source);
- printf("Command execution tracking stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/command_monitor.bt
- # Clean up
- rm -f /tmp/command_monitor.bt
- }
- # Function to monitor DNS for data exfiltration
- monitor_dns_exfiltration() {
- echo "Monitoring DNS for data exfiltration using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/dns_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- #include <net/sock.h>
- #include <linux/udp.h>
- #include <linux/ip.h>
- BEGIN
- {
- printf("Monitoring DNS for data exfiltration...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "DNS ACTIVITY");
- }
- // Track system calls for DNS queries
- tracepoint:syscalls:sys_enter_sendto,
- tracepoint:syscalls:sys_enter_sendmsg
- /args->fd >= 0/
- {
- @dns_send[pid, comm] = args->count;
- }
- // Track DNS outbound traffic by process (UDP port 53)
- tracepoint:syscalls:sys_exit_sendto,
- tracepoint:syscalls:sys_exit_sendmsg
- /@dns_send[pid, comm]/
- {
- $count = @dns_send[pid, comm];
- delete(@dns_send[pid, comm]);
- // Check for large DNS packets (potential data exfiltration)
- if ($count > 100) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d DNS QUERY: size=%d bytes\n",
- comm, pid, uid, $count);
- // Track DNS traffic volume per process
- @dns_traffic[comm, pid] += $count;
- // Check for high-volume traffic which may indicate tunneling/exfiltration
- if (@dns_traffic[comm, pid] > 10000) { // 10KB threshold
- printf("WARNING: High DNS traffic volume detected from %s (PID: %d) - possible exfiltration\n",
- comm, pid);
- }
- }
- }
- // Track DNS-related executables
- tracepoint:syscalls:sys_enter_execve
- /(strstr(str(args->filename), "dig") ||
- strstr(str(args->filename), "nslookup") ||
- strstr(str(args->filename), "host") ||
- strstr(str(args->filename), "drill") ||
- strstr(str(args->filename), "dnsmasq") ||
- strstr(str(args->filename), "drill") ||
- strstr(str(args->filename), "delv"))/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d DNS TOOL: %s",
- comm, pid, uid, str(args->filename));
- // Print command arguments if available
- $argptr = args->argv;
- printf(" ARGS: ");
- $count = 0;
- if ($argptr) {
- while ($count < 4) { // Limit to 4 arguments for display
- $arg = str(*(char **)$argptr);
- if ($arg != NULL && $arg != 0) {
- printf("%s ", $arg);
- $argptr += 8;
- $count++;
- } else {
- break;
- }
- }
- }
- printf("\n");
- // Check for suspicious DNS queries (very long or with unusual patterns)
- $argptr = args->argv + 8; // Skip the command name
- $arg = str(*(char **)$argptr);
- if ($arg) {
- $arg_len = strlen($arg);
- if ($arg_len > 50) { // Unusually long domain name
- printf("WARNING: Unusually long DNS query: %s\n", $arg);
- }
- // Check for many subdomains (potential for DNS tunneling)
- $dot_count = 0;
- for (int i = 0; i < $arg_len; i++) {
- if ($arg[i] == '.') {
- $dot_count++;
- }
- }
- if ($dot_count > 5) { // More than 5 subdomains is unusual
- printf("WARNING: Query with many subdomains (possible tunneling): %s\n", $arg);
- }
- // Check for hex/base64-like encoding in domain names
- $hex_chars = 0;
- $alnum_chars = 0;
- for (int i = 0; i < $arg_len; i++) {
- if (($arg[i] >= '0' && $arg[i] <= '9') ||
- ($arg[i] >= 'a' && $arg[i] <= 'f') ||
- ($arg[i] >= 'A' && $arg[i] <= 'F')) {
- $hex_chars++;
- }
- if (($arg[i] >= '0' && $arg[i] <= '9') ||
- ($arg[i] >= 'a' && $arg[i] <= 'z') ||
- ($arg[i] >= 'A' && $arg[i] <= 'Z')) {
- $alnum_chars++;
- }
- }
- if ($hex_chars > 0.8 * $alnum_chars && $arg_len > 20) {
- printf("WARNING: Query with hex-like encoding (possible exfiltration): %s\n", $arg);
- }
- }
- }
- // Track DNS resolution attempts via /etc/resolv.conf access
- tracepoint:syscalls:sys_enter_open,
- tracepoint:syscalls:sys_enter_openat
- /(strstr(str(args->filename), "/etc/resolv.conf") ||
- strstr(str(args->filename), "/etc/hosts"))/
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d DNS CONFIG ACCESS: %s\n",
- comm, pid, uid, str(args->filename));
- }
- // Report on DNS exfiltration indicators periodically
- interval:s:30
- {
- printf("\n=== DNS Exfiltration Indicators (30-sec interval) ===\n");
- printf("Processes with high DNS traffic volume:\n");
- print(@dns_traffic);
- printf("=====================================================\n\n");
- // Reset counters
- clear(@dns_traffic);
- }
- END
- {
- clear(@dns_send);
- clear(@dns_traffic);
- printf("DNS exfiltration monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/dns_monitor.bt
- # Clean up
- rm -f /tmp/dns_monitor.bt
- }
- # Function to detect abnormal process behavior
- detect_abnormal_process() {
- echo "Detecting abnormal process behavior using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/abnormal_process.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- BEGIN
- {
- printf("Detecting abnormal process behavior...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "ACTIVITY");
- }
- // Track process creation
- tracepoint:syscalls:sys_enter_execve
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d PROCESS STARTED: %s\n",
- comm, pid, uid, str(args->filename));
- // Record process start time
- @proc_start_time[pid] = nsecs;
- // Track process lineage
- $parent_pid = curtask->parent->pid;
- $parent_comm = curtask->parent->comm;
- @proc_parent[pid] = $parent_pid;
- @proc_cmd[pid] = str(args->filename);
- }
- // Track process exit
- tracepoint:sched:sched_process_exit
- /@proc_start_time[pid]/
- {
- $duration = (nsecs - @proc_start_time[pid]) / 1000000000; // seconds
- $parent_pid = @proc_parent[pid];
- $cmd = @proc_cmd[pid];
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d PROCESS EXITED: Duration=%d seconds\n",
- comm, pid, uid, $duration);
- // Detect short-lived processes
- if ($duration < 1 && comm != "ps" && comm != "ls" &&
- comm != "grep" && comm != "cat" && comm != "id") {
- printf("UNUSUAL: Short-lived process: %s (%d)\n", comm, pid);
- }
- // Detect abnormally long running processes that should be short-lived
- if ($duration > 600 && // 10 minutes
- (comm == "cat" || comm == "ls" || comm == "cp" ||
- comm == "mv" || comm == "dd" || comm == "grep")) {
- printf("UNUSUAL: Long-running utility process: %s (%d)\n", comm, pid);
- }
- // Clean up tracking data
- delete(@proc_start_time[pid]);
- delete(@proc_parent[pid]);
- delete(@proc_cmd[pid]);
- }
- // Track execution of processes from unusual directories
- tracepoint:syscalls:sys_enter_execve
- /(strncmp(str(args->filename), "/tmp/", 5) == 0 ||
- strncmp(str(args->filename), "/var/tmp/", 9) == 0 ||
- strncmp(str(args->filename), "/dev/shm/", 9) == 0 ||
- strncmp(str(args->filename), "/home/", 6) == 0)/
- {
- printf("UNUSUAL: Executing from non-standard location: %s\n", str(args->filename));
- }
- // Track CPU-intensive processes
- tracepoint:sched:sched_stat_runtime
- /args->runtime > 1000000000/ // 100ms
- {
- @cpu_usage[pid, comm] += args->runtime;
- }
- // Track memory usage changes
- tracepoint:syscalls:sys_enter_mmap
- {
- @mem_alloc[pid, comm] += args->len;
- }
- // Track file access patterns
- tracepoint:syscalls:sys_enter_openat
- {
- @file_opens[pid, comm] = count();
- }
- // Track network activity
- tracepoint:syscalls:sys_enter_connect,
- tracepoint:syscalls:sys_enter_sendto,
- tracepoint:syscalls:sys_enter_sendmsg
- {
- @network_activity[pid, comm] = count();
- }
- // Detect abnormal patterns periodically
- interval:s:30
- {
- printf("\n=== Abnormal Process Behavior Analysis (30-sec interval) ===\n");
- // Identify CPU-intensive processes
- printf("Top CPU-intensive processes:\n");
- print(@cpu_usage);
- // Identify processes with high memory allocation
- printf("\nTop memory-allocating processes:\n");
- print(@mem_alloc);
- // Identify processes with high file activity
- printf("\nTop file-accessing processes:\n");
- print(@file_opens);
- // Identify processes with high network activity
- printf("\nTop network-active processes:\n");
- print(@network_activity);
- // Correlate activity across dimensions to identify abnormal behavior
- printf("\nProcesses with unusual behavior patterns:\n");
- // Detect processes with both high CPU and network activity (possible cryptominer)
- if (@cpu_usage[pid, comm] > 10000000000 && @network_activity[pid, comm] > 20) {
- printf("SUSPICIOUS: %s (PID: %d) has high CPU and network activity - possible cryptominer\n",
- comm, pid);
- }
- // Detect processes with high file and network activity (possible data exfiltration)
- if (@file_opens[pid, comm] > 100 && @network_activity[pid, comm] > 20) {
- printf("SUSPICIOUS: %s (PID: %d) has high file and network activity - possible data exfiltration\n",
- comm, pid);
- }
- printf("============================================================\n\n");
- // Reset counters
- clear(@cpu_usage);
- clear(@mem_alloc);
- clear(@file_opens);
- clear(@network_activity);
- }
- END
- {
- clear(@proc_start_time);
- clear(@proc_parent);
- clear(@proc_cmd);
- clear(@cpu_usage);
- clear(@mem_alloc);
- clear(@file_opens);
- clear(@network_activity);
- printf("Abnormal process behavior detection stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/abnormal_process.bt
- # Clean up
- rm -f /tmp/abnormal_process.bt
- }
- # Function to monitor data access patterns
- monitor_data_patterns() {
- echo "Monitoring data access patterns using eBPF. Press Ctrl+C to stop."
- # Create temporary BPF program
- cat > /tmp/data_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- #include <linux/fs.h>
- BEGIN
- {
- printf("Monitoring data access patterns...\n");
- printf("%-24s %-16s %-10s %-8s %s\n", "TIME", "COMM", "PID", "UID", "ACTIVITY");
- }
- // Track file open operations
- tracepoint:syscalls:sys_enter_open,
- tracepoint:syscalls:sys_enter_openat
- {
- $filename = probe == "tracepoint:syscalls:sys_enter_open" ?
- str(args->filename) : str(args->filename);
- // Track file opens by category
- if (strncmp($filename, "/etc/", 5) == 0) {
- @file_access[pid, comm, "config"] = count();
- }
- else if (strncmp($filename, "/var/log/", 9) == 0) {
- @file_access[pid, comm, "logs"] = count();
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d LOG ACCESS: %s\n",
- comm, pid, uid, $filename);
- }
- else if (strncmp($filename, "/home/", 6) == 0 || strncmp($filename, "/root/", 6) == 0) {
- @file_access[pid, comm, "home"] = count();
- // Check for access to sensitive user files
- if (strstr($filename, ".ssh/") ||
- strstr($filename, ".aws/") ||
- strstr($filename, ".config/") ||
- strstr($filename, ".bash_history") ||
- strstr($filename, ".profile") ||
- strstr($filename, ".bashrc")) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d SENSITIVE USER FILE: %s\n",
- comm, pid, uid, $filename);
- printf("WARNING: Access to sensitive user configuration/credential file detected\n");
- }
- }
- else if (strncmp($filename, "/var/lib/", 9) == 0 || strncmp($filename, "/var/db/", 8) == 0) {
- @file_access[pid, comm, "database"] = count();
- }
- else if (strncmp($filename, "/proc/", 6) == 0 || strncmp($filename, "/sys/", 5) == 0) {
- @file_access[pid, comm, "proc_sys"] = count();
- }
- }
- // Track file reads
- tracepoint:syscalls:sys_enter_read
- {
- $fd = args->fd;
- $count = args->count;
- // Track large reads
- if ($count > 1048576) { // 1MB
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d LARGE READ: fd=%d size=%lu\n",
- comm, pid, uid, $fd, $count);
- @large_reads[pid, comm] = count();
- }
- // Track total bytes read
- @bytes_read[pid, comm] += $count;
- }
- // Track file writes
- tracepoint:syscalls:sys_enter_write
- {
- $fd = args->fd;
- $count = args->count;
- // Track large writes
- if ($count > 1048576) { // 1MB
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d LARGE WRITE: fd=%d size=%lu\n",
- comm, pid, uid, $fd, $count);
- @large_writes[pid, comm] = count();
- }
- // Track total bytes written
- @bytes_written[pid, comm] += $count;
- }
- // Track directory scanning (readdir, etc)
- tracepoint:syscalls:sys_enter_getdents,
- tracepoint:syscalls:sys_enter_getdents64
- {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d SCANNING DIRECTORY: fd=%d\n",
- comm, pid, uid, args->fd);
- @dir_scans[pid, comm] = count();
- }
- // Track file scanning behavior (many opens)
- tracepoint:syscalls:sys_exit_open,
- tracepoint:syscalls:sys_exit_openat
- /args->ret >= 0/
- {
- @file_opens[pid, comm] = count();
- // Alert on process with many file opens
- if (@file_opens[pid, comm] > 100) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d HIGH-VOLUME FILE ACCESS: %d files\n",
- comm, pid, uid, @file_opens[pid, comm]);
- printf("WARNING: Process scanning many files, possible data mining/exfiltration\n");
- }
- }
- // Track specific access patterns
- tracepoint:syscalls:sys_enter_rename,
- tracepoint:syscalls:sys_enter_renameat,
- tracepoint:syscalls:sys_enter_renameat2
- {
- time("%H:%M:%S.%f ");
- if (probe == "tracepoint:syscalls:sys_enter_rename") {
- printf("%-16s %-10d %-8d RENAME: %s -> %s\n",
- comm, pid, uid, str(args->oldname), str(args->newname));
- } else {
- printf("%-16s %-10d %-8d RENAME: (at) fd=%d %s -> fd=%d %s\n",
- comm, pid, uid, args->olddfd, str(args->oldname),
- args->newdfd, str(args->newname));
- }
- // Detect file extension changes that might indicate ransomware
- $oldname = probe == "tracepoint:syscalls:sys_enter_rename" ?
- str(args->oldname) : str(args->oldname);
- $newname = probe == "tracepoint:syscalls:sys_enter_rename" ?
- str(args->newname) : str(args->newname);
- $old_len = strlen($oldname);
- $new_len = strlen($newname);
- // Check for ransomware-like extension appending
- if ($new_len > $old_len + 3 &&
- ($newname[$new_len - 4] == '.' || $newname[$new_len - 5] == '.') &&
- ($oldname[$old_len - 4] == '.' || $oldname[$old_len - 5] == '.')) {
- printf("WARNING: Possible ransomware behavior - changing file extensions\n");
- }
- @renames[pid, comm] = count();
- }
- // Track sequential file operations (possible encryption/ransomware)
- tracepoint:syscalls:sys_exit_open,
- tracepoint:syscalls:sys_exit_openat
- /args->ret >= 0/
- {
- // Increment sequential file open counter
- @sequential_access[pid, comm, args->ret] = nsecs;
- }
- tracepoint:syscalls:sys_enter_close
- /@sequential_access[pid, comm, args->fd]/
- {
- $time_diff = nsecs - @sequential_access[pid, comm, args->fd];
- delete(@sequential_access[pid, comm, args->fd]);
- // Check if it was a quick open-close sequence
- if ($time_diff < 1000000000) { // 1 second
- @quick_file_ops[pid, comm] = count();
- }
- // Alert on many quick file operations (potential ransomware/bulk encryption)
- if (@quick_file_ops[pid, comm] > 50) {
- time("%H:%M:%S.%f ");
- printf("%-16s %-10d %-8d RAPID FILE OPERATIONS: %d files\n",
- comm, pid, uid, @quick_file_ops[pid, comm]);
- printf("WARNING: Process rapidly accessing many files - possible ransomware/encryption\n");
- }
- }
- // Analyze data access patterns periodically
- interval:s:30
- {
- printf("\n=== Data Access Pattern Analysis (30-sec interval) ===\n");
- // File access by category
- printf("File access by category:\n");
- print(@file_access);
- // Large data transfers
- printf("\nProcesses performing large reads:\n");
- print(@large_reads);
- printf("\nProcesses performing large writes:\n");
- print(@large_writes);
- // High volume access
- printf("\nDirectory scanning operations:\n");
- print(@dir_scans);
- // Byte volume transfers
- printf("\nTotal bytes read by process:\n");
- print(@bytes_read);
- printf("\nTotal bytes written by process:\n");
- print(@bytes_written);
- // Detect suspicious patterns
- // Data exfiltration pattern: high read volume with network activity
- if (@bytes_read[pid, comm] > 10485760 && @network_activity[pid, comm] > 10) { // 10MB read + network
- printf("\nWARNING: Possible data exfiltration - process reading large amounts of data and using network: %s (PID: %d)\n",
- comm, pid);
- }
- // Ransomware pattern: high read volume, high write volume, many file operations
- if (@bytes_read[pid, comm] > 10485760 && @bytes_written[pid, comm] > 10485760 &&
- @quick_file_ops[pid, comm] > 30) {
- printf("\nWARNING: Possible ransomware - process with high read/write volume and many quick file operations: %s (PID: %d)\n",
- comm, pid);
- }
- // Reset counters for next interval
- clear(@file_access);
- clear(@large_reads);
- clear(@large_writes);
- clear(@dir_scans);
- clear(@bytes_read);
- clear(@bytes_written);
- clear(@quick_file_ops);
- printf("=======================================================\n\n");
- }
- END
- {
- clear(@file_access);
- clear(@large_reads);
- clear(@large_writes);
- clear(@dir_scans);
- clear(@file_opens);
- clear(@bytes_read);
- clear(@bytes_written);
- clear(@renames);
- clear(@sequential_access);
- clear(@quick_file_ops);
- clear(@network_activity);
- printf("Data access pattern monitoring stopped.\n");
- }
- EOF
- # Run the BPF program
- sudo bpftrace /tmp/data_monitor.bt
- # Clean up
- rm -f /tmp/data_monitor.bt
- }
- # Function to generate activity report
- generate_activity_report() {
- echo "Generating eBPF activity report. This will run multiple eBPF monitoring tools for a short time."
- # Create report directory
- report_dir="ebpf_report_$(date +%Y%m%d_%H%M%S)"
- mkdir -p "$report_dir"
- echo "eBPF Malicious Activity Report - $(date)" > "$report_dir/report.txt"
- echo "=====================================" >> "$report_dir/report.txt"
- # Run a series of short eBPF monitoring sessions
- echo "Running file operations monitoring..."
- # Create temporary BPF program for file operations
- cat > /tmp/report_file_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/fs.h>
- BEGIN
- {
- printf("Monitoring suspicious file operations...\n");
- }
- // Monitor file opens in sensitive locations
- tracepoint:syscalls:sys_enter_openat
- {
- $filename = str(args->filename);
- // Check for access to sensitive files and directories
- if (
- strncmp($filename, "/etc/passwd", 11) == 0 ||
- strncmp($filename, "/etc/shadow", 11) == 0 ||
- strncmp($filename, "/etc/ssh", 8) == 0 ||
- strncmp($filename, "/etc/sudoers", 12) == 0 ||
- strncmp($filename, "/etc/crontab", 12) == 0 ||
- strncmp($filename, "/var/log", 8) == 0
- )
- {
- printf("SENSITIVE FILE: PID %d (%s, UID %d) opened %s\n",
- pid, comm, uid, $filename);
- }
- // Check for access to hidden files/directories
- if (
- (strncmp($filename, "/tmp/", 5) == 0 ||
- strncmp($filename, "/var/tmp/", 9) == 0 ||
- strncmp($filename, "/dev/shm/", 9) == 0) &&
- strncmp(basename($filename), ".", 1) == 0
- )
- {
- printf("HIDDEN FILE: PID %d (%s, UID %d) accessed %s\n",
- pid, comm, uid, $filename);
- }
- }
- EOF
- # Run for 10 seconds
- timeout 10 sudo bpftrace /tmp/report_file_monitor.bt > "$report_dir/file_operations.txt" 2>&1
- echo -e "\n== File Operations ==" >> "$report_dir/report.txt"
- if grep -q "SENSITIVE FILE\|HIDDEN FILE" "$report_dir/file_operations.txt"; then
- echo "Suspicious file operations detected:" >> "$report_dir/report.txt"
- grep "SENSITIVE FILE\|HIDDEN FILE" "$report_dir/file_operations.txt" >> "$report_dir/report.txt"
- else
- echo "No suspicious file operations detected." >> "$report_dir/report.txt"
- fi
- # Run process monitoring
- echo "Running process monitoring..."
- # Create temporary BPF program for process monitoring
- cat > /tmp/report_process_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/sched.h>
- BEGIN
- {
- printf("Monitoring process creation...\n");
- }
- // Trace process creation (execve)
- tracepoint:syscalls:sys_enter_execve
- {
- $filename = str(args->filename);
- $parent_pid = curtask->parent->pid;
- $parent_comm = curtask->parent->comm;
- printf("PROCESS: %s (PID %d, PPID %d [%s]) executed %s\n",
- comm, pid, $parent_pid, $parent_comm, $filename);
- // Track shell spawning shells (possible lateral movement or privilege escalation)
- if (($parent_comm == "bash" || $parent_comm == "sh" || $parent_comm == "dash") &&
- (comm == "bash" || comm == "sh" || comm == "dash")) {
- printf("WARNING: Shell spawning shell detected! %s (%d) -> %s (%d)\n",
- $parent_comm, $parent_pid, comm, pid);
- }
- // Track suspicious process chains (web server -> shell)
- if (($parent_comm == "apache2" || $parent_comm == "nginx" || $parent_comm == "httpd") &&
- (comm == "bash" || comm == "sh" || comm == "dash" || comm == "perl" ||
- comm == "python" || comm == "php" || comm == "ruby")) {
- printf("WARNING: Web server spawning shell! %s (%d) -> %s (%d)\n",
- $parent_comm, $parent_pid, comm, pid);
- }
- }
- EOF
- # Run for 10 seconds
- timeout 10 sudo bpftrace /tmp/report_process_monitor.bt > "$report_dir/process_creation.txt" 2>&1
- echo -e "\n== Process Creation ==" >> "$report_dir/report.txt"
- if grep -q "WARNING" "$report_dir/process_creation.txt"; then
- echo "Suspicious process creation detected:" >> "$report_dir/report.txt"
- grep "WARNING" "$report_dir/process_creation.txt" >> "$report_dir/report.txt"
- else
- echo "No suspicious process creation detected." >> "$report_dir/report.txt"
- fi
- # Run network monitoring
- echo "Running network monitoring..."
- # Create temporary BPF program for network monitoring
- cat > /tmp/report_network_monitor.bt << 'EOF'
- #!/usr/bin/env bpftrace
- #include <linux/socket.h>
- #include <net/sock.h>
- BEGIN
- {
- printf("Monitoring network activities...\n");
- // Initialize common suspicious ports table
- @suspicious_ports[21] = "FTP";
- @suspicious_ports[22] = "SSH";
- @suspicious_ports[23] = "Telnet";
- @suspicious_ports[25] = "SMTP";
- @suspicious_ports[1080] = "SOCKS";
- @suspicious_ports[3389] = "RDP";
- @suspicious_ports[4444] = "Metasploit";
- @suspicious_ports[5900] = "VNC";
- @suspicious_ports[8080] = "HTTP Alt";
- @suspicious_ports[9050] = "Tor";
- }
- // Track outgoing connections
- tracepoint:syscalls:sys_enter_connect
- {
- $sa = (struct sockaddr *)args->uservaddr;
- if ($sa->sa_family == AF_INET || $sa->sa_family == AF_INET6) {
- @connect_attempts[pid, comm] = 1;
- }
- }
- // Detect successful outbound connections
- tracepoint:syscalls:sys_exit_connect
- /args->ret >= 0 && @connect_attempts[pid, comm]/
- {
- delete(@connect_attempts[pid, comm]);
- $sockaddr = (struct sockaddr_in *)curtask->mm->arg_start;
- $dport = ($sockaddr->sin_port >> 8) | (($sockaddr->sin_port << 8) & 0xff00);
- $daddr = ntop($sockaddr->sin_addr.s_addr);
- // Check for suspicious destination ports
- $port_info = @suspicious_ports[$dport];
- if ($port_info != 0) {
- printf("SUSPICIOUS CONNECTION: %s (PID %d, UID %d) connected to %s:%d [%s]\n",
- comm, pid, uid, $daddr, $dport, str($port_info));
- }
- // Log all connections to non-standard web ports
- if ($dport != 80 && $dport != 443 && $dport < 1024) {
- printf("NON-STANDARD PORT: %s (PID %d, UID %d) connected to %s:%d\n",
- comm, pid, uid, $daddr, $dport);
- }
- }
- EOF
- # Run for 10 seconds
- timeout 10 sudo bpftrace /tmp/report_network_monitor.bt > "$report_dir/network_activity.txt" 2>&1
- echo -e "\n== Network Activity ==" >> "$report_dir/report.txt"
- if grep -q "SUSPICIOUS CONNECTION\|NON-STANDARD PORT" "$report_dir/network_activity.txt"; then
- echo "Suspicious network activity detected:" >> "$report_dir/report.txt"
- grep "SUSPICIOUS CONNECTION\|NON-STANDARD PORT" "$report_dir/network_activity.txt" >> "$report_dir/report.txt"
- else
- echo "No suspicious network activity detected." >> "$report_dir/report.txt"
- fi
- # Add system summary information
- echo -e "\n== System Information ==" >> "$report_dir/report.txt"
- echo "Kernel version: $(uname -r)" >> "$report_dir/report.txt"
- echo "Hostname: $(hostname)" >> "$report_dir/report.txt"
- echo "Date: $(date)" >> "$report_dir/report.txt"
- # List running processes
- echo -e "\n== Running Processes ==" >> "$report_dir/report.txt"
- ps -eo pid,ppid,user,stat,pcpu,pmem,comm | head -20 >> "$report_dir/report.txt"
- # List network connections
- echo -e "\n== Network Connections ==" >> "$report_dir/report.txt"
- netstat -tupn | head -20 >> "$report_dir/report.txt"
- # List loaded kernel modules
- echo -e "\n== Loaded Kernel Modules ==" >> "$report_dir/report.txt"
- lsmod | head -20 >> "$report_dir/report.txt"
- # Create summary section
- echo -e "\n== Security Assessment ==" >> "$report_dir/report.txt"
- # Count suspicious events
- file_issues=$(grep -c "SENSITIVE FILE\|HIDDEN FILE" "$report_dir/file_operations.txt")
- process_issues=$(grep -c "WARNING" "$report_dir/process_creation.txt")
- network_issues=$(grep -c "SUSPICIOUS CONNECTION\|NON-STANDARD PORT" "$report_dir/network_activity.txt")
- total_issues=$((file_issues + process_issues + network_issues))
- echo "Total suspicious events detected: $total_issues" >> "$report_dir/report.txt"
- echo "- File operations: $file_issues" >> "$report_dir/report.txt"
- echo "- Process creation: $process_issues" >> "$report_dir/report.txt"
- echo "- Network activity: $network_issues" >> "$report_dir/report.txt"
- # Give overall assessment
- if [ $total_issues -gt 5 ]; then
- echo -e "\nHIGH RISK: Multiple suspicious activities detected." >> "$report_dir/report.txt"
- echo "Recommendation: Investigate system for possible compromise." >> "$report_dir/report.txt"
- elif [ $total_issues -gt 0 ]; then
- echo -e "\nMEDIUM RISK: Some suspicious activities detected." >> "$report_dir/report.txt"
- echo "Recommendation: Monitor system activity and investigate further." >> "$report_dir/report.txt"
- else
- echo -e "\nLOW RISK: No suspicious activities detected." >> "$report_dir/report.txt"
- echo "Recommendation: Continue regular monitoring." >> "$report_dir/report.txt"
- fi
- # Clean up temporary files
- rm -f /tmp/report_file_monitor.bt /tmp/report_process_monitor.bt /tmp/report_network_monitor.bt
- echo "Activity report generated and saved to: $report_dir/report.txt"
- }
- # Main function
- main() {
- # Check for required tools
- if ! check_required_tools; then
- echo "Please install required tools before continuing."
- exit 1
- fi
- # Check if running as root
- if [ "$(id -u)" != "0" ]; then
- echo "This script must be run as root or with sudo."
- exit 1
- fi
- while true; do
- show_menu
- read choice
- case $choice in
- 1) monitor_file_operations ;;
- 2) monitor_network_activities ;;
- 3) monitor_process_chains ;;
- 4) monitor_privilege_escalation ;;
- 5) detect_library_injection ;;
- 6) monitor_syscall_anomalies ;;
- 7) detect_container_escape ;;
- 8) monitor_kernel_modules ;;
- 9) track_file_execution ;;
- 10) monitor_memory_patterns ;;
- 11) track_command_execution ;;
- 12) monitor_dns_exfiltration ;;
- 13) detect_abnormal_process ;;
- 14) monitor_data_patterns ;;
- 15) generate_activity_report ;;
- 16) echo "Exiting..."; exit 0 ;;
- *) echo "Invalid option. Press Enter to continue..."; read ;;
- esac
- echo
- echo "Operation completed. Press Enter to continue..."
- read
- done
- }
- # Start the script
- main
Add Comment
Please, Sign In to add comment