Advertisement
xe1phix

eBPF-Syscall-Tracer.sh

May 2nd, 2025
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 16.22 KB | Cybersecurity | 0 0
  1. #!/bin/bash
  2. # eBPF Syscall Tracer
  3. #
  4. # This script uses eBPF to trace and analyze system calls made by suspicious processes.
  5. # It helps identify potential malware behavior patterns by monitoring syscall frequency,
  6. # arguments, and return values.
  7. #
  8. # Options:
  9. # 1. Trace all syscalls for a specific PID
  10. # 2. Monitor syscalls related to file operations
  11. # 3. Monitor syscalls related to network operations
  12. # 4. Monitor syscalls related to process creation
  13. # 5. Monitor syscalls related to memory operations
  14. # 6. Monitor syscalls related to permission changes
  15. # 7. Monitor specific syscall by name
  16. # 8. Monitor syscalls for newly created processes
  17. # 9. Generate frequency report of syscalls
  18. # 10. Filter syscalls by return value (errors)
  19. # 11. Trace syscalls with arguments
  20. # 12. Export traced syscalls to JSON format
  21. # 13. Compare syscall patterns with known malware profiles
  22. # 14. Detect anomalous syscall patterns
  23. # 15. Generate visualization of syscall relationships
  24. # 16. Exit
  25.  
  26. # Check for required tools
  27. command -v bpftrace >/dev/null 2>&1 || { echo "Error: bpftrace is required but not installed. Install with: apt-get install bpftrace"; exit 1; }
  28.  
  29. # Function to display menu
  30. show_menu() {
  31.     clear
  32.     echo "===== eBPF Syscall Tracer ====="
  33.     echo "1. Trace all syscalls for a specific PID"
  34.     echo "2. Monitor syscalls related to file operations"
  35.     echo "3. Monitor syscalls related to network operations"
  36.     echo "4. Monitor syscalls related to process creation"
  37.     echo "5. Monitor syscalls related to memory operations"
  38.     echo "6. Monitor syscalls related to permission changes"
  39.     echo "7. Monitor specific syscall by name"
  40.     echo "8. Monitor syscalls for newly created processes"
  41.     echo "9. Generate frequency report of syscalls"
  42.     echo "10. Filter syscalls by return value (errors)"
  43.     echo "11. Trace syscalls with arguments"
  44.     echo "12. Export traced syscalls to JSON format"
  45.     echo "13. Compare syscall patterns with known malware profiles"
  46.     echo "14. Detect anomalous syscall patterns"
  47.     echo "15. Generate visualization of syscall relationships"
  48.     echo "16. Exit"
  49.     echo "================================"
  50.     echo "Enter your choice [1-16]: "
  51. }
  52.  
  53. # Function to trace all syscalls for a specific PID
  54. trace_pid_syscalls() {
  55.     read -p "Enter PID to trace: " pid
  56.     echo "Tracing all syscalls for PID $pid. Press Ctrl+C to stop."
  57.     sudo bpftrace -e "tracepoint:syscalls:sys_enter_* /pid == $pid/ { @[probe] = count(); }"
  58. }
  59.  
  60. # Function to monitor file operation syscalls
  61. monitor_file_syscalls() {
  62.     echo "Monitoring file operation syscalls. Press Ctrl+C to stop."
  63.     sudo bpftrace -e '
  64.    tracepoint:syscalls:sys_enter_open,
  65.    tracepoint:syscalls:sys_enter_openat,
  66.    tracepoint:syscalls:sys_enter_read,
  67.    tracepoint:syscalls:sys_enter_write,
  68.    tracepoint:syscalls:sys_enter_close,
  69.    tracepoint:syscalls:sys_enter_unlink,
  70.    tracepoint:syscalls:sys_enter_rename,
  71.    tracepoint:syscalls:sys_enter_mkdir,
  72.    tracepoint:syscalls:sys_enter_rmdir
  73.    {
  74.        time("%H:%M:%S ");
  75.        printf("PID: %-6d COMM: %-16s SYSCALL: %s\n", pid, comm, probe);
  76.    }'
  77. }
  78.  
  79. # Function to monitor network operation syscalls
  80. monitor_network_syscalls() {
  81.     echo "Monitoring network operation syscalls. Press Ctrl+C to stop."
  82.     sudo bpftrace -e '
  83.    tracepoint:syscalls:sys_enter_socket,
  84.    tracepoint:syscalls:sys_enter_connect,
  85.    tracepoint:syscalls:sys_enter_accept,
  86.    tracepoint:syscalls:sys_enter_bind,
  87.    tracepoint:syscalls:sys_enter_listen,
  88.    tracepoint:syscalls:sys_enter_sendto,
  89.    tracepoint:syscalls:sys_enter_recvfrom,
  90.    tracepoint:syscalls:sys_enter_sendmsg,
  91.    tracepoint:syscalls:sys_enter_recvmsg
  92.    {
  93.        time("%H:%M:%S ");
  94.        printf("PID: %-6d COMM: %-16s SYSCALL: %s\n", pid, comm, probe);
  95.    }'
  96. }
  97.  
  98. # Function to monitor process creation syscalls
  99. monitor_process_syscalls() {
  100.     echo "Monitoring process creation syscalls. Press Ctrl+C to stop."
  101.     sudo bpftrace -e '
  102.    tracepoint:syscalls:sys_enter_fork,
  103.    tracepoint:syscalls:sys_enter_vfork,
  104.    tracepoint:syscalls:sys_enter_clone,
  105.    tracepoint:syscalls:sys_enter_execve,
  106.    tracepoint:syscalls:sys_enter_execveat,
  107.    tracepoint:syscalls:sys_exit_execve,
  108.    tracepoint:syscalls:sys_exit_execveat
  109.    {
  110.        time("%H:%M:%S ");
  111.        printf("PID: %-6d COMM: %-16s SYSCALL: %s\n", pid, comm, probe);
  112.    }'
  113. }
  114.  
  115. # Function to monitor memory operation syscalls
  116. monitor_memory_syscalls() {
  117.     echo "Monitoring memory operation syscalls. Press Ctrl+C to stop."
  118.     sudo bpftrace -e '
  119.    tracepoint:syscalls:sys_enter_mmap,
  120.    tracepoint:syscalls:sys_enter_mprotect,
  121.    tracepoint:syscalls:sys_enter_munmap,
  122.    tracepoint:syscalls:sys_enter_brk,
  123.    tracepoint:syscalls:sys_enter_mremap,
  124.    tracepoint:syscalls:sys_enter_remap_file_pages,
  125.    tracepoint:syscalls:sys_enter_madvise
  126.    {
  127.        time("%H:%M:%S ");
  128.        printf("PID: %-6d COMM: %-16s SYSCALL: %s\n", pid, comm, probe);
  129.    }'
  130. }
  131.  
  132. # Function to monitor permission change syscalls
  133. monitor_permission_syscalls() {
  134.     echo "Monitoring permission change syscalls. Press Ctrl+C to stop."
  135.     sudo bpftrace -e '
  136.    tracepoint:syscalls:sys_enter_chmod,
  137.    tracepoint:syscalls:sys_enter_fchmod,
  138.    tracepoint:syscalls:sys_enter_fchmodat,
  139.    tracepoint:syscalls:sys_enter_chown,
  140.    tracepoint:syscalls:sys_enter_fchown,
  141.    tracepoint:syscalls:sys_enter_fchownat,
  142.    tracepoint:syscalls:sys_enter_setuid,
  143.    tracepoint:syscalls:sys_enter_setgid,
  144.    tracepoint:syscalls:sys_enter_setreuid,
  145.    tracepoint:syscalls:sys_enter_setregid,
  146.    tracepoint:syscalls:sys_enter_setresuid,
  147.    tracepoint:syscalls:sys_enter_setresgid,
  148.    tracepoint:syscalls:sys_enter_setfsuid,
  149.    tracepoint:syscalls:sys_enter_setfsgid,
  150.    tracepoint:syscalls:sys_enter_capset
  151.    {
  152.        time("%H:%M:%S ");
  153.        printf("PID: %-6d COMM: %-16s SYSCALL: %s\n", pid, comm, probe);
  154.    }'
  155. }
  156.  
  157. # Function to monitor a specific syscall by name
  158. monitor_specific_syscall() {
  159.     read -p "Enter syscall name (without 'sys_' prefix): " syscall_name
  160.     echo "Monitoring $syscall_name syscall. Press Ctrl+C to stop."
  161.     sudo bpftrace -e "
  162.    tracepoint:syscalls:sys_enter_$syscall_name
  163.    {
  164.        time(\"%H:%M:%S \");
  165.        printf(\"PID: %-6d COMM: %-16s SYSCALL: %s\\n\", pid, comm, probe);
  166.    }"
  167. }
  168.  
  169. # Function to monitor syscalls for newly created processes
  170. monitor_new_processes() {
  171.     echo "Monitoring syscalls for newly created processes. Press Ctrl+C to stop."
  172.     sudo bpftrace -e '
  173.    tracepoint:syscalls:sys_exit_fork,
  174.    tracepoint:syscalls:sys_exit_vfork,
  175.    tracepoint:syscalls:sys_exit_clone
  176.    /args->ret > 0/
  177.    {
  178.        printf("New process created: PID %d (parent: %d, command: %s)\n", args->ret, pid, comm);
  179.        @new_pids[args->ret] = 1;
  180.    }
  181.  
  182.    tracepoint:syscalls:sys_enter_*
  183.    /@new_pids[pid]/
  184.    {
  185.        time("%H:%M:%S ");
  186.        printf("New PID: %-6d COMM: %-16s SYSCALL: %s\n", pid, comm, probe);
  187.    }'
  188. }
  189.  
  190. # Function to generate frequency report of syscalls
  191. generate_frequency_report() {
  192.     read -p "Enter PID to analyze (0 for all processes): " pid
  193.     read -p "Enter duration in seconds: " duration
  194.     if [ "$pid" -eq 0 ]; then
  195.         echo "Generating syscall frequency report for all processes for $duration seconds..."
  196.         sudo timeout $duration bpftrace -e 'tracepoint:syscalls:sys_enter_* { @[probe] = count(); }' > syscall_frequency_report.txt
  197.     else
  198.         echo "Generating syscall frequency report for PID $pid for $duration seconds..."
  199.         sudo timeout $duration bpftrace -e "tracepoint:syscalls:sys_enter_* /pid == $pid/ { @[probe] = count(); }" > syscall_frequency_report.txt
  200.     fi
  201.     echo "Report saved to syscall_frequency_report.txt"
  202.     echo "Top 10 most frequent syscalls:"
  203.     sort -nr -k2 syscall_frequency_report.txt | head -10
  204. }
  205.  
  206. # Function to filter syscalls by return value (errors)
  207. filter_by_return_value() {
  208.     echo "Monitoring syscalls that return errors. Press Ctrl+C to stop."
  209.     sudo bpftrace -e '
  210.    tracepoint:syscalls:sys_exit_*
  211.    /args->ret < 0/
  212.    {
  213.        time("%H:%M:%S ");
  214.        printf("PID: %-6d COMM: %-16s SYSCALL: %-30s RET: %d\n", pid, comm, probe, args->ret);
  215.    }'
  216. }
  217.  
  218. # Function to trace syscalls with arguments
  219. trace_syscalls_with_args() {
  220.     read -p "Enter PID to trace (0 for all processes): " pid
  221.     if [ "$pid" -eq 0 ]; then
  222.         echo "Tracing open syscalls with arguments for all processes. Press Ctrl+C to stop."
  223.         sudo bpftrace -e '
  224.        tracepoint:syscalls:sys_enter_open,
  225.        tracepoint:syscalls:sys_enter_openat
  226.        {
  227.            time("%H:%M:%S ");
  228.            printf("PID: %-6d COMM: %-16s SYSCALL: %s ", pid, comm, probe);
  229.            
  230.            if (probe == "tracepoint:syscalls:sys_enter_open") {
  231.                printf("PATH: %s FLAGS: %d MODE: %d\n",
  232.                    str(args->filename), args->flags, args->mode);
  233.            } else {
  234.                printf("FD: %d PATH: %s FLAGS: %d MODE: %d\n",
  235.                    args->dfd, str(args->filename), args->flags, args->mode);
  236.            }
  237.        }'
  238.     else
  239.         echo "Tracing open syscalls with arguments for PID $pid. Press Ctrl+C to stop."
  240.         sudo bpftrace -e "
  241.        tracepoint:syscalls:sys_enter_open,
  242.        tracepoint:syscalls:sys_enter_openat
  243.        /pid == $pid/
  244.        {
  245.            time(\"%H:%M:%S \");
  246.            printf(\"PID: %-6d COMM: %-16s SYSCALL: %s \", pid, comm, probe);
  247.            
  248.            if (probe == \"tracepoint:syscalls:sys_enter_open\") {
  249.                printf(\"PATH: %s FLAGS: %d MODE: %d\\n\",
  250.                    str(args->filename), args->flags, args->mode);
  251.            } else {
  252.                printf(\"FD: %d PATH: %s FLAGS: %d MODE: %d\\n\",
  253.                    args->dfd, str(args->filename), args->flags, args->mode);
  254.            }
  255.        }"
  256.     fi
  257. }
  258.  
  259. # Function to export traced syscalls to JSON format
  260. export_to_json() {
  261.     read -p "Enter PID to trace (0 for all processes): " pid
  262.     read -p "Enter duration in seconds: " duration
  263.     output_file="syscall_trace_$(date +%Y%m%d_%H%M%S).json"
  264.    
  265.     echo "Tracing syscalls for $duration seconds and exporting to $output_file..."
  266.     echo "{\"syscalls\": [" > $output_file
  267.    
  268.     if [ "$pid" -eq 0 ]; then
  269.         sudo timeout $duration bpftrace -e '
  270.        tracepoint:syscalls:sys_enter_*
  271.        {
  272.            printf("{\"timestamp\":\"%s\",\"pid\":%d,\"comm\":\"%s\",\"syscall\":\"%s\"},\n",
  273.                strftime("%Y-%m-%d %H:%M:%S", nsecs), pid, comm, probe);
  274.        }' >> $output_file
  275.     else
  276.         sudo timeout $duration bpftrace -e "
  277.        tracepoint:syscalls:sys_enter_*
  278.        /pid == $pid/
  279.        {
  280.            printf(\"{\\\"timestamp\\\":\\\"%s\\\",\\\"pid\\\":%d,\\\"comm\\\":\\\"%s\\\",\\\"syscall\\\":\\\"%s\\\"},\\n\",
  281.                strftime(\"%Y-%m-%d %H:%M:%S\", nsecs), pid, comm, probe);
  282.        }" >> $output_file
  283.     fi
  284.    
  285.     # Fix JSON format (remove trailing comma and close array)
  286.     sed -i '$ s/,$//' $output_file
  287.     echo "]}" >> $output_file
  288.    
  289.     echo "JSON export completed. Saved to $output_file"
  290. }
  291.  
  292. # Function to compare syscall patterns with known malware profiles
  293. compare_with_known_profiles() {
  294.     read -p "Enter PID to analyze: " pid
  295.     echo "Analyzing syscall patterns for PID $pid and comparing with known malware profiles..."
  296.    
  297.     # Create temporary files
  298.     temp_file=$(mktemp)
  299.    
  300.     # Collect syscall pattern for 10 seconds
  301.     echo "Collecting syscall pattern for 10 seconds..."
  302.     sudo timeout 10 bpftrace -e "
  303.    tracepoint:syscalls:sys_enter_*
  304.    /pid == $pid/
  305.    {
  306.        @[probe] = count();
  307.    }" > $temp_file
  308.    
  309.     # Define known malware patterns (simplified for demonstration)
  310.     echo "Comparing with known malware patterns..."
  311.     echo "
  312.    Cryptominer pattern: High frequency of CPU-intensive syscalls (nanosleep, clock_gettime)
  313.    Rootkit pattern: Unusual combinations of module-related syscalls, hidden processes
  314.    Backdoor pattern: Persistent network connections, unusual file access patterns
  315.    Data exfiltration: High frequency of read/write operations followed by network activity
  316.    "
  317.    
  318.     # Check for cryptominer pattern
  319.     if grep -q "nanosleep\|clock_gettime" $temp_file && grep -q "count: [0-9]\{3,\}" $temp_file; then
  320.         echo "WARNING: Process shows patterns consistent with cryptomining malware!"
  321.     fi
  322.    
  323.     # Check for rootkit pattern
  324.     if grep -q "init_module\|finit_module\|delete_module" $temp_file; then
  325.         echo "WARNING: Process shows patterns consistent with rootkit activity!"
  326.     fi
  327.    
  328.     # Check for backdoor pattern
  329.     network_count=$(grep -c "connect\|sendto\|recvfrom" $temp_file)
  330.     if [ "$network_count" -gt 10 ]; then
  331.         echo "WARNING: Process shows patterns consistent with backdoor activity!"
  332.     fi
  333.    
  334.     # Clean up
  335.     rm $temp_file
  336.     echo "Analysis complete."
  337. }
  338.  
  339. # Function to detect anomalous syscall patterns
  340. detect_anomalous_patterns() {
  341.     read -p "Enter monitoring duration in seconds: " duration
  342.     echo "Monitoring system for anomalous syscall patterns for $duration seconds..."
  343.    
  344.     # Create temporary files
  345.     baseline_file=$(mktemp)
  346.    
  347.     echo "Establishing baseline syscall frequency..."
  348.     sudo timeout 5 bpftrace -e '
  349.    tracepoint:syscalls:sys_enter_*
  350.    {
  351.        @[comm, probe] = count();
  352.    }' > $baseline_file
  353.    
  354.     echo "Monitoring for anomalies..."
  355.     sudo timeout $duration bpftrace -e '
  356.    tracepoint:syscalls:sys_enter_*
  357.    {
  358.        @syscalls[comm, probe] = count();
  359.    }
  360.  
  361.    interval:s:1
  362.    {
  363.        print(@syscalls);
  364.        print("Analyzing for anomalous patterns...");
  365.        clear(@syscalls);
  366.    }'
  367.    
  368.     # Clean up
  369.     rm $baseline_file
  370.     echo "Anomaly detection complete."
  371. }
  372.  
  373. # Function to generate visualization of syscall relationships
  374. generate_visualization() {
  375.     read -p "Enter PID to visualize: " pid
  376.     read -p "Enter duration in seconds: " duration
  377.     output_file="syscall_graph_$(date +%Y%m%d_%H%M%S).dot"
  378.    
  379.     echo "Generating syscall relationship graph for PID $pid for $duration seconds..."
  380.    
  381.     # Create DOT file header
  382.     echo "digraph syscall_graph {" > $output_file
  383.     echo "  node [shape=box];" >> $output_file
  384.    
  385.     # Collect syscall sequence
  386.     echo "Collecting syscall sequence..."
  387.     sudo timeout $duration bpftrace -e "
  388.    tracepoint:syscalls:sys_enter_*
  389.    /pid == $pid/
  390.    {
  391.        printf(\"%s -> \", probe);
  392.    }" | sed 's/tracepoint:syscalls:sys_enter_//g' | tr -d '\n' > syscall_sequence.txt
  393.    
  394.     # Process sequence to create graph edges
  395.     echo "Processing syscall sequence to create graph..."
  396.     prev_syscall=""
  397.     for syscall in $(cat syscall_sequence.txt | tr ' -> ' '\n' | grep -v "^$"); do
  398.         if [ ! -z "$prev_syscall" ]; then
  399.             echo "  \"$prev_syscall\" -> \"$syscall\";" >> $output_file
  400.         fi
  401.         prev_syscall=$syscall
  402.     done
  403.    
  404.     # Close DOT file
  405.     echo "}" >> $output_file
  406.    
  407.     echo "Visualization data saved to $output_file"
  408.     echo "To create a graph image, install graphviz and run: dot -Tpng $output_file -o syscall_graph.png"
  409.    
  410.     # Clean up
  411.     rm syscall_sequence.txt
  412. }
  413.  
  414. # Main function
  415. main() {
  416.     while true; do
  417.         show_menu
  418.         read choice
  419.        
  420.         case $choice in
  421.             1) trace_pid_syscalls ;;
  422.             2) monitor_file_syscalls ;;
  423.             3) monitor_network_syscalls ;;
  424.             4) monitor_process_syscalls ;;
  425.             5) monitor_memory_syscalls ;;
  426.             6) monitor_permission_syscalls ;;
  427.             7) monitor_specific_syscall ;;
  428.             8) monitor_new_processes ;;
  429.             9) generate_frequency_report ;;
  430.             10) filter_by_return_value ;;
  431.             11) trace_syscalls_with_args ;;
  432.             12) export_to_json ;;
  433.             13) compare_with_known_profiles ;;
  434.             14) detect_anomalous_patterns ;;
  435.             15) generate_visualization ;;
  436.             16) echo "Exiting..."; exit 0 ;;
  437.             *) echo "Invalid option. Press Enter to continue..."; read ;;
  438.         esac
  439.        
  440.         echo
  441.         echo "Operation completed. Press Enter to continue..."
  442.         read
  443.     done
  444. }
  445.  
  446. # Start the script
  447. main
  448.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement