Created
March 7, 2017 15:53
-
-
Save JayGoldberg/dc2c525f9244cd886f7310cc7cfb29a0 to your computer and use it in GitHub Desktop.
Auto-discovering port scanner in bash
This file contains 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 | |
## @author Jay Goldberg | |
## @email jaymgoldberg@gmail.com | |
## @license Apache 2.0 | |
## @description scans above/below given port | |
## @usage smartportscan.sh <text file with "<host> <port>" lines | |
#======================================================================= | |
#TODO(JSON output mode using jq) | |
#TODO(option to insert into SQLite) | |
#TODO(check if port exists in SQLite before scanning it) | |
#TODO(accept from stdin or file, autodetect) | |
#TODO(ability to parse CSV in addition to SSV | |
#if [[ $# -ge 1 && -f "$1" ]] && input="$1" || input="/dev/stdin" | |
#fi | |
# which ports to scan in addition to whats in the input file | |
otherports="80 8080 50000 1024" | |
# how many seconds to wait for a TCP connect | |
timeout=2 | |
# how many ports the scanner will climb up/down to detect failure | |
# before it assumes there are no more live ports coming up | |
maxsequentialfailures=3 | |
portcheck () { | |
local port="$1" | |
# first conditional checks for integer, second for range | |
if [ $port -eq $port ] 2>/dev/null || [ $port -le 0 -o $port -ge 65535 ]; then | |
#TODO(consolidate test using -o flag or (if [[ expression && expression || expression ]] ; then)) | |
echo "$port is not a valid port number" | |
exit 1 | |
fi | |
} | |
portconnect () { | |
local host="$1" | |
local port="$2" | |
timeout ${timeout} bash -c "cat < /dev/null > /dev/tcp/${host}/${port}" 2>/dev/null | |
if [ $? -ne 0 ]; then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
scan () { | |
local failed=0 | |
local host=$2 | |
local port=$3 | |
case "$1" in | |
up) | |
# scan upward from the specified port | |
op=1 | |
;; | |
down) | |
# scan downward from the specified port | |
op=-1 | |
port=$((port+op)) # we should have already scanned this in | |
# main()'s call to up() but this is an assumption, we should | |
# prob do up/down inside this fn | |
;; | |
esac | |
while [ $failed -lt $maxsequentialfailures ]; do | |
portconnect $host $port | |
if [ $? -ne 0 ]; then | |
echo $host:$port success | |
port=$(( port + op )) | |
else | |
echo $host:$port failure | |
(( failed++ )) | |
port=$(( port + op )) | |
fi | |
done | |
} | |
while read host port; do | |
#parsehostport #TODO(detect and handle a URL as well) | |
scan up $host $port | |
scan down $host $port | |
# check | |
if [[ $otherports ]]; then | |
for otherport in $otherports; do | |
scan up $host $otherport | |
scan down $host $otherport | |
done | |
fi | |
done < "$1" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment