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:
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:
  1. Call the system call "setuid(0)" from within the program.  Zero is root's user-id.
  2. 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:
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:
Note that many bugs in setuid executables can be exploited by a local user to gain root access:
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