Sistemas operativos en los que se ha probado el script
CentOS 7.6 / RHEL 7.6
Requisitos
- Entorno de escritorio basado en Gnome (no probado con otros)
- Software clamd@scan instalado y debidamente configurado
- Tener bien localizado el grupo de usuarios al que aplicará el script
- Tener bien definido la carpeta dónde mandaremos el log.
- Tener bien definida la carpeta de cuarentena dónde mandaremos los posibles ficheros infectados.
- Poder trabajar con la cuenta de «root«
Creación de las udev rules
Lo primero es crear las reglas udev que van a controlar los dispositivos autorizados a conectarse en nuestra plataforma. Para ello, crearemos el fichero «99-scan-UsbStorage«, bajo el directorio «/etc/udev/rules.d/«, con el siguiente contenido:
# Sustituir el valor de las variables ATTRS{serial} por el Serial Number real de los dispositivos que queramos autorizar
# Para pinchos USB normales
DRIVERS=="usb", KERNEL=="sd[b-z]*", ATTRS{serial}=="xxxxxxxxxxxxxxxxxxx", SYMLINK+="USB01", ACTION=="add", ENV{ID_FS_LABEL}=="USB01" RUN+="/root/scripts/scan_usb.sh /dev/USB01"
DRIVERS=="usb", KERNEL=="sd[b-z]*", ATTRS{serial}=="xxxxxxxxxxxxxxxxxxx", SYMLINK+="USB02", ACTION=="add", ENV{ID_FS_LABEL}=="USB02" RUN+="/root/scripts/scan_usb.sh /dev/USB02"
DRIVERS=="usb", KERNEL=="sd[b-z]*", ATTRS{serial}=="xxxxxxxxxxxxxxxxxxx", SYMLINK+="USB03", ACTION=="add", ENV{ID_FS_LABEL}=="USB03" RUN+="/root/scripts/scan_usb.sh /dev/USB03"
DRIVERS=="usb", KERNEL=="sd[b-z]*", ATTRS{serial}=="xxxxxxxxxxxxxxxxxxx", SYMLINK+="USB04", ACTION=="add", ENV{ID_FS_LABEL}=="USB04" RUN+="/root/scripts/scan_usb.sh /dev/USB04"
DRIVERS=="usb", KERNEL=="sd[b-z]*", ATTRS{serial}=="xxxxxxxxxxxxxxxxxxx", SYMLINK+="USB05", ACTION=="add", ENV{ID_FS_LABEL}=="USB05" RUN+="/root/scripts/scan_usb.sh /dev/USB05"
# Para discos duros externos
DRIVERS=="usb|uas", KERNEL=="sd[b-z]*", ATTRS{serial}=="xxxxxxxxxxxxxxxxxxx", SYMLINK+="USB06", ACTION=="add", ENV{ID_FS_LABEL}=="USB06" RUN+="/root/scripts/scan_usb.sh /dev/HDDEXT06"
DRIVERS=="usb|uas", KERNEL=="sd[b-z]*", ATTRS{serial}=="xxxxxxxxxxxxxxxxxxx", SYMLINK+="USB07", ACTION=="add", ENV{ID_FS_LABEL}=="USB07" RUN+="/root/scripts/scan_usb.sh /dev/HDDEXT07"
# Para apagar directamente aquellos dispositivos no autorizados:
DRIVERS=="usb|uas", KERNEL=="sd[b-z]*", ATTRS{serial}!="3727065C8E3D512033910|372714450D79AC8520728|3727101723F6006925174|372701503BBF915015037|HEADER14BEE25864551|NAA78YB8|NAA78YJT", ACTION=="add", ENV{ID_FS_LABEL}!="USB01|USB02|USB03|USB04|USB05|HDDEXT06|HDDEXT07", SYMLINK+="UNSAFE", RUN+="/bin/udisksctl power-off --block-device /dev/UNSAFE"
Una vez creado el fichero, lo guardamos y recargamos las reglas udev de la siguiente forma:
# udevadm control -R
Fichero con los Serial Numbers
Necesitamos tener un fichero de texto con los mismos serial numbers autorizados en las reglas udev. Crearemos el mismo bajo el directorio «/root/scripts/ (si no existe lo creamos)«. Cada serial number deberá estar en una línea diferente, quedando algo así:
561999952995
581498984889
666998887236
MJGT58912868
POIJSW588168
LKUJMHJ88871
MNBRE6549788
Creación del script
Ahora, vamos a crear el script bajo el directorio «/root/scripts» . El script se debe llamar igual que el fichero al cual se hace referencia en las reglas udeve creadas anteriormente, por lo tanto, lo llamaremos «scan_usb.sh» y pegaremos el siguiente contenido en el mismo:
#!/bin/bash
export DISPLAY=":0.0"
DATE=$(date +%Y-%m-%d) #Date of the day
LOGFILE="/var/log/clamav/clamscan-usb.log" #Scanner log
VIRUS_FOLDER="/var/log/clamav/QUARANTINE/" #Quarantine virus folder
SERIAL_NUMBERS_FILE="/root/scripts/serial_numbers.txt" #File with permited serials numbers of USB's
DEVICE=$1 #Device to scan
FLAG="0"
AUTHORIZED_USERS_GROUP=$(getent group sysadmins | cut -d":" -f3) #Extract ID sysadmins group
SEARCH_ID=$(users | awk '{print $1}' | uniq)
USER_ID=$(id ${SEARCH_ID} | awk '{print $1}' | cut -d"=" -f 2 | cut -d"(" -f1)
CURRENT_USER=$(users | awk {'print $1'} | uniq)
if [ ! -d ${VIRUS_FOLDER} ];then
mkdir ${VIRUS_FOLDER}
fi
echo "-------------------------------------------------" >> $LOGFILE
echo $DATE >> $LOGFILE
echo "-------------------------------------------------" >> $LOGFILE
UDEVADM=$(udevadm info ${DEVICE} | grep ID_SERIAL_SHORT | cut -d"=" -f 2)
SERIAL_FILE=`cat ${SERIAL_NUMBERS_FILE}`
echo "Checking serial number ${UDEVADM}" >> $LOGFILE
for j in ${SERIAL_FILE}
do
if [ ${j} == ${UDEVADM} ]
then
FLAG=0
break
else
FLAG=1
fi
done
if [ ${FLAG} -eq 0 ]
then
echo "The serial number match" >> $LOGFILE
LABEL=$(sudo blkid ${DEVICE} -sLABEL -ovalue)
FSTYPE=$(sudo blkid ${DEVICE} -sTYPE -ovalue)
echo "The device will be scanned" >> $LOGFILE
mkdir -m 770 -p /tmp/clamavreport
mount -t ${FSTYPE} -o umask=000,gid=${AUTHORIZED_USERS_GROUP},uid=${CURRENT_USER} ${DEVICE} /tmp/clamavreport
/usr/bin/clamdscan --move=${VIRUS_FOLDER} --fdpass /tmp/clamavreport/* >> $LOGFILE 2>&1
umount /tmp/clamavreport
rm -rf /tmp/clamavreport
INFECTED=$(tail -10 $LOGFILE | grep -i "infected files" | awk '{print $3}')
if [ ${INFECTED} -ge 1 ]
then
export DISPLAY=":0.0"
USER=$(who |grep tty| awk '{print $1}')
su - $USER -c "zenity --warning --width=250 --title='ClamAV USB Malware Scanner' --text='¡¡ATENTION!! Virus detected on USB. File moved to quarantine folder' --display=${DISPLAY} &"
echo "Virus detected on USB. File moved to quarantine folder and will be notified" >> $LOGFILE
espeak "WARNING. Virus detected"
umount /run/media/${CURRENT_USER}/${LABEL}
eject -t ${DEVICE}
udisksctl power-off --block-device ${DEVICE}
echo "Unmounted dangerous USB device" >> $LOGFILE
else
export DISPLAY=":0.0"
USER=$(who |grep tty| awk '{print $1}')
su - $USER -c "zenity --info --width=250 --title='ClamAV USB Malware Scanner' --text='No virus detected on USB' --display=${DISPLAY} &"
echo "No virus detected in USB" >> $LOGFILE
if [ -d /run/media/${CURRENT_USER}/${LABEL} ];
then
rm -rf /run/media/${CURRENT_USER}/${LABEL}
mkdir -m 770 -p /run/media/${CURRENT_USER}/${LABEL}
chown -R ${CURRENT_USER}:sysadmins /run/media/${CURRENT_USER}/${LABEL}
mount -t ${FSTYPE} -o umask=000,gid=${AUTHORIZED_USERS_GROUP},uid=${CURRENT_USER} ${DEVICE} /run/media/${CURRENT_USER}/${LABEL}
else
mkdir -m 770 -p /run/media/${CURRENT_USER}/${LABEL}
chown -R ${CURRENT_USER}:sysadmins /run/media/${CURRENT_USER}/${LABEL}
mount -t ${FSTYPE} -o umask=000,gid=${AUTHORIZED_USERS_GROUP},uid=${CURRENT_USER} ${DEVICE} /run/media/${CURRENT_USER}/${LABEL}
fi
echo "USB mounted in path /run/media/${CURRENT_USER}/${LABEL}" >> $LOGFILE
chmod -R 770 /run/media/${CURRENT_USER}/${LABEL}
fi
else
echo "The serial number don't match" >> $LOGFILE
eject -t ${DEVICE}
export DISPLAY=":0.0"
USER=$(who |grep tty| awk '{print $1}')
su - $USER -c "zenity --error --width=250 --title='ClamAV USB Malware Scanner' --text='This USB is not authorized to use in this platform. Please unplug the USB' --display=${DISPLAY} &"
echo "USB isn't mounted. Please unplug the usb" >> $LOGFILE
udisksctl power-off --block-device ${DEVICE}
fi
exit 0
Cómo podemos visualizar en el script, existe una variable que hace referencia a un grupo de usuarios ( AUTHORIZED_USERS_GROUP ). Este grupo debe existir, no tiene porque llamarse «sysadmins», pero los usuarios normales deben pertener a este grupo para que se les aplique las restricción de USB’s,.
Es decir, si tenemos el grupo «tecnicos» y los usuarios «pepe» y «juan«, ambos deben tener cómo grupo secundario a «tecnicos» y en nuestro script deberemos cambiar la búsqueda que se realiza en la variable «AUTHORIZED_USERS_GROUP » , quedando algo así:
AUTHORIZED_USERS_GROUP=$(getent group tecnicos | cut -d":" -f3)
Espero que os sea de utilidad Sysadmins!! 🙂