Attack Phase 3: Local User to Root
CS 493/693 Lecture,
Dr. Lawlor, 2006/02/13
Once an attacker has gained local access, for example by:
- Finding a vulnerability in an unpatched network service.
- Using social engineering on an unsecured secretary.
- Convincing the sysadmins that he needs access.
The next step is to escalate local user access to local
root/Administrator access. This is trivial if you've successfully
attacked a network service that's already running as root--this alone
is a good reason to run network services under a special "nobody"
account with no access rights.
Set-User-ID (setuid) Executables
The single most common route to root from a local user account on a UNIX server is finding a bug in a set-user-id executable. Any executable can be tagged to run as root (or any other user) with two easy steps:
- Call the system call "setuid(0)" from within the program. Zero is root's user-id.
- Change the program's owner to root, and permission to include the
"set-user-id" (s) bit. You need to be root already to do both
these things:
- chown root myprogram
- chmod +s myprogram
With these two conditions met, "myprogram" will run as root.
Clearly this hands over the machine if "myprogram" (for example) calls
a shell, like this:
/* A program that sets UID 0 and spawns a shell.
Used to execute arbitrary commands as root--
represents a HUGE security hole.
Orion Lawlor, olawlor@acm.org, 2006/02/13
*/
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
setuid(0); setgid(0);
return execv("/bin/sh",argv);
}
In fact, a program like this is a pretty obvious backdoor one might
insert after cracking a system. Hence a wary UNIX system
administrator will periodically scan the filesystem for setuid
executables, like this:
find / -perm +4000
Note that a typical UNIX system will have at least a dozen setuid
executables to perform various tasks that ordinary users are unable to
perform, including:
- ping, the ICMP-based network tester. Ordinary users can't
create ICMP packets (they're too dangerous), but it's nice to allow
them to test out the network. Hence ping is setuid root, and can be used to create a safe subset of ICMP packets.
- passwd, the password-reset tool. Clearly, you don't want
ordinary users to be able to edit all the passwords on the system, but
with enough checking and logging, they should be able to edit their own
password. "passwd" runs as root so it can modify the password
file, and provides this additional checking and logging.
- sudo allows a user listed in a particular file (/etc/sudoers) to execute (a possibly limited set of) commands as root. sudo checks the user's password and username before allowing them to become root.
Note that many bugs in setuid executables can be exploited by a local user to gain root access:
- Buffer overflows in command-line parsing can trivially be exploited.
- Various strange problems involving the environment variables
passed to setuid executables can be exploited. For example, odd
PATH settings, environment variable parsing buffer overflows, strange
characters, etc.
- Race conditions, often involving temporary file creation, were a
fruitful way to exploit local bugs. Running the setuid program
with "nice -n 20" to slow it down could help expose these race
conditions.
Due to the large number of setuid executables, these "local exploits"
seem more common than network server exploits. See, for a variety
of real examples, this list of Solaris exploits from 2001.