Script para permitir solo USB’s autorizados

por | noviembre 18, 2019

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!! 🙂

About: Miguel Carretas Perulero

Miguel Carretas Perulero ha escrito 72 artículos en este blog.

Deja un comentario