Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

We have a industrial system(running on linux) with a USB port. We have the USB port only for copying certain data. Other than this we don't want the USB drive to contain any other executables or scripts.etc. As end users may copy a worm/virus on to a USB device and attach to the system. What are the ways to avoid this ? I'm aware that if its mounted with noexec option the user cannot execute the files. What are the different ways to enhance the security of the USB devices? Update: The system runs without a GUI like KDE/GNOME.

share|improve this question
1  
From the question on the other SE site, don't forget that you also need to physically secure this system to protect the data/software. –  Cry Havok Apr 2 '13 at 6:29
    
Sure,the system is physically secure. –  m4n07 Apr 2 '13 at 6:32
add comment

2 Answers

I'd start with locking down BIOS so that the device can't be used to boot the system.

Then, I would disable automounting for USB devices. At this point, you need to limit user's interaction with the USB drive "subsystem". For example, this copying of data is usually required to dump logs or acquired data, therefore you can boil it down (in most cases) to:

  • mount the USB device
  • verify it is valid and has enough space
  • select the data you want copied among a choice of possible files (e.g. datalog.001, 20130402-dump.csv, anything in /var/local/data...)
  • copy said files
  • (optionally) re-read and check their MD5/SHA hashes
  • (optionally) delete/rotate the originals to free space on device
  • unmount the USB device

The process only allows interaction in the "select data", and that interaction is limited to a multiple checkbox choice. There are utilities (zenity, kdialog, or dialog for curses systems) that allow you to build a "locked down" interface in next to no time: this is an adapted example

#!/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*

Now, the user can only usefully plug a USB key when the system is already booted, and when he does, nothing happens; when he chooses the "Data Dump" function, his choices are limited.

You shouldn't need it, but be aware of possible exploits through shell metacharacters embedded in file names. Always get the file names with ls (or equivalent) and filter them.

Note: as noticed by Gilles, the above example is flawed: dialog there will only support names without spaces. For a more robust implementation, you ought to use something else than a bash script, possibly Python with Urwid or, depending on the existing interface, a CGI or web module.

Update

The best that can be done in bash and with dialog is, unfortunately, to remove the problematic files (those with $, space, single quote, double quotes...). A better, if lacking, script is this. It ignores any file not adhering to its naming convention; it may still be useful to someone (e.g. to copy logs. Unless you're now closing 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

To do better, we have to employ a less fragile costruct. As suggested above, this can be done in Python using the urwid library (apt-get install python-urwid on Ubuntu, I'm told. Otherwise, installation is straightforward). This is little more than a modified tutorial I whipped up - yet it works even with files that either choke dialog or are copied incorrectly:

/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

The only thing is that UTF8 files may have their names mangled: I have a file that's named "Chissà?" in Linux EXT3, and while it remains intact when copied to Linux or NTFS, it became "Chiss????" (yes, four question marks) on a FAT USB key. But I believe this is a limitation of the filesystem, not the 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()
share|improve this answer
add comment

The risk of an open USB port is far more then you have anticipated. What i will recommend is to BIOS protect your server on which your Industrial services are running. By Password protecting your BIOS you can restrict unauthorized user to boot from USB devices and gain unauthorized access to your server resources. You can further install antivirus such as ClamAV to scan USB devices for malware.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.