Browse Source

tcp-investiogation.sh config

netico 2 years ago
parent
commit
eea60320c7
1 changed files with 217 additions and 0 deletions
  1. 217 0
      Network/Investigation/tcp-investigation.sh

+ 217 - 0
Network/Investigation/tcp-investigation.sh

@@ -0,0 +1,217 @@
+#!/bin/bash
+
+: '
+Author: netico <netico@riseup.net>
+
+Thu 13 Jan 2022 05:43:29 PM CET
+Mon 17 Jan 2022 11:33:08 AM CET
+Fri 11 Feb 2022 10:26:56 AM CET
+
+TCP investigation script
+'
+
+# CONFIGURATION
+# Sender
+SENDER="someone@domain.tld"
+# Recipient
+RECIPIENT="someone.else@domain.tld"
+# Mail relay URL
+RELAY="smtp://powerful.mail.server:587"
+
+
+# ERRORS HANDLING
+E=false
+if [[ $EUID -ne 0 ]]
+then
+    E=true
+    ERROR="This script must be run as root!"
+fi
+
+# FUNCTIONS
+# See https://stackoverflow.com/questions/19059944/convert-kb-to-mb-using-bash
+hprint() {
+    local -i bytes=$1;
+    if [[ $bytes -lt 1024 ]]
+    then
+        echo "${bytes}B"
+    elif [[ $bytes -lt 1048576 ]]
+    then
+        echo "$(( (bytes + 1023)/1024 ))kB"
+    else
+        echo "$(( (bytes + 1048575)/1048576 ))MB"
+    fi
+}
+pidinfo() {
+    local PID="$1"
+    local STAT=$(pidstat -p $PID -d | tail -1)
+    local READ=$(echo $STAT | awk '{print $5}')
+    local WRITE=$(echo $STAT | awk '{print $6}')
+    local DELETE=$(echo $STAT | awk '{print $7}')
+    local IODELAY=$(echo $STAT | awk '{print $8}')
+
+    echo "<h5>IO</h5>"
+    echo "<table>"
+    echo "<tr>"
+    echo "<th>READ/S</th><th>WRITE/S</th><th>DEL/S</th><th>IO DELAY</th>"
+    echo "</tr>"
+    echo "<tr>"
+    echo "<td>${READ}kB</td><td>${WRITE}kB</td><td>${DELETE}KB</td><td>$IODELAY</td>"
+    echo "</tr>"
+    echo "</table>"
+
+    echo "<h5>FILES</h5>"
+    echo "<table>"
+    echo "<tr>"
+    echo "<th>TYPE</th><th>SIZE</th><th>NAME</th>"
+    echo "</tr>"
+
+    while read -r FIELD; do
+        case ${FIELD::1} in
+          s)
+            local SIZE=$(echo -n ${FIELD:1})
+            ;;
+          t)
+            local TYPE=$(echo -n ${FIELD:1})
+            ;;
+          n)
+            local NAME=$(echo -n ${FIELD:1})
+            ;;
+        esac
+        if [ -e "$NAME" ] && [ -n "$TYPE" ] && [ "$SIZE" -gt 0 ]
+        then    
+            echo "<tr><td>$TYPE</td><td>" $(hprint $SIZE) "</td><td>$NAME</td></tr>"
+            SIZE=0
+            TYPE=""
+            NAME=""
+        fi
+
+    done < <(lsof -p $PID -w -F pstn)
+    echo "</table>"    
+}
+
+# MAIN
+# IP address
+# IP="192.168.0.100"
+IP=$(hostname -I | awk {'print $1'})
+# HTML report
+HTML="/tmp/report.html.$RANDOM"
+echo "<!DOCTYPE html>" > $HTML
+echo "<html>" >> $HTML
+echo "<head>" >> $HTML
+echo "<meta charset='UTF-8'>" >> $HTML
+echo "<title>TCP investigation</title>" >> $HTML
+echo "<style>" >> $HTML
+echo "body {margin: 0pt; padding: 10pt;}" >> $HTML
+echo "div, p {width: 100%; padding: 0pt; color: MidnightBlue; font-size: 11pt;}" >> $HTML
+echo "table {width: 100%; font-size: 10pt; color: DarkSlateGrey; border: 1pt solid LightGrey; margin: 0pt 0pt 10pt 0pt; padding: 1.2pt; border-radius: 5pt;}" >> $HTML
+echo "th, td {text-align: left; padding: 1.2pt}" >> $HTML
+echo "a {text-decoration: none;}" >> $HTML
+echo "h1, h2, h3, h4, h5 {text-align: left; margin: 0pt 0pt 10pt 0pt; padding: 0pt;}" >> $HTML
+echo "</style>" >> $HTML
+echo "</head>" >> $HTML
+echo "<body>" >> $HTML
+echo "<h1>TCP investigation</h1>" >> $HTML
+echo "<p><b>IP</b>: $IP</p>" >> $HTML
+echo "<p><b>Date</b>: "$(date)"</p>" >> $HTML
+# Are there any active connections?
+ITEMS=$(netstat -pant 2>/dev/null | grep "$IP" | grep ESTABLISHED | wc -l)
+if [[ $ITEMS -eq 0 ]]
+then
+    E=true
+    ERROR="There are no active connections"
+fi
+# Is everything okay?
+if [ "$E" = true ]
+then
+    echo "<p><b>Error</b>: $ERROR</p>" >> $HTML
+else
+    # Active connections
+    declare -a P
+    declare -a C
+    I=0
+    echo "<h3 id='connections'>ACTIVE TCP CONNECTIONS</h3>"$'\n' >> $HTML
+    echo "<table>" >> $HTML
+    echo "<tr>" >> $HTML
+    echo "<th>PID</th><th>REMOTE IP</th><th>REMOTE PORT</th><th>USER</th><th>GROUP</th><th>COMMAND</th>" >> $HTML
+    echo "</tr>" >> $HTML
+    while read -r CONNECTION; do
+        if [[ $CONNECTION ]]
+        then
+            PID=$(echo $CONNECTION | awk '{print $7}' | cut -d/ -f1)
+            if [[ "$PID" =~ ^[0-9]+$ ]]
+	        then	        
+  	            USER=$(ps -p $PID -o user,group=GROUP | tail -1 | awk '{print $1}')
+  	            GROUP=$(ps -p $PID -o user,group=GROUP | tail -1 | awk '{print $2}')    
+  	            COMMAND=$(ps -p $PID -o args=COMMAND | tail -1)
+	            REMOTE=$(echo $CONNECTION | awk '{print $5}' | cut -d: -f1)
+	            PORT=$(echo $CONNECTION | awk '{print $5}' | cut -d: -f2)
+		        C[$I]="$PID|$REMOTE|$PORT|$USER|$GROUP|$COMMAND"
+		        P[$I]=$PID
+		        I=$(expr $I + 1)
+	        fi
+        fi
+    done < <(netstat -pant 2>/dev/null | grep $IP | grep ESTABLISHED)
+    readarray -t C < <(printf '%s\n' "${C[@]}" | sort -n | uniq)
+    for L in "${C[@]}"
+    do
+        echo "<tr>" >> $HTML
+        LPID=$(echo $L | cut -d'|' -f1)
+        REMOTE=$(echo $L | cut -d'|' -f2)
+        PORT=$(echo $L | cut -d'|' -f3)
+        USER=$(echo $L | cut -d'|' -f4)
+        GROUP=$(echo $L | cut -d'|' -f5)
+        COMMAND=$(echo $L | cut -d'|' -f6)
+        echo "<td><a href='#pid-"$LPID"'>$LPID</a></td><td>$REMOTE</td><td>$PORT</td><td>$USER</td><td>$GROUP</td><td>$COMMAND</td>" >> $HTML
+        echo "</tr>" >> $HTML
+    done
+    echo "</table>" >> $HTML
+
+    echo "<h3>PROCESSES INVOLVED</h3>" >> $HTML
+    readarray -t P < <(printf '%s\n' "${P[@]}" | sort -n | uniq)
+    for PID in "${P[@]}"
+    do
+        echo "<h4 id='pid-"$PID"'><a href='#connections'>&uarr;</a> PROCESS ID $PID</h4>" >> $HTML
+        pidinfo $PID  >> $HTML
+    done
+fi
+echo '</body>' >> $HTML
+echo '</html>' >> $HTML
+
+# REPORT
+# Internet Message Format
+MSG="/tmp/report.eml.$RANDOM"
+# Message headers
+FROM="From: \"TCP investigation\" <$SENDER>"
+TO="To: \"Report\" <$RECIPIENT>"
+SUBJECT="Subject: TCP investigation"
+MIME="MIME-Version: 1.0"
+TYPE="Content-Type: text/html; charset=UTF-8"
+DATE="Date: $(date -R)"
+ENCODING="Content-Transfer-Encoding: base64"
+DISPOSITION="Content-Disposition: inline"
+# Message-ID ?
+# https://en.wikipedia.org/wiki/Message-ID
+# https://www.jwz.org/doc/mid.html
+# https://datatracker.ietf.org/doc/html/rfc2392
+echo $FROM > $MSG
+echo $TO >> $MSG
+echo $SUBJECT >> $MSG
+echo $DATE >> $MSG
+echo $MIME >> $MSG
+echo $TYPE >> $MSG
+echo $ENCODING >> $MSG
+echo $DISPOSITION >> $MSG
+echo >> $MSG
+# Encode HTML
+echo $(base64 <<< "$(cat $HTML)") >> $MSG
+# https://serverfault.com/questions/1036588/error-message-on-emailing-998-octets
+sed -i -E 's/.{998}/&\n/g' $MSG
+# https://cr.yp.to/docs/smtplf.html
+unix2dos -q $MSG
+
+# Sending e-mail
+curl -s -n --ssl-reqd $RELAY --mail-from $SENDER --mail-rcpt $RECIPIENT --upload-file $MSG
+
+# Cleaning
+rm -f "$MSG"
+rm -f "$HTML"