Re: setuid for priv sockets?
Re: setuid for priv sockets?
- Subject: Re: setuid for priv sockets?
- From: Brian Mastenbrook <email@hidden>
- Date: Mon, 27 Oct 2008 22:22:42 -0500
Hi Damien,
I think I'm beginning to see that I'm not communicating very
clearly. :-) I am viewing the problem as an attacker, and as such I am
probably missing distinctions that are important to the users and
implementors of these APIs.
On Oct 27, 2008, at 8:15 PM, Damien Sorresso wrote:
If SuperFancyEthernetCaptureProgram is requesting my user name and
password, who am I to argue with it? Nevermind that
TotallyEvilMaware.dylib has injected itself into the process and
will be rooting my system at the same time. By contrast, the
execution environment of setuid binaries is locked down so that
other user programs can't influence it. Even sudo itself is setuid
and is this isolated from the effects of PATH,
DYLD_INSERT_LIBRARIES, and other magic.
The lockdown of setuid binaries is enforced across multiple
components. dyld will refuse to honor the DYLD_INSERT_LIBRARIES
environment variable for setuid binaries, and the setuid(2) call
itself will (I believe) clean out some environment variables. But
the parent process can still corrupt the environment of the setuid
process. (For example, setuid programs inherit file descriptors in
exactly the same fashion as any other program.)
But you're conflating the safeness of the execution environment with
its trustworthiness. While setuid binaries execute in a slightly
safer environment because of little tricks here and there, their
environment is far less trustworthy because *anyone* with executable
access to the binary can run it with elevated privileges. The onus
of sanitizing the environment still rests with the author.
Yes - I do not think that setuid binaries are great, as I mentioned.
If you use a system-level launchd daemon, however, your execution
environment is implicitly trusted, since /sbin/launchd is implicitly
trusted. A user cannot affect the environment of your daemon *at
all* because the parent process is launchd, not the client process.
... except by communicating with the daemon. How many local root
exploits have been due to daemons running on the localhost which
accept but do not properly validate input from clients? How many
remote exploits? We are still operating in the mindset of launching a
piece of code with root privileges that receives tainted data from a
user process, and any such program is suspect for the same set of
reasons that make writing setuid helper tools difficult - and possibly
moreso, because now I have to deal with socket interactions to read
and parse the request rather than just reading and validating some pre-
tokenized arguments in argv. Sample code or no, there's still
significant opportunity for error here.
I really think you should read the AuthorizationServices
documentation. Don't take the existence of
AuthorizationExecuteWithPrivileges() to mean that it's the standard
way to do privilege escalation on Mac OS X. And please don't labor
under the impression that setuid binaries are the safest way to
elevate privileges on Mac OS X. They're not. See
BetterAuthorizationSample and/or the WWDC security talk (if you have
access).
I have read the documentation. I don't have access to the WWDC
security talk.
Even if APIs other than AuthorizationExecuteWithPrivileges are used,
any method of performing privileged operations that results in a
password dialog box is suspect. There are multiple problems with this
password dialog box. There is little-to-no useful information about
which right exactly is being requested. If multiple rights are
requested, only the first is displayed. Nobody bothers to check what's
behind the disclosure triangle anyway. The dialog can be spoofed. If
the user whose credentials are entered has administrative access,
anything running as my user now has root - even if the requested right
did not require admin!
Attempting to split the logic of the application into a safe portion
which only runs in a trusted environment (invoked by launchd) and an
unsafe portion which runs as an ordinary user is very difficult in non-
trivial cases. Having logic which is very difficult to implement that
needs to run as root is the same situation that got us into the setuid
mess in the first place.
*Any* access by an an unsafe user process to privileged operations is
problematic. Allowing an ordinary user process access to snoop
Ethernet traffic is the same as allowing anything that happens to be
running in my user account access to this right. If that's all I
wanted to accomplish, I could just change the permissions on /dev/
bpf*, and then I wouldn't have a helper tool running as root to worry
about implementing correctly.
AuthorizationExecuteWithPrivileges() is used also very commonly.
BetterAuthorizationSample uses it to install its helper tool. Software
Update and System Preferences use it.
The root of my point is this: if privilege escalation is done with
setuid programs, I have to find a setuid program which has been badly
written in order to gain root. Why would I bother when I can hijack
Software Update, or the LowNumberedPorts part of
BetterAuthorizationSample?
--
Brian Mastenbrook
email@hidden
http://brian.mastenbrook.net/
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden