Understanding Privilege Escalation

This sample attack will show you some of the techniques intruders use to scale up their powers.

Local privilege escalation happens when one user acquires the system rights of another user. Network intruders have many techniques for increasing privileges once they have gained a foothold on a system. The initial intrusion could start from anywhere. A guest account? A local user who has carelessly written a username and password on a Post It note? Everyday users typically operate at a relatively low privilege level – specifically to prevent someone who obtains their credentials from gaining control of the system. Once inside, the intruder employs privilege escalation techniques to increase the level of control over the system. In this article, I'll describe some techniques malicious users employ to escalate their privileges on a Linux system.

I'll start with a low-privilege user account with SSH access and try to escalate the privileges. Of course, this article can only cover a small fraction of the privilege escalation techniques in use today, but it should give some indication of how an intruder thinks and acts in a typical attack session.

For purposes of this exercise, I'll launch this test attack on a system running Metasploitable. Metasploitable is a purposely old and vulnerable Ubuntu 8.04 system maintained by the Metasploit project.

Information Gathering

Once the intruder logs in with a low-end user account, the first step is to get some information about the system and rights.

First, get the distribution name:

$ cat /etc/issue
Ubuntu 8.04 \n \l

An intruder typically executes some basic commands to get to know the system. Of particular interest are the \etc directory and the package manager.

One really obvious (but rarely successful) trick is to look for writable SUID/GUID files. SUID (Set User ID) files execute with the privileges of file owner, rather than the user, and a writable SUID file would essentially allow the user to execute any commands the owner of the file could execute simply by modifying the file.

find / -o -group `id -g` -perm \ 
 -g=w -perm -u=s -o -perm -o=w\
 -perm -u=s -o -perm -o=w \
 -perm -g=s -ls 

SUID files are naturally used to escalate privileges when needed and should not be writable. If they are, a malicious user can simply change their contents before executing them, thus effectively escalating his privileges system wide.

Other questions the intruder asks are:

  • Are there any unmounted filesystems?
  • What development tools are available? Is there access to a compiler? Can I execute compiled files?
  • Is there access to a package manager to download and configure new applications?

Also, it is worth getting information about scheduled cron jobs, checking out network configuration, and searching for files writable outside the home directory.

Most of this information gathering can be automated with at least a simple shell script, though there is always some part that has to be done manually. Listing 1 shows an example of a shell script an intruder might use to gather basic information about the system. The results are written to the standard output, which is typically redirected to a text file. A single output file lets the intruder concentrate on analyzing the gathered information, instead of typing a succession of interactive find commands (and man commands to look up find parameters).

In this case, since the initial user account has a low privilege level, most of find commands will generate Permission denied warnings. The redirection 2>/dev/null attached to each of the commands in Listing 1 removes those warnings from the output, making the report much easier to read and analyze.

Listing 1: Example of basic information gathering script
#!/bin/sh
echo Distribution and kernel version
cat /etc/issue
uname -a

echo Mounted filesystems
mount -l

echo Network configuration
ifconfig -a
cat /etc/hosts
arp

echo Development tools availability
which gcc
which g++
which python

echo Installed packages (Ubuntu)
dpkg -l

echo Services
netstat -tulnpe

echo Processes
ps -aux

echo Scheduled jobs
find /etc/cron* -ls 2>/dev/null
find /var/spool/cron* -ls 2>/dev/null

echo Readable files in /etc 
find /etc -user `id -u` -perm -u=r \
 -o -group `id -g` -perm -g=r \
 -o -perm -o=r \
 -ls 2>/dev/null 

echo SUID and GUID writable files
find / -o -group `id -g` -perm -g=w -perm -u=s \
 -o -perm -o=w -perm -u=s \
 -o -perm -o=w -perm -g=s \
 -ls 2>/dev/null 

echo SUID and GUID files
find / -type f -perm -u=s -o -type f -perm -g=s \
 -ls 2>/dev/null

echo Writable files outside HOME
mount -l find / -path “$HOME” -prune -o -path “/proc” -prune -o \( ! -type l \) \( -user `id -u` -perm -u=w  -o -group `id -g` -perm -g=w  -o -perm -o=w \) -ls 2>/dev/null

Running the script from Listing 1 on Metasploitable produces quite a large amount of output.

In the case of Metasploitable, the script did not turn up any unmounted filesystems, as the cfdisk and mount -l commands don't show anything suspicious. If any unmounted filesystems existed, the next step would be to try to mount them, look around, and execute all the information-gathering steps again.

The script outputs some details about the network configuration, but nothing looks interesting – no hosts defined in /etc/hosts, one network interface, and an almost-empty arp table.

Several development tools are available, including gcc and g++. I can run compiled programs from the home directory, which means I can compile exploits if we need to.

The account has access to a package manager. I can't install or remove software, but I can list the software installed with its detailed version information. This information will be very useful later.

Also, I can list all system processes with ps aux and listen on ports with netstat -tulnp, although I can't see for sure which process listens on what port (root rights required). Nonetheless I can infer that, among others, Apache, Distcc, and Tomcat running.

There are also a few scheduled cron jobs, including PHP- and Tomcat-related jobs. I can't use them directly, but they give me a clue about what's running on the system. Also, if I can read their contents, I can try to control their input (if they have any).

And finally, great news – I can read virtually the whole content of /etc and /var directories.

Access to the /etc and /var directories gives me a great starting position for searching configuration flaws, though the administrator could easily have prevented access to this configuration information. Different use of traditional Unix file rights, enhanced by grsecurity, would stop me from reading configuration files, services, processes, network configuration, and information on installed software without making the life of the typical user any harder.

Configuration Flaws

I didn't find any writable SUID/GUID files, which is not surprising, but I found 884 SUID/GUID files without permission to write. This is an unusually high number, which increases the chances that one or more will be vulnerable to privilege escalation. Most of these files are GUID files owned by user msfadmin and group www-data. The remaining 11 GUID files are owned by root and various groups. These files do not seem useful at first glance, so I won't analyze them deeper now, but I will remember to get back to them if I'm not successful with anything else.

Searching for writable files and directories outside home directory might provide a means for escalating privileges. Metasploitable revealed 1070 such entries. Among these writable files and directories, two directories are particularly interesting.

First is the directory /var/lib/php5, owned by user root and group root, with write/execute permissions but without reading permission for my user directory. I could try to use this directory for overwriting some PHP lib with my own version, but that seems like a lot of work, so I pass on that option for now and look for lower-hanging fruit. I can always get back to this if I don't find anything better.

Second are 473 files and directories owned by the user msfadmin and group msfadmin, placed in /var/www/tkwiki/data and /var/www/twiki/pub/Main. Most of these files are executable, in spite of the fact, that they are mainly image and text files. At first glance, these files don't seem to be of much use for us, but wait, doesn't this look like it might be website data? Invoking a simple grep -r '/var/www/twiki' /etc/apache2 and looking up the collected earlier process list and services list reveals that I have happened onto the wiki called Twiki, which should be available through HTTP.

Indeed, I can even open a wiki website using the URL: http://metasploitable/twiki/. This means I can easily run code with the rights of the web server, that is, as the previous ps showed, with www-data rights. A simple proof of concept is a PHP script with the following contents:

echo 'User: ' . exec('whoami');

I place the script in /var/www/twiki/pub/Main/. After navigating with a web browser to http://metasploitable/twiki/pub/Main/whoami.php, I get a web page saying User: www-data. Unfortunately (if you're the attacker) or fortunately (if you're the administrator), the web server doesn't run with root privileges. Nonetheless, I can escalated my rights to www-data, and I can use this account for further escalation later.

Software Vulnerabilities

To escalate privileges, I can also approach the system from a little different angle. Instead of trying to find flaws in the configuration, I can find flaws in the software itself and exploit them, either remotely or locally. This approach might include looking for flaws in services, installed software, or the Linux kernel itself. Listing 2 shows partial results of a few useful commands run on the Metasploitable system. Overall, I found a very old kernel, 28 ports open for incoming connections, and 441 packages installed and not updated for a while.

Listing 2: grep, ps and netstat example results
user@metasploitable:~$ uname -a
Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux

user@metasploitable:~$ netstat -tulnp 
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:8009            0.0.0.0:*               LISTEN      -               
tcp        0      0 0.0.0.0:139             0.0.0.0:*               LISTEN      -               
…
udp        0      0 0.0.0.0:68              0.0.0.0:*                           -               
udp        0      0 0.0.0.0:35579           0.0.0.0:*                           -               
udp6       0      0 :::48134                :::*                                -               
udp6       0      0 :::53                   :::*                                -               


user@metasploitable:~$ dpkg -l

Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Installed/Config-f/Unpacked/Failed-cfg/Half-inst/t-aWait/T-pend
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name                                  Version                     Description
+++-=====================================-=======================================================================
ii  adduser                               3.105ubuntu1                add and remove users and groups
ii  ant                                   1.7.0-3                     Java based build tool like make
ii  antlr                                 2.7.6-10                    language tool for constructing recognizers, 
…
ii  xkb-data                              1.1~cvs.20080104.1-1ubuntu6 X Keyboard Extension (XKB) configuration dat
ii  zlib1g                                1:1.2.3.3.dfsg-7ubuntu1     compression library – runtime
ii  zlib1g-dev                            1:1.2.3.3.dfsg-7ubuntu1     compression library – development

An easy way to quickly check for known remote service vulnerabilities is to use the Metasploit security testing tool. Metasploit checks for over 700 exploits, and it is very easy to use. It can be installed on any Linux system, but I'll use a specialized Linux distribution called BackTrack, which comes with Metasploit preinstalled. BackTrack can run as a live CD as well as installed on the hard disk. Because BackTrack and Metasploit are frequently updated, it's important to run

apt-get update && apt-get upgrade

and

cd /pentest/exploits/framework2/
svn update

before starting msfconsole.

The recipe for how to escalate privileges using Metasploit is as follows: start msfconsole, get running services and their versions, search and select matching exploits, set payload and options, run exploit, and, if you're lucky, try out a new session. When in doubt, don't hesitate to use the help command.

In the information gathering phase, I've already obtained a list of running services, so I can start searching for matching exploits. To do that, I use the search command for each service. For example, search distcc reveals one available exploit. To try it out, I select exploit/unix/misc/distcc_exec, set the target host (set RHOST metasploitable) set the port (set RPORT 3632), set the payload (set PAYLOAD cmd/unix/bind_perl), and run exploit. You can see the effect of this in Figure 1. As you can see, the exploit worked, and I now have daemon privileges, and I have another account that can be used for the next iteration of privilege escalation. Keep in mind though, that usually you don't get so successful the first time or even the few first times.

Figure 1: Exploiting distcc with Metasploit.

To simplify the search and exploit process, Metasploit also provides the db_autopwn method. This method automates the process, but it doesn't always work as well as manual reviewing. Also, to use db_autopwn, I have to fill the Metasploit database with running services and their version numbers. First, I check if the database is connected with db_status. If it is, I can run an nmap scan, for example: db_nmap -sS metasploitable. This scan fills up the database with services. After the scan finishes, I can check the results with db_services. Now, I run db_autopwn -p -e, which tries every available exploit based on the port number. You can see the result in Figure 2. I've got two sessions, one for www-data user and the other for daemon user.

Figure 2: Metasploit db_autopwn results on Metasploitable.

When Metasploit gives no positive results, I can manually search the Internet for vulnerabilities and local exploits. Good places to start searching for such exploits are the ExploitDB, SecurityFocus, and PacketStorm websites, as well as with Google and other search engines. Throwing the Metasploitable kernel and a few software packages at them reveals a number of exploits. Having SSH access to Metasploitable, I can simply copy and paste, run gcc, and test if the exploit works.

The preceding process is very time consuming. Unfortunately, the attacker usually has time to try out exploits one by one and wait to hit the right one. On the other hand, the administrator has to spend much time testing the systems to prevent all possible attacks. A much less time consuming approach, that is often quite successful in significantly reducing exposure to attack, is simply patching and updating the software.

Conclusion

User privilege escalation is a very broad topic with way more aspects than one can cover in any short article. A few other techniques are worth mentioning in conclusion: bruteforcing, sniffing, and social engineering.

Bruteforcing is an unsophisticated method that might work on systems with a very weak (or nonexistent) security policy. Too short or dictionary passwords and guessable user accounts greatly increase the probability of success with a brute force attack. Sniffing is much more complicated. If you can see network traffic, several options exist for getting access, including sniffing for unencrypted passwords and launching a man-in-the-middle attack. Last but not least, social engineering can sometimes reveal secrets you won't find online. Sometimes simply tricking people into giving up their credentials is easier than searching for a configuration flaw or vulnerable software. This doesn't always require you to make a phone call. Sometimes a simple email works. A useful tool for that can be Metasploit SET (Social Engineering Toolkit).

As with any other aspect of life, to have good results, experience is the key. Get familiar with BackTrack, and try out some of the deliberately vulnerable Linux distributions and installable software. Some examples of vulnerable software and distros include pWnOS, the Holynix and De-ICE series, OWASP BWA, and Web Security Dojo.

And remember, do not learn to hack – hack to learn!

The Author

Marcin Teodorczyk has been passionate about Linux for over 12 years. Currently he works with grid environments as an Information Security Assistant and in his spare time – juggles.