A word of caution on the use of suphp ------------------------------------- This is a lame advisory, but an advisory nonetheless. Introduction ------------ At our site we use both mod_php and mod_suphp to make a transition from mod_php (scripts run as user www-data) to mod_suphp (scripts run as the owner of the script) This temporary situation can be abused by outside attackers to gain access to almost any user account on a webserver by abusing mod_php to gain www-data privileges and abusing the www-data account to gain other privileges through suphp. This "advisory" will show you how easy this can be accomplished... How suphp works --------------- Because suphp is setuid root, it is only natural that some security checks are performed before executing a script with elevated privileges. This is how suphp works: - The environment variable (env var) SCRIPT_FILENAME is checked to see if it exists. - The uid of the calling user is checked to see if it is allowed to run suphp (in our case, it needs to be www-data"). - the filename of the script (SCRIPT_FILENAME) is checked to see if it resides in the document root (DOCUMENT_ROOT env var). - the filename is checked to see if the file exists. - the file permissions of the script are checked to make sure that it is readable by the owner, and not writable by either "group" or "other" (u+r,g-w,o-w). - the uid and gid to run the script as, are retrieved from env vars PHP_SU_USER and PHP_SU_GROUP. - The script is checked to make sure it is owned by user with uid = PHP_SU_USER and group with gid = PHP_SU_GROUP. - PHP_SU_USER and PHP_SU_GROUP are checked to make sure they are larger than some number (in our case 100, which rules out executing things as e.g. root). - If the filename is a symbolic link, it is dereferenced and checked again for the above conditions. - A message is logged. - uid/gid are set - a new environment is created - /usr/bin/php is run and the script is executed. It is clear that we don't need to do the impossible to foil suphp: - gain www-data privileges - put a php script in a file owned by some user and only writable by that user. - set some environment variables - execute suphp Step 1: gaining www-data privileges ----------------------------------- Since most scripts are running as user www-data, it's not a big challenge to gain www-data privileges. Even for an outside attacker. We used to find (failed) backdoors at our site on a regular basis, proving that the sites and forums of our users aren't safe at all. Step 2: uploading code for suphp to execute ------------------------------------------- Injecting php-code into a file owned by another user and not writable by anyone but that user might look challenging... and it is. I have spent a while pondering about this issue, thinking it would be very tricky... However, the answer is more simple than it thought. Usually, every user has a mailbox which is owned by that user, and not writable by anyone else. So... we just mail them a php-script and execute their mailbox! (This part is totally optional however. Instead of uploading code and executing that, you might just simply want to read sensitive files like private ssh keys) Step 3: creating a nice environment ----------------------------------- This needs to be done as user www-data: export SCRIPT_FILENAME=/some/path/to/Mailbox export DOCUMENT_ROOT=/ export PHP_SU_USER=theuser export PHP_SU_GROUP=hisgroup Step 4: executing the uploaded code ----------------------------------- Suphp doesn't take any arguments and gets everything from environment, so : /usr/bin/suphp Solution -------- The most obvious solution would be to not use both mod_php and mod_suphp at the same time. I'm not aware of any other solutions at this time. greets, -- Steven Steven Van Acker deepstar@ulyssis.org [ Need a challenge ? ] [ Visit http://www.pulltheplug.com ]