PoisonTap solution
PoisonTap is a Raspberry Pi based device that siphons cookies, exposes internal router & installs web backdoor on locked computers. It works by posing as a USB network adapter that sets itself up as an IP gateway via DHCP. This article provides instructions to set up a simple protection for this attack vector by disabling networking when the screen is locked. It works for GNU/Linux but should be easy to implement in other operating systems.
The method
It's done by having a simple script like the one below run on the screensaver events.
#!/usr/bin/perl
while(<>) {
`nmcli nm enable false` if /true/;
`nmcli nm enable true` if /false/;
}
A line is then added to /etc/rc.local so that triggers in response to changes in the screensaver status that call your script are set up at boot time using the dbus-monitor command as follows:
dbus-monitor --session "type=signal,interface=org.cinnamon.ScreenSaver,member=ActiveChanged" | /path/to/your/script.pl
But note that the details are subtly different depending on the distro, so following is more detail about how it works and how to make your own script that matches your system.
Rolling your own
First you need to find out the best way to turn the network on and off. On most distros these days the network is controlled by the Network Manager and you can turn it on and off with:
nmcli nm enable [true|false]
Some other possible options are:
service [start|stop] networking
/etc/init.d/networking [start|stop]
if[up|down] -a
You need something that disables it and prevents a new device that's plugged in from functioning, but when re-enabled all devices are seen to be functioning normally again.
Once you've found your networking starting and stopping commands, next you need to find the event that your desktop uses to broadcast changes of the screen-locking status. All modern distros use the DBus system so you can use the following command to observe all events and then lock and unlock the screen and check the output to see which events it used.
Here's the command to observe all the DBus signals being emitted by the system:
dbus-monitor --session "type=signal"
On my system this a snippet of what was outputted (it was actually about 4 times as much as this), I've highlighted the relevant lines:
signal sender=:1.1 -> dest=(null destination) serial=198 path=/org/gnome/SessionManager/Presence;
interface=org.gnome.SessionManager.Presence; member=StatusChanged
uint32 3
signal sender=:1.19 -> dest=(null destination) serial=3245 path=/org/Cinnamon/LookingGlass;
interface=org.Cinnamon.LookingGlass; member=WindowListUpdate
:signal sender=:1.37 -> dest=(null destination) serial=40 path=/org/cinnamon/ScreenSaver;
interface=org.cinnamon.ScreenSaver; member=ActiveChanged
boolean true
signal sender=org.freedesktop.DBus -> dest=(null destination) serial=86 path=/org/freedesktop/DBus;
interface=org.freedesktop.DBus; member=NameOwnerChanged
string "org.freedesktop.ReserveDevice1.Audio0"
string ""
string ":1.10"
:signal sender=:1.37 -> dest=(null destination) serial=41 path=/org/cinnamon/ScreenSaver;
interface=org.cinnamon.ScreenSaver; member=ActiveChanged
boolean false
signal sender=:1.1 -> dest=(null destination) serial=202 path=/org/gnome/SessionManager/Presence
interface=org.gnome.SessionManager.Presence; member=StatusChanged
This shows that the event used on my machine for screensaver status changes has interface=org.cinnamon.ScreenSaver and member=ActiveChanged and that the value is boolean true or boolean false depending on whether the screensaver is starting or stopping. We cn use this to construct a more specific observation command that only outputs screensaver state changes like this:
dbus-monitor --session "type=signal,interface=org.cinnamon.ScreenSaver,member=ActiveChanged"
We then need to make a small script that enables or disables the networking using the command you found above depending on whether the DBus output says the screensaver is starting or stopping. I found Perl simplest for this job, because my shell scripting skills are pretty lame. In my case the start/stop depends on the value being boolean true or boolean false so I've used the simple regular expressions highlighted in the script below.
#!/usr/bin/perl
while( <> ) {
`nmcli nm enable false` if /true/;
`nmcli nm enable true` if /false/;
}
Save your script, in my case I've called it /var/www/tools/nopoisontap.pl and ensure that it has executable permissions for example with chmod 755.
And then finally you need to run the whole command that sends the DBus output to your new script. The trailing ampersand runs it in the background.
dbus-monitor --session "type=signal,interface=org.cinnamon.ScreenSaver,member=ActiveChanged" | /var/www/tools/nopoisontap.pl &
Once you've established that it's all working properly, you can run the command from your /etc/rc.local file so it starts at boot time.