Wireshark-dev: Re: [Wireshark-dev] Lua error while running Wireshark as root (was: Re: Wireshar
From: Guy Harris <guy@xxxxxxxxxxxx>
Date: Tue, 5 Feb 2019 15:47:47 -0800
On Feb 5, 2019, at 2:38 PM, Peter Wu <peter@xxxxxxxxxxxxx> wrote:

> On Tue, Feb 05, 2019 at 02:25:58PM -0800, Guy Harris wrote:
>> On Feb 5, 2019, at 2:07 PM, Peter Wu <peter@xxxxxxxxxxxxx> wrote:
>> 
>>> The last option would permit *users* to invoke arbitrary commands as
>>> root if they run Wireshark with sudo or as root user. I think that might
>>> not be a bad idea after all:
>> 
>> 	[existing reasons elided]
>> 
>> - They shouldn't be running *Wireshark* as root unless they're on a
>> system such as Kali where everything runs as root; if they need root
>> privileges in order to capture, they should make dumpcap set-UID root.
> 
> I agree, a warning is already printed by tshark when running it as root.

Depending on whether you have issetugid() or not.

On UN*X, started_with_special_privs() is:

/*
 * "Started with special privileges" means "started out set-UID or set-GID",
 * or run as the root user or group.
 */
gboolean
started_with_special_privs(void)
{
	g_assert(init_process_policies_called);
#ifdef HAVE_ISSETUGID
	return issetugid();
#else
	return (ruid != euid || rgid != egid || ruid == 0 || rgid == 0);
#endif
}

If you have issetugid(), it just returns what that returns; it's a system call that never fails.  In recent macOS, the comment for the kernel routine is

 * Notes:       A process is considered tainted if it was created as a retult
 *              of an execve call from an imnage that had either the SUID or
 *              SGID bit set on the executable, or if it has changed any of its
 *              real, effective, or saved user or group IDs since beginning  
 *              execution.

and it returns 1 if the process is "tainted" and 0 if it isn't (it just checks a flag set elsewhere).  Other *BSD-flavored OSes may do the check differently; macOS has a comment that

	/*
	 * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
	 * we use P_SUGID because we consider changing the owners as
	 * "tainting" as well.
	 * This is significant for procs that start as root and "become"
	 * a user without an exec - programs cannot know *everything*
	 * that libc *might* have put in their data segment.
	 */

I think OpenBSD was the system that introduced issetugid(); all the *BSDs, and macOS, have it.

I'm not sure whether any Linux distributions have issetugid(); I'm not seeing a symbol "issetugid" in Glibc 2.23 or the 4.20.3 kernel.  Solaris might have it.

That routine doesn't necessarily check for the *real* user or group ID being 0, however, so, on systems with issetugid(), a real user or group ID may not suffice to indicate that you were "started with special privileges", so running logged in as root, or with sudo, might not cause a warning to be printed.

So that somewhat depends on what "started with special privileges" means.

I'd say that running set-UID or set-GID clearly counts.  We're not a daemon that "starts as root and [becomes] a user without an exec", so that macOS-vs-OpenBSD difference doesn't matter to us.

If the program is run with sudo, one could argue that it was started with special privileges.

If you log in as root (the Kali Linux case), should *every program you run* be deemed as "started with special privileges"?  If not, how do you distinguish that from "run with sudo"?

I think the original intent of issetugid() is to catch cases where environment variables are tweaked when running a set-UID program, so that you end up loading shared libraries, plugins, etc. from a directory at which the (untrusted) user has pointed the program.  The warning from the packaging documentation, however, has nothing to do with that - it's warning that Wireshark is a big enough program that the dissectors provide a nice big attack surface.

So what warnings *should* we provide about running with elevated privileges?  Should we consider "running as root" to be "running with elevated privileges" even if issetuid() returns 0 (because your program didn't get its privileges from set-UID), and issue a UI warning in that case?