Question

I am trying to create a shell script to block all apple devices on my network. I am using nmap for os detection. What I have so far is this:

while (true) do
    nmap -O -T4 -p 22,80 -v 172.20.0.0/24 | grep -B9 'OS details: Apple' | \
        grep 'Nmap scan report for' | cut -f4 -d'r' | cut -f2 -d' ' | \
        iptables -i wlan0 -A INPUT -j DROP -s
    sleep 10
done

Is there a way to simplify this at all so there is less grepping and cutting involved? Also, this script will run into errors if there are more than one or zero apple devices found on the network. Is it possible to add logic for that?

Était-ce utile?

La solution

Yes, of course it is possible. You can use perl/awk to simplify the script a lot.

Also, I'm not sure that your script is correct at the moment. You have a pipe that write addresses to iptables, but iptables doesn't work this way.

If you want to run iptables for each address that is produced by nmap, you can read the addresses using read to some variable (in my example ADDR) and then use the variable in iptables:

while (true) do
    nmap -O -T4 -p 22,80 -v 172.20.0.0/24 | grep -B9 'OS details: Apple' | \
        grep 'Nmap scan report for' | cut -f4 -d'r' | cut -f2 -d' ' | \
        while read ADDR
        do
          iptables -i wlan0 -A INPUT -j DROP -s $ADDR
        done
    sleep 10
done

Autres conseils

A few more remarks:

  • You do not need the parenthesis around true. This starts a new subshell, which is inefficient. In this case, you probably won't care, but it's good practice to avoid needless subshells.
  • the $ADDR in Igor Chubin's answer is dangerous. If $ADDR contains a whitespace character, it will be split up into separate parameters. Someone on the network may be able to affect the output of NMap, and modify the structure of the iptables command. Even if this is not the case here, it's good practice to put the argument in between double quotes whenever possible to prevent this: "$ADDR".
  • for similar reasons, you'll usually want to use read -r instead of just read. Without the -r parameter, backslash characters in the input will escape subsequent special characters (such as spaces).
  • NMap has its own Lua scripting support. This is another way to go at this problem, which may prevent you from having to parse any text at all.
  • If you are physically on the same network, you may be able to block Apple devices without any NMap at all, by blocking devices based on the MAC address of the device. The first three bytes identify the organisation which issued the MAC address. You can look them up here. They can be faked on a rooted device, but then again, so can the NMap fingerprinting (though that would likely be harder).

An important part of scripting is understanding the programs you are using and how to get the appropriate output from them. It looks like you have a decent understanding of Nmap, since you limit the number of ports scanned (-p 22,80) and request OS detection (-O), but you could avoid a lot of text processing if you used the appropriate output format.

Nmap's "grepable" format is deprecated, meaning that it can't be used to get a lot of more-recent features' output, but it works just fine for OS detection. You request it with -oG. Here's an example, borrowing some looping help from @IgorChubin's excellent answer:

while (true) do
    nmap -O -T4 -p 22,80 -oG - 172.20.0.0/24 | awk '/OS: Apple/{print $2}' | \
        while read ADDR
        do
          iptables -i wlan0 -A INPUT -j DROP -s $ADDR
        done
    sleep 10
done

Some other improvements include moving the sleep 10 into the while condition of the outermost loop, to allow killing it with Ctrl-C during one of the sleeps. Also, be aware that DHCP leases expire, and the IP you are blocking may be assigned to a different system in the future. In general, this approach does not seem like the best way to accomplish what you want.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top