Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/sh
- VER="v2.03"
- #======================================================================================================= © 2016-2017 Martineau, v2.03
- #
- # Report on Hacker attempts to attack local LAN ports. (Usually called by IPSET_Block.sh as part of its Summary display)
- # ('IPSET_Block.sh v3.xx' if 'nolog' arg is used then this script will NOT be able to report on the attacks!!!)
- # ('IPSET_Block.sh v4.xx' optionally uses an IPSET as a crude database for logging the hack attempts as well as, or in place of, Syslog messages)
- #
- # The console display report is also created to disk and allows double-clicking on the URLs to help identify the port being attacked and its attacker.
- #
- # HackerPorts [help | -h] | [file_name_for report] [verbose] [syslog] [num=nn] [all] [wipe] [in=syslog_file]
- #
- # HackerPorts
- # Will produce a summary display of the top 10 WAN blocks in three categories: (unless default 'num=nn' has been specified)
- #
- # 4541 records scanned from Syslog ('/tmp/syslog.log')
- #
- # 07 May 13:58:40: # Unique Ports attacked via 'eth0': 172 (out of 2119 attempts) tracked via SYSLOG, May 5 20:39:18 - May 7 13:58:36
- #
- # ***ATTENTION 5 GRE (Generic Route Encapsulation) aka Virtual Private Network (VPN) attacks.
- #
- # Top 10 Ports attacked:
- # 4227 http://www.speedguide.net/port.php?port=23 e.g. https://dnsquery.org/ipwhois/1.10.130.6
- # <...>
- # Top 10 attackers:
- # 3 https://dnsquery.org/ipwhois/52.174.156.242
- # <...>
- # Last 10 most recent attackers:
- # https://dnsquery.org/ipwhois/146.185.239.117
- # <...>
- #
- # HackerPorts verbose
- # Will produce a summary display as above, but will also list ALL of the attacked ports and by whom! i.e. 167 in this example!!
- # HackerPorts syslog num=25
- # Will ignore the BlacklistTRK IPSET (if it exists) and use the Syslog attack messages and the top 25 (instead of 10) are listed.
- # HackerPorts all wipe
- # Will produce a summary display for ALL i.e. any interface (e.g. ppp0/vlan etc.) with the top 3 in each category listed.
- # NOTE: ALL tracking records to date will be *ERASED* from Syslog/BlacklistTRK IPSET.
- # HackerPorts syslog in=/mnt/USB/Syslog/Archive/syslog.log-20170416-144840
- # Will produce a summary display as above but will not use the current live '/tmp/syslog.log' instead '/mnt/USB/Syslog/Archive/syslog.log-20170416-144840' is used
- #
- # https://dnsquery.org/ipwhois/ is FREE but not 100% accurate?, whereas https://www.whoisxmlapi.com/ is accurate but ONLY 20 FREE IP lookups per Guest
- # Print between line beginning with '#==' to first blank line inclusive
- ShowHelp() {
- awk '/^#==/{f=1} f{print; if (!NF) exit}' $0
- }
- # Function Parse(String delimiter(s) variable_names)
- Parse() {
- #
- # Parse "Word1,Word2|Word3" ",|" VAR1 VAR2 REST
- # (Effectivley executes VAR1="Word1";VAR2="Word2";REST="Word3")
- local string IFS
- TEXT="$1"
- IFS="$2"
- shift 2
- read -r -- "$@" <<EOF
- $TEXT
- EOF
- }
- Tracking_Enabled () {
- # Try and determine if Port tracking is enabled - either via Syslog or IPSET
- # I really should use a semaphore such as NVRAM variable?
- # but someone will always complain about wasting a few precious bytes? if it generates the Yellow '!'
- local STATUS=0 # 0-DISABLED,1-Syslog,2-IPSET,3-Both
- local FN=
- if [ ! -z "$(grep -iE "/jffs/scripts/IPSET_Block\.sh" /jffs/scripts/firewall-start | grep -vE "^\#")" ];then
- if [ -z "$(grep -iE "/jffs/scripts/IPSET_Block\.sh.*nolog" /jffs/scripts/firewall-start)" ];then
- STATUS=1 # Yes Syslog i.e. 'nolog' wasn't specified
- else
- FN="/jffs/scripts/firewall-start"
- fi
- else
- if [ ! -z "$(grep -iE "/jffs/scripts/IPSET_Block\.sh" /jffs/scripts/services-start | grep -vE "^\#")" ];then
- if [ -z "$(grep -iE "/jffs/scripts/IPSET_Block\.sh.*nolog" /jffs/scripts/services-start)" ];then
- STATUS=1 # Yes Syslog i.e. 'nolog' wasn't specified
- else
- FN="/jffs/scripts/services-start"
- fi
- else
- if [ ! -z "$(grep -iE "/jffs/scripts/IPSET_Block\.sh" /jffs/scripts/post-mount | grep -vE "^\#")" ];then
- if [ -z "$(grep -iE "/jffs/scripts/IPSET_Block\.sh.*nolog" /jffs/scripts/post-mount)" ];then
- STATUS=1 # Yes Syslog i.e. 'nolog' wasn't specified
- else
- FN="/jffs/scripts/post-mount"
- fi
- fi
- fi
- fi
- if [ "$(ipset $LIST BlacklistTRK 2> /dev/null | wc -l)" -gt 0 ]; then
- STATUS=$(($STATUS+2)) # Yes - IPSET
- fi
- echo $STATUS","$FN
- }
- Delete_TempFiles () {
- rm $LOGFILE".tmp" 2> /dev/null
- rm $LOGFILE".new" 2> /dev/null
- return 0
- }
- #==============================================Main=============================================
- # Need assistance!???
- if [ "$1" == "help" ] || [ "$1" == "-h" ]; then
- ShowHelp
- exit 0
- fi
- MYROUTER=$(nvram get computer_name)
- if [ -d "/tmp/mnt/"$MYROUTER ];then
- MOUNT="/tmp/mnt/"$MYROUTER
- else
- MOUNT="/tmp"
- fi
- SYSLOG="/tmp/syslog.log"
- if [ "$( echo $@ | grep -o "in=" | wc -w )" -eq 1 ];then
- Parse "$( echo $@ | grep -oE "in=.*")" " =" v1 SYSLOG v3 # Use the supplied file to generate the report from.
- TRACKING=1 # Spoof a valid tracker status for the user file! ;-)
- else
- # Using standard Syslog, so a quick check to ensure 'nolog' isn't specifed!
- Parse "$(Tracking_Enabled)" "," TRACKING FN
- if [ "$TRACKING" == "0" ];then
- echo -e "\a\n\t***ERROR Tracking not enabled? - check '"$FN"' 'IPSET_Block.sh init' is used WITHOUT 'nolog'\n"
- logger -t "($(basename $0))" $$ "***ERROR Tracking not enabled? - check '"$FN"' 'IPSET_Block.sh init' is used WITHOUT 'nolog'"
- exit 96
- fi
- fi
- # Check that Syslog or the user supplied file actually exists!
- if [ ! -f $SYSLOG ];then
- echo -e "\a\n\t***ERROR Input Syslog file '$SYSLOG' NOT found\n"
- logger -t "($(basename $0))" $$ "***ERROR Input Syslog file '"$SYSLOG"' NOT found"
- exit 94
- fi
- if [ ! -z $1 ] && [ "$1" != "verbose" ] && [ -z $(echo $1 | grep -o "syslog") ] && \
- [ -z $(echo $1 | grep -o "num=") ] && [ -z $(echo $1 | grep -o "all") ] && \
- [ -z $(echo $1 | grep -o "wipe") ] && [ -z $(echo $1 | grep -o "in=") ] && \
- [ -z $(echo $1 | grep -o "any") ];then
- LOGFILE=$1
- else
- LOGFILE=${MOUNT}/HackerReport.txt
- fi
- Delete_TempFiles
- # 380.63+ for ARM routers, IPSET v6 is available...Load appropriate IPSET modules
- case $(ipset -v | grep -o "v[4,6]") in
- v6) MATCH_SET='--match-set'; LIST='list'; CREATE='create'; SAVE='save'; RESTORE='restore'; FLUSH='flush'; DESTROY='destroy'; ADD='add'; SWAP='swap'; IPHASH='hash:ip'; NETHASH='hash:net'; SETNOTFOUND='name does not exist'; TIMEOUT="timeout"
- lsmod | grep -q "xt_set" || for module in ip_set ip_set_hash_net ip_set_hash_ip xt_set
- do modprobe $module; done;;
- v4) MATCH_SET='--set'; LIST='--list'; CREATE='--create'; SAVE='--save'; RESTORE='--restore'; FLUSH='--flush'; DESTROY='--destroy'; ADD='--add'; SWAP='--swap'; IPHASH='iphash'; NETHASH='nethash'; SETNOTFOUND='Unknown set'; TIMEOUT=; RETAIN_SECS=
- lsmod | grep -q "ipt_set" || for module in ip_set ip_set_nethash ip_set_iphash ipt_set
- do modprobe $module; done;;
- *) logger -st "($(basename $0))" $$ "**ERROR** Unknown ipset version: $(ipset -v). Exiting." && (echo -e "\a";exit 99);;
- esac
- logger -st "($(basename $0))" $$ $VER "Hacker Port attacks Report....."
- if [ "$(ipset $LIST Blacklist 2> /dev/null | wc -l)" -eq 0 ];then
- echo -e "\a\n\t***ERROR IPSET Blacklist does not exist! - Please run 'IPSET_Block.sh init'\n"
- logger -t "($(basename $0))" $$ "***ERROR IPSET Blacklist does not exist! - Please run 'IPSET_Block.sh init'"
- exit 95
- fi
- VERBOSE=0
- if [ "$( echo $@ | grep -o "verbose" | wc -w )" -eq 1 ];then
- VERBOSE=1 # List ALL report lines rather than just the summary
- fi
- # How many attack items to be displayed in each category
- TOPX=10
- if [ "$( echo $@ | grep -o "num=" | wc -w )" -eq 1 ];then
- Parse "$( echo $@ | grep -oE "num=.*")" "=" v1 TOPX
- TOPX=$(echo $TOPX | cut -d" " -f1) # Tacky! regexp should be used properly!
- TOPX=$(echo $TOPX | sed 's/ //g') # Tacky! regexp should be used properly!
- if [ -z "$TOPX" ] || [ -z "${TOPX##*[!0-9]*}" ] || [ "$TOPX" -eq 0 ];then # Must be only digits and not blank or '0'
- TOPX=1
- echo -e "\a\n\t\e[91m***Warning \e[5m'num='\e[25m directive invalid...num=1 assumed!\e[0m"
- fi
- fi
- # Modern Firmware?
- if [ -z "$(which uniq)" ];then
- echo -e "\a\n\t***ERROR 'uniq' utility not installed?\n"
- logger -t "($(basename $0))" $$ "***ERROR 'uniq' utility not installed?"
- exit 97
- fi
- # How may input lines scanned/processed
- REC_CNT=0
- # Does the Port tracker IPSET exist with at least 1 entry?
- if [ "$(ipset $LIST BlacklistTRK 2> /dev/null | wc -l)" -gt 7 ] && [ "$( echo $@ | grep -o "syslog" | wc -w )" -eq 0 ];then
- ipset $LIST BlacklistTRK | grep -E "^[0-9]" | tr ",:" " " | sort -nk3 | uniq -f2 -c | while read ITEM
- do
- Parse "$ITEM" " " PORTCNT SRC v3 PORT
- echo -e "$(printf "%5d %-45s e.g. %s" $PORTCNT "http://www.speedguide.net/port.php?port="$PORT )" "https://dnsquery.org/ipwhois/"$SRC >> $LOGFILE.tmp
- done
- DTYPE="IPSET"
- PERIODTXT=
- REC_CNT=$(ipset $LIST BlacklistTRK | grep -E "^[0-9]" | wc -l)
- else
- if [ "$TRACKING" == "1" ] || [ "$TRACKING" == "3" ] ;then
- # Extract the relevant Hacker attempt msgs (created by /jffs/scripts/IPSET_Block.sh etc.) from file usually Syslog or an archived Syslog
- IFNAME=$(nvram get wan0_ifname)
- IIFXT="'"$IFNAME"'"
- if [ "$( echo $@ | grep -o "all" | wc -w )" -eq 1 ];then # WAN only report ?
- IFNAME= # ALL i.e. ANY interface e.g. 'ppp0' or 'vlan2' etc.
- IIFXT="ANY interface"
- fi
- # Report these 'GRE' attacks separately as they don't have a DST=
- # Block IN=eth0 OUT= MAC=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
- # SRC=114.34.75.79 DST=xxx.xxx.xxx.xxx
- # LEN=52 TOS=0x00 PREC=0x00 TTL=53 ID=63784
- # DF PROTO=47
- GRE_CNT=0
- GRE_CNT=$(grep -E "Block IN=$IFNAME" $SYSLOG | grep "PROTO=47" | wc -l )
- echo -e "\n\e[1;36mScanning" $SYSLOG "for" $IIFXT "violations, please wait.....\e[0m"
- # grep -E "Block IN=" /tmp/syslog.log | grep -oE "SRC=.*DPT=[0-9]+" | sed -e 's/SRC=//' -e 's/DPT=//' | awk '{ print $1" "$(NF) }' | sort -k2n | awk '{a[$2]++;}END{for (i in a)print i, a[i];}'
- # Weird, need to parse the clunky old-skool way :-(
- # Also wot if 'uniq -c ' isn't installed?
- # "awk '{a[$1]++;}END{for (i in a)print i, a[i];}'" counts how many times first word appears
- grep -E "Block IN=$IFNAME" $SYSLOG | \
- grep -v "PROTO=47" | \
- sed -e 's/^.*SRC=//' -e 's/SEQ.*$//' -e 's/LEN=.*TOS//' -e 's/WINDOW.*$//' -e 's/LEN=.*$//' -e 's/DPT=//' | \
- awk '{ print $1" "$(NF) }' | \
- sort -k2n | \
- uniq -f 1 -c |
- while read ITEM
- do
- Parse "$ITEM" " " PORTCNT SRC PORT
- echo -e "$(printf "%5d %-45s e.g. %s" $PORTCNT "http://www.speedguide.net/port.php?port="$PORT )" "https://dnsquery.org/ipwhois/"$SRC >> $LOGFILE.tmp
- done
- DTYPE="SYSLOG"
- REC_CNT=$(wc -l $SYSLOG | awk '{print $1}')
- # Beware in some Syslog extracts, the displayed month e.g. 'May' is actually 4 chars long! "May'0xa0'" ('0xa0' = 240 octal)
- # NOTE: The Unicode 0xa0 char is the ' ' so maybe it's just present when the user debug/test data is transferred from the forum?
- FIRSTTIMESTAMP=$(head -n 1 $SYSLOG | tr -d "\240" | awk '{print $1" "$2" "$3}')
- LASTTIMESTAMP=$(tail -n 1 $SYSLOG | tr -d "\240" | awk '{print $1" "$2" "$3}')
- PERIODTXT=", $FIRSTTIMESTAMP - $LASTTIMESTAMP"
- else
- echo -e "\a\t\n***ERROR Syslog Tracking DISABLED? - check '$FN' to run 'IPSET_Block.sh init'\n"
- logger -t "($(basename $0))" $$ "***ERROR Syslog Tracking DISABLED? - check '$FN' to run 'IPSET_Block.sh init'"
- exit 98
- fi
- fi
- UTOTAL=0;TOTAL=0
- if [ -f ${LOGFILE}.tmp ];then
- UTOTAL=$(wc -l ${LOGFILE}.tmp | cut -d" " -f1) # Unique Ports attacked
- TOTAL=$(awk -F' ' '{sum+=$1} END{print sum;}' ${LOGFILE}.tmp) # Physical number of attacks
- fi
- TIMESTAMP=$(date +"%d %b %T")":"
- echo -e "\n\n"$TIMESTAMP "# Unique Ports attacked via "$IIFXT":" $UTOTAL "(out of" $TOTAL "attempts) tracked via" $DTYPE"$PERIODTXT" >> $LOGFILE.new # New period's report Header
- logger -t "($(basename $0))" $$ "Hacker report created '"$LOGFILE"' - Statistics: Total Unique Ports attacked:" $UTOTAL "(out of" $TOTAL "attempts) tracked using" $DTYPE "$PERIODTXT"
- if [ $GRE_CNT -gt 0 ];then
- echo -e "\n\t***ATTENTION" $GRE_CNT "GRE (Generic Route Encapsulation) aka Virtual Private Network (VPN) attacks." >> $LOGFILE.new
- fi
- echo -e "\n\tTop" $TOPX "Ports attacked:" >> $LOGFILE.new
- if [ -f ${LOGFILE}.tmp ];then
- sort -nr $LOGFILE".tmp" | head -n $TOPX >> $LOGFILE.new
- fi
- echo -e "\n\tTop" $TOPX "attackers:" >> $LOGFILE.new
- if [ -f ${LOGFILE}.tmp ];then
- cat $LOGFILE".tmp" | uniq -f 3 -c | sort -nr | head -n $TOPX| awk '{printf "%5d %s\n", $1, $5}' >> $LOGFILE.new
- fi
- echo -e "\n\tLast" $TOPX "most recent attackers:" >> $LOGFILE.new
- if [ -f ${LOGFILE}.tmp ];then
- tail -n $TOPX $LOGFILE".tmp" | awk '{print " "$4}' >> $LOGFILE.new # ...in chronological order last is 'most recent'
- fi
- cat $LOGFILE".new" >> $LOGFILE # Update master report with this period's attack summary
- echo -e "\n\tPorts attacked:" >> $LOGFILE
- if [ -f ${LOGFILE}.tmp ];then
- cat $LOGFILE".tmp" >> $LOGFILE # Update master report with this period's attack details
- fi
- echo -e "\n\033[0;92m"$REC_CNT "records scanned from Syslog ('"$SYSLOG"')\e[0m"
- # Show report just created ...either in FULL or just the summary.
- if [ "$VERBOSE" == "1" ];then # Just the summary report or ALL report details?
- awk -v pattern="${TIMESTAMP}" ' $0 ~ pattern { matched = 1 }; matched { print }' "$LOGFILE" # Display ALL report lines
- else
- echo -en "\e[1;31m"
- LINES=3
- if [ $GRE_CNT -gt 0 ];then
- LINES=5
- fi
- head -n $LINES $LOGFILE.new # Highlight the Summary header and GRE count if >0 in RED
- LINES=$(($LINES+1))
- echo -e "\033[00m"
- tail -q -n +$LINES $LOGFILE.new # Only display the new period's summary report
- fi
- echo -e " "
- Delete_TempFiles
- # Always sanitise the Syslog now that the report file has been created ?
- if [ "$( echo $@ | grep -o "wipe" | wc -w )" -eq 1 ];then
- echo "`sed '/Block IN=/d' $SYSLOG`" > $SYSLOG
- echo -e "\a\e[41m***Warning 'Block IN=' tracking messages now erased! ('"$SYSLOG"')\033[00m"
- logger -t "($(basename $0))" $$ "'Block IN=' tracking messages now erased! ('"$SYSLOG"')"
- echo -e " "
- fi
- exit 0
Add Comment
Please, Sign In to add comment