Don't MiTM me please To first understand how MiTM works I've made a few MiTM scripts, but this time I wanted to defend myself against such attacks. I'm unsure if my idea even works. The code seems to be working but I make a few assumptions and I'm not sure if those are correct.

Assumptions


When I do a traceroute the IP of the Attacker is in the route.
When I trace the route, and there is not a router device in my route it means an attacker(laptop) is listening on my connection
When I the attacker does an ARP-Spoof, the ARP-table has duplicate values.


Code issues


I have this long python -c "command" it feels a bit silly to do in bash




Any review is welcome!

Plus I would be happy if anyone has additional information on how to prevent MiTM attacks.



#!/bin/bash

route_checker() {
    private_route=$(python -c 'import re; import subprocess; from ipaddress import IPv4Address; print([ip for ip in re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", subprocess.Popen(["traceroute", "-n", "8.8.8.8"], stdout=subprocess.PIPE).communicate()[0]) if IPv4Address(bytearray(ip)).is_private])' | tr --delete []\')
    echo "Your private route = $private_route"
    echo "Checking the safety of route: $private_route"

    echo ""
    echo "Starting nmap scan"
    OLD_IFS=$IFS
    IFS=', ' read -ra IP &lt;&lt;&lt; "$private_route"
    for ip in "${IP[@]}"; do
    echo "Checking ip adress $ip:"
    os_scan=$(nmap -A -T4 "$ip")
    if [[ "$os_scan" =~ "broadband router" ]]
    then
        echo "[*] Warning! No router found."
    else
        echo "[*] Safe! A router was found."
    fi
    done
    IFS=$OLD_IFS
}

arp_checker() {
    if [[ $(arp -an | awk '{print $4}' | sort | uniq -c | grep -v ' 1 ') ]]
    then
    echo "[*] Warning! You are being spoofed"
    else
    echo "[*] Safe! Did not find any duplicate ARP values"
    fi
}

main() {
    echo "@Ludisposed"
    echo ""
    echo "Checking for ARP spoofing"
    arp_checker

    echo ""
    echo "Checking if we have a safe private route"
    route_checker
}

main
A few words about assumptions:


You're assuming that arp is installed. This is definitely not true for my system. arp as well as other "core network tools" like ifconfig have been superseded by ip. The more modern equivalents are ip neigh show and ip addr. The obsolescense is explicitly mentioned on the manpage
IIUC (because traceroute isn't available on my arch) similar considerations apply for traceroute. Also do note that you should be able to use the same idea as for the arp-check in the creation of private_route:

route = $(tracepath -n 8.8.8.8 | awk '{print $2}')
private_route = # consider ipcalc or use $route as a smaller input to python



Final considerations:

You're inconsistent in the indentation of block scopes. In arp_checker the then and else block are indented, in route_checker they are, but the for loop body is not.
I strongly recommend indenting every block to increase readability.

Aside from that: Good job of not falling into common traps like:


not double-quoting variables
not using subshells
using unsafe condition checks
missing a shebang


From what I can see, this is a well-crafted script :)