ARP Monitoring script with notification and speech synthesis
A little bash script for GNU/Linux to monitor the system ARP table and detect duplicate entries leaved by ARP poisoning attacks.
See above in action :
-
State:
This is a Proof of Concept...
You can install 'notify-send' to be alerted by notifications and 'espeak' for the speech synthesis. -
License:
-
Code from my Github Gist:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters#!/bin/bash # arp_monitor.sh # Check if each IP address has a unique MAC address in the ARP table # Julien Deudon (initbrain) # Known duplicate MAC address # ("aa:bb:cc:dd:ee:ff" "aa:bb:cc:dd:ee:ff" "aa:bb:cc:dd:ee:ff") bypass_macaddr=() # Waiting time between each check wait=5 # Select the ARP information source # 0: 'cat /proc/net/arp' (without dns resolving, faster) # 1: 'arp -a' (attempt to determine hostnames) source=1 function colorize { echo -e "$(echo "$3" | sed -e "s/${2}/\\${1}${2}\\${endColor}/g")" } boldWhite='\e[1;37m' green='\e[1;32m' red='\e[1;31m' endColor='\e[0m' espeakBin=$(which espeak) if [ -z "$espeakBin" ] then echo "[!] Warning, 'espeak' need to be installed if you want voice alerting" fi notifyBin=$(which notify-send) if [ -z "$notifyBin" ] then echo "[!] Warning, 'libnotify-bin' need to be installed if you want notify alerting" fi echo "Launch in 3 seconds, please wait..." sleep 3 threatHistory="" for (( ; ; )) do # ARP table if [ ! $source ]; then arp_table=$(tail -n +2 /proc/net/arp | awk '{print $4,$1}') else arp_table=$(arp -a | awk '{print $4,$2,$1}' | sed 's/[\(\)]//g') fi # Formated ARP table string if [ ! $source ]; then formated=$(echo "$arp_table" | awk 'BEGIN{printf("%-22s%-20s\n","HW address","IP address")}{printf("%-22s%-20s\n",$1,$2)}') else formated=$(echo "$arp_table" | awk 'BEGIN{printf("%-22s%-20s%-30s\n","HW address","IP address","Hostname")}{printf("%-22s%-20s%-30s\n",$1,$2,$3)}') fi # Duplicate MAC address with the number of occurrences in parentheses if [ ! $source ]; then duplicate_occurrences=$(echo "$arp_table" | awk '{print $1}' | sort | uniq -c | grep -v '1 ' | awk '{print $2" ("$1")"}') else duplicate_occurrences=$(echo "$arp_table" | awk '{print $1}' | sort | uniq -c | grep -v '1 ' | awk '{print $2" ("$1")"}') fi # Duplicate MAC address duplicate=$(echo "$duplicate_occurrences" | awk '{print $1}') # Known duplicate MAC addresses colorized in green for macaddr in "${bypass_macaddr[@]}" do formated=$(colorize "$green" "$macaddr" "$formated") duplicate_occurrences=$(colorize "$green" "$macaddr" "$duplicate_occurrences") duplicate=$(echo -e "$duplicate" | grep -v "$macaddr") done # Unknown duplicate MAC addresses colorized in red for threat in "$duplicate" do if [ ! -z "$threat" ] then if [[ ! "$threatHistory" =~ "$threat" ]] then threatLines=$(echo -e "$arp_table" | grep "$threat") threatHistory="$threatHistory\n$(date)\n$threatLines" if [ ! -z "$espeakBin" ] then espeak -v en -s 120 'Warning, ARP poisoning detected !' & fi if [ ! -z "$notifyBin" ] then threatLinesSplited=(${threatLines//\\\t/ }) formatedThreat="$(date)\n---" if [ ! $source ]; then formatedThreat="$formatedThreat\nHW address: ${threatLinesSplited[0]}" formatedThreat="$formatedThreat\nIP address: ${threatLinesSplited[1]}" formatedThreat="$formatedThreat\n---" formatedThreat="$formatedThreat\nHW address: ${threatLinesSplited[2]}" formatedThreat="$formatedThreat\nIP address: ${threatLinesSplited[3]}" else formatedThreat="$formatedThreat\nHW address: ${threatLinesSplited[0]}" formatedThreat="$formatedThreat\nIP address: ${threatLinesSplited[1]}" formatedThreat="$formatedThreat\nHostname: ${threatLinesSplited[2]}" formatedThreat="$formatedThreat\n---" formatedThreat="$formatedThreat\nHW address: ${threatLinesSplited[3]}" formatedThreat="$formatedThreat\nIP address: ${threatLinesSplited[4]}" formatedThreat="$formatedThreat\nHostname: ${threatLinesSplited[5]}" fi notify-send -u critical -c network.error -i security-high-symbolic "ARP Poisoning Detected" "$formatedThreat" & fi fi formated=$(colorize "$red" "$threat" "$formated") duplicate_occurrences=$(colorize "$red" "$threat" "$duplicate_occurrences") fi done clear echo -e "${boldWhite}ARP table - $(date):${endColor}\n" echo -e "$formated" if [ ! -z "$duplicate_occurrences" ] then echo -e "\n${boldWhite}Suspicious MAC address (duplicate):${endColor}\n" echo -e "$duplicate_occurrences" fi if [ ! -z "$threatHistory" ] then echo -e "\n${boldWhite}History (threats) :${endColor}" echo -e "$threatHistory" fi sleep $wait done