php multiuser system – the www-data problem

On a lot of multi-user systems, like the one at the school where we have 300+ users all with usermod enabled, we also happen to have other web services running. It’s inconvenient and in insecure for everyone to be running their dynamic web stuff as the same user. I understand this is nearly impossible to do with good security, but this is a university and the point of this server is to let students learn, which means being able to host code.

One security problem in particular is php. suexec was built for cgi-bin stuff – but php is a whole other beast. That’s what I’m talking about here – getting php to run as the user who owns it. More specifically, this will show how /home/user/public_html/myphp.php will run as “user”, but stuff in /var/www will still run as www-data.

One good article I found describing this is here: http://alain.knaff.lu/howto/PhpSuexec/

First things first – mod_php needs to be disabled. This can be done globally, but it’s better to just disable it for public_html dirs. This can be done by adding the following to /etc/apache2/apache2.conf.

<Directory /home>
 php_admin_flag engine off
</Directory>

Now, to enable suphp.

First install php-cgi. and the apache2 prefork which has some things we’ll need later on.

apt-get install php-cgi apache2-prefork-dev

Do not install libapache2-mod-suphp – at least not on 8.04. This older version lacks some of the things most people need… like having more than one directory.

Download the latest suphp module from http://www.suphp.org/Home.html.  Compile this like:

tar xfzv suphp-SNAPSHOT-2008-03-31.tar.gz
cd suphp-SNAPSHOT-2008-03-31
./configure --with-apxs=/usr/bin/apxs2 --with-setid-mode=owner
make
make install

Modify apache’s config

LoadModule suphp_module /usr/lib/apache2/modules/mod_suphp.so
<Directory /home>
AddHandler application/x-httpd-php .php .php3 .php4 .php5 .phtml
suPHP_AddHandler application/x-httpd-php
suPHP_Engine on
</Directory>

Now in /usr/local/etc/suphp.conf

[global]
webserver_user=www-data
docroot=${HOME}/public_html
check_vhost_docroot=false

[handlers]
;Handler for php-scripts
application/x-httpd-php="php:/usr/bin/php-cgi"

Restart apache. To debug, check /var/log/apache2/errors.log.  To test create scripts in public_html directories and in /var/www that exec(‘whoami’) and make sure they’re called with the correct permissions.

It’s a start, but then there’s always stuff like XSS, etc.

Small Steps

These are some small steps you can take to make it harder for an attacker to figure out what version of some things you have running. These are specific to ubuntu:

apache

Go into /etc/apache2/apache2.conf and change

ServerTokens Full

to

ServerTokens Prod

This will change your info for things like 404s, so instead of listing your exact os, version of apache, etc, it will only say something like ‘Apache Server at progeny.isu.edu Port 80’

postfix

change the smtpd_banner line to something like “smtpd_banner = $myhostname ESMTP $mail_name (Linux)” which will be much harder to figure out than all the crap this normally prints, which, once again, is the exact version of postfix you are running along with the os.

bind

By default, bind also lets people know all this info.  You can change this by changing the version = lines as follows

options {

version “back off, dirt bag!”;

}

Though many of these services can still be fingerprinted without too much effort, not reporting your version info for every service you run is probably a good idea.  So, for example, because of this, you may have a harder time figuring out that this server is running apache2.2 on ubuntu7.04 and postfix2.5… damn it.