Wireshark-users: [Wireshark-users] [patch] drop privs in dumpcap if run setuid by non-root
From: Hank Leininger <hlein@xxxxxxxxxxxxx>
Date: Mon, 12 Feb 2007 17:26:59 -0500
The other day, I wanted to run wireshark live, i.e. capture and view
some packets, rather than just feed it an existing pcap.  On Linux, I
found this was basically impossible (longtime users probably know this
already):

- By default no part of wireshark is installed setuid
- There is an --enable-setuid-install configure option, which installs
  both wireshark and dumpcap setuid root
- However, as mentioned in the docs, gtk apps don't like running as
  root.  And besides, this just seemed dumb.
- So, too, did actually being root to run (all of) wireshark.
- I tried chmod +s'ing only dumpcap.  This gives it the needed privs,
  _but_ it creates a tempfile with which to communicate with wireshark
  that is mode 600 -- so when it runs as root, the rest of wireshark
  cannot read the file.

While on a plane back home I whipped up the attached patch to dumpcap to
drop elevated privileges as soon as the pcap socket has been opened.
Then I can create a 'sniffer' group, and chgrp sniffer, chmod 4110 the
dumpcap binary.  Tested for a whole five minutes, seems to work fine:
wireshark launches dumpcap to sniff, opens the raw capture socket, drops
root, opens the output file, and starts reading/writing packets.  It
looks to me like every time a new capture is started, dumpcap is
respawned, so euid0 is not needed again.  Works with tshark as well.

At the time, I had not yet read the discussions on the wireshark lists
(and the ethereal ones years before that) about how privilege separation
would be a better way to go, and about how the dissectors would best run
not just non-root, but non-user either--that is, they should run as a
dedicated, chrooted user.  I agree that that would be ideal.  But in the
meantime, I think something like this would be better than nothing.

Thanks,

-- 

Hank Leininger <hlein@xxxxxxxxxxxxx>
F980 A584 5175 1996 DD7E  C47B 1A71 105C CB44 CBF8
diff -urP wireshark-0.99.5/Makefile.am wireshark-0.99.5-hap/Makefile.am
--- wireshark-0.99.5/Makefile.am	2007-02-01 18:01:43.000000000 -0500
+++ wireshark-0.99.5-hap/Makefile.am	2007-02-12 01:17:59.000000000 -0500
@@ -655,7 +655,6 @@
 if SETUID_INSTALL
 install-exec-hook:
 	-chmod +s $(DESTDIR)$(bindir)/dumpcap
-	-chmod +s $(DESTDIR)$(bindir)/tshark
 else
 install-exec-hook:
 endif
diff -urP wireshark-0.99.5/Makefile.in wireshark-0.99.5-hap/Makefile.in
--- wireshark-0.99.5/Makefile.in	2007-02-01 18:02:55.000000000 -0500
+++ wireshark-0.99.5-hap/Makefile.in	2007-02-12 01:18:10.000000000 -0500
@@ -2167,7 +2167,6 @@
 
 @SETUID_INSTALL_TRUE@install-exec-hook:
 @SETUID_INSTALL_TRUE@	-chmod +s $(DESTDIR)$(bindir)/dumpcap
-@SETUID_INSTALL_TRUE@	-chmod +s $(DESTDIR)$(bindir)/tshark
 @SETUID_INSTALL_FALSE@install-exec-hook:
 
 wireshark.1: doc/wireshark.pod AUTHORS-SHORT-FORMAT
diff -urP wireshark-0.99.5/capture_loop.c wireshark-0.99.5-hap/capture_loop.c
--- wireshark-0.99.5/capture_loop.c	2007-02-01 18:01:47.000000000 -0500
+++ wireshark-0.99.5-hap/capture_loop.c	2007-02-12 01:55:22.000000000 -0500
@@ -1271,6 +1271,12 @@
     goto error;
   }
 
+  if (setgid(getgid()) || setuid(getuid())) {
+    g_snprintf(errmsg, sizeof(errmsg), "error dropping privileges: %s", strerror(errno));
+    *secondary_errmsg = '\0';
+    goto error;
+  }
+
   /* init the input filter from the network interface (capture pipe will do nothing) */
   switch (capture_loop_init_filter(ld.pcap_h, ld.from_cap_pipe, capture_opts->iface, capture_opts->cfilter)) {
 

Attachment: pgpaujfYve9ao.pgp
Description: PGP signature