Communitytreffen-Moderator
Ich hab mal wieder ein kleines bisschen mit bash rumgespielt. Anlass war, dass ich einen kleinen Portscanner brauchte, der zwischen "Connection refused" und einem Timeout unterscheidet, weil ich ne Firewall, die verbotene Pakete einfach droppt, testen wollte (daher auch die vielen Timeouts im Screenshot). Wer ihn haben will, sei herzlich eingeladen. Für Verbesserungsvorschläge bin ich immer offen. Getestet wurde auf Mac OS X Snow Leopard, aber alle anderen Unixoiden sollten auch gehen.
Code (bash):
#!/bin/bash
display_usage( )
{
echo "usage: $(echo $0 | sed "s/^.*\///") host port_from [port_to]"
}
# Check parameters
if [ $# -eq 0 ] ; then
display_usage
exit 1
fi
# Setup variables
ADDRESS =$1
FROM =$2
TO =$3
if [ -z "$TO " ] ; then
TO =$2
fi
FINISHED =0
TEMPFILE ="/tmp/.portscan-temp-$$"
OPEN ="/tmp/.portscan-open-$$"
REFUSED ="/tmp/.portscan-refused-$$"
TIMEOUT ="/tmp/.portscan-timeout-$$"
PID =0
NUM_OPEN =0
NUM_REFUSED =0
NUM_TIMEOUT =0
# Setup screen positions
PROGRESS_X =1
PROGRESS_Y =2
PROGRESS_WIDTH =$[ $( tput cols) - ${PROGRESS_X} * 2 - 4]
CURRENT_X =3
CURRENT_Y =3
STATUS_X =3
STATUS_Y =5
OPEN_X =3
REFUSED_X =$[ ( $( tput cols) - 15) / 2]
TIMEOUT_X =$[ $( tput cols) - ${OPEN_X} * 2 - 15]
PORTS_Y =7
PORTS_HEIGHT =$[ $( tput lines) - ${PORTS_Y} - 4 ]
# Create exit handler
trap "exit_handler" EXIT
exit_handler( )
{
# Kill running nc
if [ "$PID " -gt 0 ] ; then
kill $PID 2>/ dev/ null
wait $PID 2>/ dev/ null
fi
# Remove temp file
rm $TEMPFILE
# End on last line
tput cup $[ $( tput lines) + $FINISHED - 2] 0
printf '\e[0K'
# Restore cursor
printf '\e[?25h'
# Restore foreground color
tput setaf 9
}
display_progress( )
{
# Display progress bar
tput cup ${PROGRESS_Y} ${PROGRESS_X}
tput setaf 9
echo -n "[ "
PROGRESS =$[ ( 1 + ${PORT} - ${FROM} ) * ${PROGRESS_WIDTH} / ( 1 + ${TO} - ${FROM} ) ]
for ( ( I =0 ; I < $PROGRESS ; I++) ) ; do
echo -n "-"
done
for ( ( I =$PROGRESS ; I < $PROGRESS_WIDTH ; I++) ) ; do
echo -n " "
done
echo " ]"
}
display_current( )
{
tput cup ${CURRENT_Y} ${CURRENT_X}
tput setaf 9
echo "Currently scanning port $PORT "
}
display_ports( )
{
# Display ports header
tput cup ${PORTS_Y} ${OPEN_X}
tput setaf 2
echo -n "Open: ${NUM_OPEN} "
if [ -f $OPEN ] ; then
I =2
for P in $( tail -n ${PORTS_HEIGHT} ${OPEN} ) ; do
tput cup $[ ${PORTS_Y} + I] ${OPEN_X}
echo -n $P
I =$[ $I + 1]
done
fi
tput cup ${PORTS_Y} ${REFUSED_X}
tput setaf 3
echo -n "Refused: ${NUM_REFUSED} "
if [ -f $REFUSED ] ; then
I =2
for P in $( tail -n ${PORTS_HEIGHT} ${REFUSED} ) ; do
tput cup $[ ${PORTS_Y} + I] ${REFUSED_X}
echo -n $P
I =$[ $I + 1]
done
fi
tput cup ${PORTS_Y} ${TIMEOUT_X}
tput setaf 1
echo -n "Timeout: ${NUM_TIMEOUT} "
if [ -f $TIMEOUT ] ; then
I =2
for P in $( tail -n ${PORTS_HEIGHT} ${TIMEOUT} ) ; do
tput cup $[ ${PORTS_Y} + I] ${TIMEOUT_X}
echo -n $P
I =$[ $I + 1]
done
fi
}
# Clear screen and hide cursor
tput clear
printf '\e[?25l'
echo "Scanning $ADDRESS from port $FROM to $TO "
tput cup $[ $( tput lines) - 1] 0
echo -n "Cancel with CTRL+C"
display_ports
for ( ( PORT =$FROM ; PORT < = $TO ; PORT++) ) ; do
display_progress
display_current
# Scan and display status
tput cup ${STATUS_Y} ${STATUS_X}
tput setaf 9
echo -n "Status: "
nc -zv $ADDRESS $PORT 2> $TEMPFILE > $TEMPFILE &
PID =$!
sleep 1
kill $PID 2>/ dev/ null
wait $PID 2>/ dev/ null
RESULT =$( cat $TEMPFILE )
if grep -qi succeeded $TEMPFILE ; then
tput setaf 2
printf '\e[0K'
echo "Found open port $PORT "
NUM_OPEN =$[ $NUM_OPEN + 1]
echo $PORT >> $OPEN
elif grep -qi refused $TEMPFILE ; then
tput setaf 3
printf '\e[0k'
echo "Connection refused on port $PORT "
NUM_REFUSED =$[ $NUM_REFUSED + 1]
echo $PORT >> $REFUSED
else
NUM_TIMEOUT =$[ $NUM_TIMEOUT + 1]
echo $PORT >> $TIMEOUT
fi
display_ports
done
FINISHED =1
Edit: ich seh grad, dass ich ein paar temporäre Dateien noch nicht automatisch lösch (die, in denen die Ergebnisse stehen), weil ich eigentlich konfigurierbar machen wollte, ob man die behält. Werde ich bei Gelegenheit anpassen.
Geändert von DFYX (16.02.2012 um 23:10 Uhr)