Protección de la unidad flash USB en linux

6

Tenemos un sistema industrial (que se ejecuta en Linux) con un puerto USB. Tenemos el puerto USB solo para copiar ciertos datos. Aparte de esto, no queremos que la unidad USB contenga ningún otro ejecutable o scripts.etc. Los usuarios finales pueden copiar un gusano / virus en un dispositivo USB y adjuntarlo al sistema. ¿Cuáles son las formas de evitar esto? Soy consciente de que si está montado con la opción noexec, el usuario no puede ejecutar los archivos. ¿Cuáles son las diferentes formas de mejorar la seguridad de los dispositivos USB? Actualizar : el sistema se ejecuta sin una GUI como KDE / GNOME.

    
pregunta m4n07 02.04.2013 - 07:31
fuente

2 respuestas

7

Comenzaría con el bloqueo del BIOS para que el dispositivo no pueda usarse para iniciar el sistema.

Luego, deshabilitaría el montaje automático para dispositivos USB. En este punto, debe limitar la interacción del usuario con el "subsistema" de la unidad USB. Por ejemplo, esta copia de datos generalmente se requiere para volcar registros o datos adquiridos, por lo tanto, puede reducirlos (en la mayoría de los casos) para:

  • monta el dispositivo USB
  • verifica que sea válido y que tenga suficiente espacio
  • seleccione los datos que desea copiar entre una selección de posibles archivos   (por ejemplo, datalog.001, 20130402-dump.csv, cualquier cosa en / var / local / data ...)
  • copiar dichos archivos
  • (opcionalmente) releer y verificar sus hashes MD5 / SHA
  • (opcionalmente) elimine / gire los originales para liberar espacio en el dispositivo
  • desmontar el dispositivo USB

El proceso solo permite la interacción en los "datos seleccionados", y esa interacción está limitada a una opción de casilla de verificación múltiple. Existen utilidades (zenity, kdialog o dialog for curses systems) que le permiten crear una interfaz "bloqueada" en muy poco tiempo: este es un ejemplo adaptado

#!/bin/bash
n=0
for file in $(ls /tmp); do
    n=$[n+1]
    echo "$file $n off" >> /tmp/output.txt
done
dialog --checklist "Items to copy:" 20 60 20 \
    $(cat /tmp/output.txt) 2>/tmp/output2.txt

for i in $(cat /tmp/output2.txt); do
    cp $i /mnt/usbkey/
done
rm /tmp/output*

Ahora, el usuario solo puede conectar una llave USB de manera útil cuando el sistema ya se ha iniciado, y cuando lo hace, no sucede nada; cuando elige la función "Volcado de datos", sus opciones son limitadas.

No debería necesitarlo, pero tenga en cuenta las posibles vulnerabilidades a través de metacaracteres de shell incrustados en los nombres de archivos. Siempre obtenga los nombres de los archivos con ls (o equivalente) y filtrelos.

Nota : como lo notó Gilles, el ejemplo anterior es defectuoso: dialog , solo admitirá nombres sin espacios. Para una implementación más robusta, deberías usar algo más que un script bash, posiblemente Python con Urwid o, dependiendo de la interfaz existente, un CGI o módulo web.

Actualizar

Lo mejor que se puede hacer en bash y con dialog es, por desgracia, eliminar los archivos problemáticos (aquellos con $, espacio, comilla simple, doble citas...). Un guión mejor, si falta, es este. ignora cualquier archivo que no se adhiera a su convención de nomenclatura; todavía puede ser útil para alguien (por ejemplo, para copiar registros. A menos que ahora esté cerrando data-九月.log ).

#!/bin/bash

DIRTOCOPY="/tmp"

clean() {
        rm -f .tmp.dir .tmp.out .tmp.cpy
}

clean

n=0

ls "$DIRTOCOPY" > .tmp.dir

while read file ; do
    if ( echo "$file" | grep "^[A-Za-z0-9._~^-]*\$" > /dev/null ); then
        n=$[n+1]
        echo "$file $n off" >> .tmp.out
    fi
done < .tmp.dir
rm -f .tmp.dir

dialog --checklist "Items to copy:" 20 60 20 \
    $(cat .tmp.out) 2>.tmp.cpy

cat .tmp.cpy
exit

for file in $( cat .tmp.cpy ); do
    echo cp "$file" /mnt/usbkey/
done

clean

Python

Para hacerlo mejor, tenemos que emplear un costructo menos frágil. Como se sugirió anteriormente, esto se puede hacer en Python usando la biblioteca urwid ( apt-get install python-urwid en Ubuntu, me han dicho. De lo contrario, la instalación es sencilla). Esto es poco más que un tutorial modificado que preparé, pero funciona incluso con archivos que ahogan dialog o se copian incorrectamente:

/tmp/tests/file with spaces.txt
/tmp/tests/file "quoted, but only once.txt
/tmp/tests/file "quoted twice", that's right!.txt
/tmp/tests/ceci n'est pas une |.txt

Lo único es que los archivos UTF8 pueden tener sus nombres destrozados: tengo un archivo que se llama "Chissà?" en Linux EXT3, y mientras permanece intacto cuando se copia a Linux o NTFS, se convierte en "Chiss ????" (sí, cuatro signos de interrogación) en una llave USB FAT. Pero creo que esto es una limitación del sistema de archivos, no del script.

#!/usr/bin/python

import urwid
from os import listdir
from os.path import isfile, join
from shutil import copyfile

directory = '/tmp'
destination = '/mnt/usbkey'

choices = [ file for file in listdir(directory) if isfile(join(directory,file)) ]

tocopy = [ ]

def menu(title, choices):
    body = [urwid.Text(title), urwid.Divider()]
    for c in choices:
        box     = urwid.CheckBox(c, False, False, toggle, c)
        body.append(urwid.AttrMap(box, None, focus_map='reversed'))

    ende = urwid.Button('-- COPY --')
    urwid.connect_signal(ende, 'click', item_chosen)
    body.append(urwid.AttrMap(ende, None, focus_map='reversed'))

    return urwid.ListBox(urwid.SimpleFocusListWalker(body))

def toggle(button, state, file):
    if state:
        tocopy.append(file)
    else:
        tocopy.remove(file)

def item_chosen(button):
    response = urwid.Text([u'Proceed with copy?\n'])
    done = urwid.Button(u'Proceed')
    fine = urwid.Button(u'Cancel')
    urwid.connect_signal(done, 'click', copy_files)
    urwid.connect_signal(fine, 'click', exit_program)
    main.original_widget = urwid.Filler(urwid.Pile([response,
        urwid.AttrMap(done, None, focus_map='reversed'),
        urwid.AttrMap(fine, None, focus_map='reversed') ]))

def exit_program(button):
    raise urwid.ExitMainLoop()

def copy_files(button):
    for file in tocopy:
        src = join(directory, file)
        dst = join(destination, file)
        copyfile(src, dst)
    raise urwid.ExitMainLoop()

main = urwid.Padding(menu(u'File to be copied to USB', choices), left=2, right=2)
top = urwid.Overlay(main, urwid.SolidFill(u'\N{MEDIUM SHADE}'),
    align='center', width=('relative', 60),
    valign='middle', height=('relative', 60),
    min_width=20, min_height=9)
urwid.MainLoop(top, palette=[('reversed', 'standout', '')]).run()
    
respondido por el LSerni 02.04.2013 - 14:32
fuente
3

El riesgo de un puerto USB abierto es mucho más de lo que anticipó. Lo que recomendaré es proteger el BIOS de su servidor en el que se ejecutan sus servicios industriales. Al proteger con contraseña su BIOS, puede restringir que usuarios no autorizados arranquen desde dispositivos USB y obtengan acceso no autorizado a los recursos de su servidor. Además, puede instalar antivirus como ClamAV para escanear dispositivos USB en busca de malware.

    
respondido por el Ali Ahmad 02.04.2013 - 08:43
fuente

Lea otras preguntas en las etiquetas