240 lines
7 KiB
Bash
Executable file
240 lines
7 KiB
Bash
Executable file
#!/bin/sh
|
|
#############################################################################
|
|
## Script de déconexion/reconnexion automatique pour virus de type blaster ##
|
|
## ##
|
|
## Principe : ##
|
|
## -> détection des attaques grâce aux logs du firewall ##
|
|
## lecture par *_scan.awk ##
|
|
## -> à partir du nombre d'attaques et de l'heure de dernière attaque ##
|
|
## déconnecte ou reconnecte des machines ##
|
|
## ##
|
|
## Frédéric Pauget 02/2003 ##
|
|
## 07/2004 adaptation pour scan de plusieurs types d'attaques ##
|
|
#############################################################################
|
|
|
|
is_up() {
|
|
# Supression de la machine dans la table arp
|
|
/usr/sbin/arp -d $1 2> /dev/null
|
|
|
|
# Teste si la machine founie est up
|
|
if fping -c1 $1 > /dev/null 2>&1 ; then
|
|
# Elle a répondu au ping
|
|
return 0
|
|
fi
|
|
if /usr/sbin/arp $1 2>/dev/null | egrep -q '(no entry|incomplete)' ; then
|
|
# Elle n'est pas dans la table ARP
|
|
return 1
|
|
else
|
|
# Elle est dans la table ARP
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
|
|
if [[ $1 ]] && [[ $1 = "--real-run" ]]; then
|
|
dry=false
|
|
else
|
|
dry=true
|
|
fi
|
|
|
|
BLACKLIST_FINAL='/tmp/virus_blacklist'
|
|
|
|
# Logs du firewall
|
|
FW_LOGS=/var/log/firewall/filtre.log
|
|
|
|
# Prétraitement logs
|
|
tail -7200 $FW_LOGS > /tmp/fw_logs_light
|
|
|
|
# Fonction utile : retourne l'IP d'une machine
|
|
ip() {
|
|
echo $(host $1 2>/dev/null | awk '{print $3}')
|
|
}
|
|
|
|
# Fonction principale
|
|
scan() {
|
|
# signification des arguments :
|
|
# 1 : nombre d'attaques pour être considéré infecté
|
|
# 2 : nombre de secondes sans attaques pour être considéré sain
|
|
# 3 : script de scan
|
|
# 4 : repertoire de stockage fichiers
|
|
nb_att=$1
|
|
nb_sec=$2
|
|
SCRIPT=$3
|
|
|
|
# Liste des attaques
|
|
INFECTES=$4/infectes
|
|
# Machines décontaminées
|
|
RECO=$4/reconectes
|
|
|
|
# Machines blacklistées
|
|
BLACKLIST=$4/blacklist
|
|
|
|
# Fichiers temporaires supplémentaires
|
|
DIFF=/tmp/virus_diff
|
|
TMPFILE=/tmp/virus_scan
|
|
|
|
# Doit exister, même vides
|
|
touch $RECO
|
|
touch $BLACKLIST
|
|
|
|
if ! [[ -e $INFECTES ]]; then
|
|
dry=true
|
|
echo "dry-run mode forcé (fichier absent)"
|
|
touch $INFECTES
|
|
fi
|
|
|
|
# Test préliminaire
|
|
if [[ ! -e $SCRIPT ]] ; then
|
|
echo "Erreur : $SCRIPT non trouvé"
|
|
exit 255
|
|
fi
|
|
|
|
# Conversion blacklist hostname -> IPs
|
|
if [[ "$(head -1 $BLACKLIST)" == "komaz" ]]; then
|
|
echo "Ancienne blackliste vide"
|
|
touch $BLACKLIST.ip
|
|
else
|
|
echo "Conversion blackliste..."
|
|
for i in $(cat $BLACKLIST | sort | uniq)
|
|
do
|
|
ip $i
|
|
done > $BLACKLIST.ip
|
|
fi
|
|
|
|
echo "Détection des infectés..."
|
|
$SCRIPT $BLACKLIST.ip /tmp/fw_logs_light > $TMPFILE
|
|
# sort un fichier du type :
|
|
# Mois Jour Heure hostname nb d'attaques depuis les dernier logrotate
|
|
|
|
echo "Traitement..."
|
|
mv $INFECTES $INFECTES.old
|
|
sort -r $TMPFILE > $INFECTES
|
|
echo -n "" > $TMPFILE
|
|
|
|
# Différencee entre le fichier obtenu la au dernier lancement et le nouveau
|
|
diff -U 1000 $INFECTES.old $INFECTES | egrep -v '\-\-\-|\+\+\+|@@' > $DIFF
|
|
|
|
if ! [[ -s $DIFF ]]; then
|
|
echo "Aucun changement par rapport au dernier scan."
|
|
cp $INFECTES $DIFF
|
|
fi
|
|
|
|
# Traitement par host
|
|
for host in $(awk '{print $4}' $DIFF | sort | uniq)
|
|
do
|
|
if grep -q "\+.* $host " $DIFF && grep -q "\-.* $host " $DIFF ; then
|
|
# En + et - : variation
|
|
nb=$(echo $(awk '$4=="'$host'" {print $5}' $INFECTES) - $(awk '$4=="'$host'" {print $5}' $INFECTES.old) | bc)
|
|
echo -ne "Variation ($nb) "
|
|
if grep -q "^$host$" $BLACKLIST ; then
|
|
# Déja blacklisté, on remet
|
|
echo -ne "\033[1;31m(RESTE) "
|
|
echo $host >> $TMPFILE
|
|
elif [[ $nb -gt $nb_att ]] ; then
|
|
# Nouveau
|
|
echo -ne "\033[1;31m(NOUVEAU) "
|
|
echo $host >> $TMPFILE
|
|
else
|
|
# Pas assez de tentatives
|
|
echo -n "(PASSE) "
|
|
fi
|
|
|
|
|
|
elif grep -q "\+.* $host " $DIFF ; then
|
|
# Que en + donc c'est un nouveau
|
|
nb=$(awk '$4=="'$host'" {print $5}' $INFECTES)
|
|
if [[ $nb -gt $nb_att ]] ; then
|
|
echo -ne "\033[1;31mNOUVEAU ($nb) "
|
|
echo $host >> $TMPFILE
|
|
else
|
|
echo -ne "PASSE ($nb) "
|
|
fi
|
|
|
|
elif grep -q "\-.* $host " $DIFF ; then
|
|
# Que en -, c'est un coup de logrotate, on remet les blacklistés.
|
|
if grep -q "^$host$" $BLACKLIST ; then
|
|
echo "RESTE : $host"
|
|
echo $host >> $TMPFILE
|
|
else
|
|
echo "Vieux : $host"
|
|
fi
|
|
|
|
else
|
|
# Pas de variation
|
|
if grep -q "^$host$" $BLACKLIST ; then
|
|
echo -n "Pas de variation "
|
|
# UP or not ?
|
|
if is_up $host ; then
|
|
# UP
|
|
last=$(date -d "$(awk '$4=="'$host'" {print $1" "$2" "$3}' $INFECTES)" +%s 2>/dev/null)
|
|
# Cas ou c'est vraiment trop vieux
|
|
if [[ -z $last ]] ; then
|
|
last=0
|
|
fi
|
|
now=$(date +%s)
|
|
t=$(echo "$now-$last" | bc)
|
|
if [[ $t -gt $nb_sec ]] ; then
|
|
# Reconexions automatique
|
|
echo -n " reconnexion"
|
|
echo $host >> $RECO
|
|
else
|
|
echo $host >> $TMPFILE
|
|
fi
|
|
|
|
else
|
|
# Down
|
|
echo -ne "\033[1;41m(NO_PING)"
|
|
echo $host >> $TMPFILE
|
|
fi
|
|
|
|
echo -ne "\033[0m : "
|
|
else
|
|
echo -n "Reste connecté "
|
|
fi
|
|
fi
|
|
echo -ne "\033[0m"
|
|
awk '$4=="'$host'" {print $1" "$2" "$3" "$4}' $INFECTES
|
|
done
|
|
|
|
# Opérations finales
|
|
sort $TMPFILE > $BLACKLIST
|
|
}
|
|
|
|
#######################################################################
|
|
|
|
# Scan des attaques sur le 135 :
|
|
# 10 tentatives pour être considéré infecté
|
|
# 1h sans attaque pour être considéré désinfecté
|
|
echo -e "\033[1;33m###############################\nScan attaques port 135 ou 6667\033[1;0m"
|
|
scan 10 3600 /usr/scripts/analyse_komaz/rpc_scan.awk /var/tmp/rpc
|
|
|
|
# Scan des floods :
|
|
# 100 tentatives pour être considéré infecté
|
|
# 1h sans attaque pour être considéré désinfecté
|
|
echo -e "\033[1;33m###############################\nScan floods\033[1;0m"
|
|
scan 100 3600 /usr/scripts/analyse_komaz/flood_scan.awk /var/tmp/flood
|
|
|
|
# Constitution de la blackliste finale
|
|
cat /var/tmp/rpc/blacklist /var/tmp/flood/blacklist | sort | uniq > $BLACKLIST_FINAL.new
|
|
|
|
if ! [[ -s $BLACKLIST_FINAL.new ]]; then
|
|
# Il n'y a personne, il faut au moins une machine sinon squid aime pas.
|
|
echo 'komaz' > $BLACKLIST_FINAL.new
|
|
fi
|
|
|
|
if ! $dry ; then
|
|
if diff -q $BLACKLIST_FINAL $BLACKLIST_FINAL.new ; then
|
|
echo "Pas de changement dans la blackliste"
|
|
else
|
|
# Synchro blacklist
|
|
/usr/bin/rsync -C -a -e "ssh -i /usr/scripts/analyse_komaz/keys/synchro_virus" $BLACKLIST_FINAL.new root@sila.crans.org:/etc/squid/blacklist_infectes
|
|
# Reload de squid
|
|
/usr/bin/ssh -o StrictHostKeyChecking=no -i /usr/scripts/analyse_komaz/keys/reload_squid root@sila.crans.org squid reload
|
|
fi
|
|
else
|
|
echo "Dry mode : blackliste non copiée sur sila et squid non relancé"
|
|
echo "Utiliser l'option --real-run pour tout faire."
|
|
fi
|
|
|
|
# On ne garde que la dernière version de la blacklist
|
|
mv $BLACKLIST_FINAL.new $BLACKLIST_FINAL
|