USB Firewall

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

USB Firewall

Charlie Eddy
Hello,

Is there a method to detect and halt additional USB devices being added
after initializing connections? Concerned about widespread vulnerability of
keystroke injection.
Reply | Threaded
Open this post in threaded view
|

Re: USB Firewall

Stephane HUC "PengouinBSD"
Perhaps, using hotplugd and file /etc/hotplug/attach?

Le 01/16/18 à 18:39, Charlie Eddy a écrit :
> Hello,
>
> Is there a method to detect and halt additional USB devices being added
> after initializing connections? Concerned about widespread vulnerability of
> keystroke injection.
>

--
~ " Fully Basic System Distinguish Life! " ~ " Libre as a BSD " +=<<<
----
<me>Stephane HUC as PengouinBSD or CIOTBSD</me>
<mail>[hidden email]</mail>

Reply | Threaded
Open this post in threaded view
|

Re: USB Firewall

Jiri B-2
On Tue, Jan 16, 2018 at 07:03:58PM +0100, Stephane HUC "PengouinBSD" wrote:
> Perhaps, using hotplugd and file /etc/hotplug/attach?
>
> Le 01/16/18 à 18:39, Charlie Eddy a écrit :
> > Hello,
> >
> > Is there a method to detect and halt additional USB devices being added
> > after initializing connections? Concerned about widespread vulnerability of
> > keystroke injection.

There's no such way. Maybe something like this https://usbguard.github.io/
but that's for Linux only.

There can be hw attacks over DisplayPort too. Some Linux people were
discussing a possibility to disallow adding new DisplayPort based
devices after boot to prevent physical attack on fully booted (physically
unprotected) computer.

Jiri


Reply | Threaded
Open this post in threaded view
|

Re: USB Firewall

Gabriel Kihlman
In reply to this post by Charlie Eddy
Charlie Eddy <[hidden email]> writes:
>
> Is there a method to detect and halt additional USB devices being added
> after initializing connections? Concerned about widespread vulnerability of
> keystroke injection.

I do not remember who posted it (should be in the archives), but this
diff adds a knob for allowing usb bus probing or not. When I tried it,
it did stop new usb devices from attaching on my laptop.

Index: sys/dev/usb/uhub.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uhub.c,v
retrieving revision 1.89
diff -u -p -u -r1.89 uhub.c
--- sys/dev/usb/uhub.c 2 Sep 2016 09:14:59 -0000 1.89
+++ sys/dev/usb/uhub.c 1 Jan 2017 22:52:53 -0000
@@ -55,6 +55,9 @@
 
 #define DEVNAME(sc) ((sc)->sc_dev.dv_xname)
 
+/* controls enabling/disabling of USB bus probing */
+int busprobe = 1;
+
 struct uhub_softc {
  struct device sc_dev; /* base device */
  struct usbd_device *sc_hub; /* USB device */
@@ -439,6 +442,9 @@ uhub_explore(struct usbd_device *dev)
  usbd_clear_port_feature(sc->sc_hub, port,
     UHF_C_PORT_LINK_STATE);
  }
+
+ if (!busprobe)
+ return (0);
 
  /* Recursive explore. */
  if (up->device != NULL && up->device->hub != NULL)
Index: sys/dev/usb/usb.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb.c,v
retrieving revision 1.111
diff -u -p -u -r1.111 usb.c
--- sys/dev/usb/usb.c 18 May 2016 18:28:58 -0000 1.111
+++ sys/dev/usb/usb.c 1 Jan 2017 22:52:53 -0000
@@ -87,6 +87,8 @@ int usb_noexplore = 0;
 #define DPRINTFN(n,x)
 #endif
 
+extern int busprobe;
+
 struct usb_softc {
  struct device sc_dev; /* base device */
  struct usbd_bus  *sc_bus; /* USB controller */
@@ -607,6 +609,14 @@ usbioctl(dev_t devt, u_long cmd, caddr_t
 #endif
  break;
 #endif /* USB_DEBUG */
+ case USB_GET_BUS_PROBE:
+ *(unsigned int *)data = busprobe;
+ break;
+ case USB_SET_BUS_PROBE:
+ if ((error = suser(curproc, 0)) != 0)
+ return (error);
+ busprobe = !!*(unsigned int *)data;
+ break;
  case USB_REQUEST:
  {
  struct usb_ctl_request *ur = (void *)data;
Index: sys/dev/usb/usb.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb.h,v
retrieving revision 1.57
diff -u -p -u -r1.57 usb.h
--- sys/dev/usb/usb.h 19 Jun 2016 22:13:07 -0000 1.57
+++ sys/dev/usb/usb.h 1 Jan 2017 22:52:53 -0000
@@ -760,6 +760,8 @@ struct usb_device_stats {
 #define USB_DEVICE_GET_CDESC _IOWR('U', 6, struct usb_device_cdesc)
 #define USB_DEVICE_GET_FDESC _IOWR('U', 7, struct usb_device_fdesc)
 #define USB_DEVICE_GET_DDESC _IOWR('U', 8, struct usb_device_ddesc)
+#define USB_GET_BUS_PROBE _IOR ('U', 9,  unsigned int)
+#define USB_SET_BUS_PROBE _IOW ('U', 10, unsigned int)
 
 /* Generic HID device */
 #define USB_GET_REPORT_DESC _IOR ('U', 21, struct usb_ctl_report_desc)
Index: usr.sbin/usbdevs/usbdevs.8
===================================================================
RCS file: /cvs/src/usr.sbin/usbdevs/usbdevs.8,v
retrieving revision 1.9
diff -u -p -u -r1.9 usbdevs.8
--- usr.sbin/usbdevs/usbdevs.8 26 Jun 2008 05:42:21 -0000 1.9
+++ usr.sbin/usbdevs/usbdevs.8 1 Jan 2017 22:52:53 -0000
@@ -39,6 +39,7 @@
 .Op Fl dv
 .Op Fl a Ar addr
 .Op Fl f Ar dev
+.Op Fl p Ns Op Ar on | off
 .Sh DESCRIPTION
 .Nm
 prints a listing of all USB devices connected to the system
@@ -53,6 +54,10 @@ Only print information about the device
 Show the device drivers associated with each device.
 .It Fl f Ar dev
 Only print information for the given USB controller.
+.It Fl p Ns Op Ar on | off
+Enable or disable USB bus probing.  The default
+is
+.Ar on .
 .It Fl v
 Be verbose.
 .El
Index: usr.sbin/usbdevs/usbdevs.c
===================================================================
RCS file: /cvs/src/usr.sbin/usbdevs/usbdevs.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 usbdevs.c
--- usr.sbin/usbdevs/usbdevs.c 22 Dec 2015 08:36:40 -0000 1.25
+++ usr.sbin/usbdevs/usbdevs.c 1 Jan 2017 22:52:53 -0000
@@ -30,14 +30,15 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <sys/types.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
-#include <fcntl.h>
 #include <unistd.h>
-#include <err.h>
-#include <errno.h>
 #include <dev/usb/usb.h>
 
 #ifndef nitems
@@ -46,21 +47,23 @@
 
 #define USBDEV "/dev/usb"
 
-int verbose = 0;
-int showdevs = 0;
+int verbose;
+int showdevs;
+int getprobe;
+int setprobe;
 
 void usage(void);
 void usbdev(int f, int a, int rec);
 void usbdump(int f);
 void dumpone(char *name, int f, int addr);
-int main(int, char **);
+void busprobe(int f, unsigned int probe);
 
 extern char *__progname;
 
 void
 usage(void)
 {
- fprintf(stderr, "usage: %s [-dv] [-a addr] [-f dev]\n", __progname);
+ fprintf(stderr, "usage: %s [-dv] [-a addr] [-f dev] [-p[on | off]]\n", __progname);
  exit(1);
 }
 
@@ -177,6 +180,21 @@ dumpone(char *name, int f, int addr)
  usbdump(f);
 }
 
+void
+busprobe(int f, unsigned int probe)
+{
+       if (setprobe) {
+               if (ioctl(f, USB_SET_BUS_PROBE, &probe))
+                       err(1, "setprobe");
+       } else if (getprobe) {
+               if (ioctl(f, USB_GET_BUS_PROBE, &probe))
+                       err(1, "getprobe");
+               printf("bus probing: %s\n",
+                      probe ? "on" : "off");
+       }
+}
+
+
 int
 main(int argc, char **argv)
 {
@@ -184,10 +202,11 @@ main(int argc, char **argv)
  char buf[50];
  char *dev = NULL;
  const char *errstr;
+ unsigned int probe = 1;
  int addr = 0;
  int ncont;
 
- while ((ch = getopt(argc, argv, "a:df:v?")) != -1) {
+ while ((ch = getopt(argc, argv, "a:df:p::v?")) != -1) {
  switch (ch) {
  case 'a':
  addr = strtonum(optarg, 1, USB_MAX_DEVICES, &errstr);
@@ -200,6 +219,19 @@ main(int argc, char **argv)
  case 'f':
  dev = optarg;
  break;
+ case 'p':
+ if (!optarg) {
+ getprobe = 1;
+ } else {
+ if (!strcmp(optarg, "on"))
+ probe = 1;
+ else if (!strcmp(optarg, "off"))
+ probe = 0;
+ else
+ usage();
+ setprobe = 1;
+ }
+ break;
  case 'v':
  verbose = 1;
  break;
@@ -210,11 +242,19 @@ main(int argc, char **argv)
  argc -= optind;
  argv += optind;
 
+ if (argc)
+ usage();
+
  if (dev == 0) {
  for (ncont = 0, i = 0; i < 10; i++) {
  snprintf(buf, sizeof buf, "%s%d", USBDEV, i);
  f = open(buf, O_RDONLY);
  if (f >= 0) {
+ if (setprobe || getprobe) {
+ busprobe(f, probe);
+ close(f);
+ break;
+ }
  dumpone(buf, f, addr);
  close(f);
  } else {
@@ -229,10 +269,15 @@ main(int argc, char **argv)
     __progname);
  } else {
  f = open(dev, O_RDONLY);
- if (f >= 0)
- dumpone(dev, f, addr);
- else
+ if (f >= 0) {
+ if (setprobe || getprobe)
+ busprobe(f, probe);
+ else
+ dumpone(dev, f, addr);
+ close(f);
+ } else {
  err(1, "%s", dev);
+ }
  }
  exit(0);
 }

Reply | Threaded
Open this post in threaded view
|

Re: USB Firewall

Kevin Chadwick-4
In reply to this post by Jiri B-2
On Wed, 17 Jan 2018 03:38:39 -0500


> > > Is there a method to detect and halt additional USB devices being
> > > added after initializing connections? Concerned about widespread
> > > vulnerability of keystroke injection.  
>

I am struggling to remember the details and will have to re-check but if
you are worried about intels debug port then I *think* it may suffice
to disable the USB3 ports or controller in the bios. The congatec
skylake bios atleast allows you to disable particular ports. OEMs may
hide this bios option from you though. I believe access via PCI-EX will
vary per board.

> There's no such way. Maybe something like this
> https://usbguard.github.io/ but that's for Linux only.
>
> There can be hw attacks over DisplayPort too. Some Linux people were
> discussing a possibility to disallow adding new DisplayPort based
> devices after boot to prevent physical attack on fully booted
> (physically unprotected) computer.

I assume their aim is to raise the bar for easier detection but
protecting a physically unprotected computer isn't possible.