├── LICENSE ├── README.md └── list-packet-sniffers └── list_packet_sniffers.sh /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Sandfly Security, Ltd 2 | www.sandflysecurity.com 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sandfly Security Linux Forensic Scripts 2 | 3 | This is a collection of scripts to help with Linux forensics and incident response tasks. 4 | 5 | # License 6 | 7 | Licensed under the MIT license unless stated otherwise. 8 | -------------------------------------------------------------------------------- /list-packet-sniffers/list_packet_sniffers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script lists processes that have packet sockets open by parsing /proc/net/packet. 3 | # 4 | # It accesses /proc/net/packet and /proc/[pid]/fd directly to find processes associated with 5 | # packet sockets. It can help find processes that are sniffing network traffic without relying 6 | # on external tools like lsof. 7 | # 8 | # Sandfly Security - www.sandflysecurity.com 9 | # Agentless Endpoint Detection and Response (EDR) for Linux 10 | # 11 | # Licensed under the MIT License (MIT) 12 | 13 | # Usage: Run this script with root privileges to ensure access to all process directories. 14 | 15 | if [ "$(id -u)" -ne 0 ]; then 16 | echo "This script must be run as root. Please use 'sudo' or switch to the root user." 17 | exit 1 18 | fi 19 | 20 | echo "Parsing inodes from /proc/net/packet and finding associated processes" 21 | echo "---------------------------------------------------------------------" 22 | 23 | # Check if /proc/net/packet exists 24 | if [ ! -f "/proc/net/packet" ]; then 25 | echo "Error: /proc/net/packet not found." 26 | exit 1 27 | fi 28 | 29 | # Read /proc/net/packet, skip header, and extract unique inode numbers 30 | inodes=$(awk 'NR > 1 {print $9}' /proc/net/packet | sort -u) 31 | 32 | if [ -z "$inodes" ]; then 33 | echo "No inodes found in /proc/net/packet. No packet sockets are currently open." 34 | exit 0 35 | fi 36 | 37 | echo "Found the following unique inodes in /proc/net/packet:" 38 | echo "$inodes" 39 | echo "" 40 | 41 | for packet_inode in $inodes; do 42 | echo "Searching for processes with packet socket inode: $packet_inode" 43 | found_process=false 44 | 45 | # Iterate through all process directories 46 | for pid_dir in /proc/[0-9]*; do 47 | pid=$(basename "$pid_dir") 48 | comm_file="$pid_dir/comm" 49 | exe_link="$pid_dir/exe" 50 | 51 | # Check if the process directory and its 'fd' subdirectory exist 52 | if [ ! -d "$pid_dir/fd" ]; then 53 | continue 54 | fi 55 | 56 | process_name="Unknown" 57 | if [ -f "$comm_file" ]; then 58 | process_name=$(cat "$comm_file") 59 | elif [ -L "$exe_link" ]; then 60 | # Fallback to executable path if 'comm' is not available 61 | process_name=$(readlink -f "$exe_link" | xargs basename) 62 | fi 63 | 64 | # Iterate through all file descriptors for the current process 65 | for fd_link in "$pid_dir"/fd/*; do 66 | if [ -L "$fd_link" ]; then 67 | # Read the target of the symlink 68 | target=$(readlink "$fd_link") 69 | 70 | # Check if the target is a socket and contains the inode number 71 | # Common format for socket file descriptors is "socket:[inode]" 72 | if [[ "$target" =~ ^socket:\[([0-9]+)\]$ ]]; then 73 | socket_inode="${BASH_REMATCH[1]}" 74 | 75 | if [ "$socket_inode" = "$packet_inode" ]; then 76 | echo " PID: $pid (Name: $process_name)" 77 | echo " FD: $(basename "$fd_link") -> $target" 78 | found_process=true 79 | fi 80 | fi 81 | fi 82 | done 83 | done 84 | 85 | if ! $found_process; then 86 | echo "No process found with a file descriptor linking to inode $packet_inode." 87 | echo "This may indicate that a process is grabbing packets but is not showing itself in /proc." 88 | echo "If you suspect a hidden process, consider using tools like 'sandfly-process-decloak' for further investigation." 89 | fi 90 | echo "---------------------------------------------------------------------" 91 | done 92 | 93 | echo "Script finished." 94 | --------------------------------------------------------------------------------