ECE4112 Internetwork Security

Lab: Securing Apache and PHP

Group Number: ______

Member Names: ______

Date Assigned:

Date Due:

Last Edited: December 11, 2007

Lab Authored By: Christopher Pau, Justin Mayhue

Please read the entire lab and any extra materials carefully before starting. Be sure to start early enough so that you will have time to complete the lab. Answer ALL questions and be sure you turn in ALL materials listed in the Turn-in Checklist ON or BEFORE the Date Due.

Goal: This lab will explore the popular open-source Apache web server and PHP scripting language. You will learn common web server vulnerabilities and server-level protections for them.

Summary: The popular LAMP (Linux-Apache-Mysql-PHP) setup uses free software - it is popularity makes it used for the majority of web servers today.

According to Netcraft, Apache servers represent 50.76% of web servers in November 2007. But the popularity of the server makes it an easy target. Most hosts will set up the software with the default configurations. Because most hosts are worried about stability, they will not often update to the latest versions.
This lab will explore server-level protection for Apache and PHP including
- httpd.conf - Configuration changes for less disclosure, stop DDOS, protecting sensitive folders
- PHPsuexec - designed to protect PHP scripts by running scripts under the current user permissions using PHP as a CGI module

- suPHP – another way to extend user permissions using PHP as a CGI module
- PHP safe mode - configurations such as magic_quotes_gpc, register_globals, and open_basedir
- mod_security - Apache module designed to filer incoming connections against common attacks

This assumes the Red Hat WS 4 and VMWare setup. This also assumes Apache has been set up correctly from the Web Security lab and scripts are set up correctly. And finally, it requires the Web Security additions to the lab for RFI.

Background and Theory:

Apache is a popular, free web server developed for Unix-based systems by the Apache Software Foundation. It is available for a wide variety of operating systems including Windows, Novell NetWare, Mac OS X, and Linux. Released under the Apache license, it is free / open source software named out of respect for the Native American Indian tribe of Apache as well as its roots as a set of patches to the code base of NCSA HTTPd 1.3 – making it “a patchy” server [1].

Apache supports numerous features, many implemented as compiled modules to extend functionality. One of its main strengths is the support for virtual hosting – allowing one Apache installation to serve many different actual websites simultaneously [1].

PHP is a programming language designed for producing dynamic web pages. Mainly used for server-side scripting, it can also be used from command line interface or standalone graphical applications. Like Apache, PHP is also released as free / open source software by its foundation, the Free Software Foundation. It can run on many operating systems and web servers, but its match within the free software LAMP (Linux-Apache-Mysql-PHP) platform makes it very popular and easy to use. PHP is a recursive initialism for PHP: Hypertext Preprocessor [2].

PHP (and other scripting languages) complement Apache very well – Apache to serve out web content to the user and PHP to generate the dynamic content. PHP was originally written as a set of Common Gateway Interface (CGI) binaries in C programming language [2]. CGI was one of the earliest standards to allow the server to pass requests from a web browser to an external application. Thus, dynamically generated content can be created very easily in different executable files and passed through the web server. Web servers often have a cgi-bin directory to hold executable files [3]. PHP still has an installation designed for CGI.

CGI is very popular method for Perl and PHP scripts. However, if the executable binary is separated from the cgi-bin scripts that are running (say for multiple users with different cgi-bin paths who want to access the same installed binary), all scripts must place a header to indicate the binary to execute such as:

PHP

#!/usr/local/bin/php

Perl

#!/usr/bin/perl

The last line is probably very familiar to anyone who has done Perl programming for a web server. The binary path must be known in order for the script to execute [4].
There is another way to install PHP: as an Apache module. This is what we did in the web security lab by changing the httpd.conf file.

LoadModule php4_module modules/libphp4.so

This configuration tells Apache to load the php4 module so we can use it. There are other configurations we can use and set default configurations for Apache and PHP for better security.

Why use an Apache module over a CGI binary? Speed. The Apache module is much faster because it passes the work to child processes of its own. PHP as a CGI “wrapper” requires an instance of the PHP interpreter to be created and destroyed for every page request. Any resources that it uses is closed and destroyed after the request is done. In Apache, every child process can reuse the same resources such as an established connection to an SQL server. This allows it to be much more efficient in serving multiple users [5].

Why use a CGI binary over an Apache module? Security. Under Unix-based systems, Apache uses robust user permissions system to protect all scripts and stop unauthorized execution. Apache runs as its own user – typically inheriting the permissions of the “nobody” user. As an Apache module, all resources such as databases must be accessible to “nobody” – allowing malicious scripts to also do the same. Further it does not require the execute flag to run. Since version 1.2, Apache has supported suEXEC – a feature to allow users the ability to run CGI and SSI programs under different user IDs. This generally has more to configure, but provides a very good set up for multiple users in a virtual hosting environment. More on installation, advantages, disadvantages of each: [6,7,8,9].

Web hosts often have to choose between CGI and an Apache module. Developers and webmasters need to know what secure measures are in place using PHP with CGI and suEXEC (often called PHPsuexec = PHP + suexec) and how this affects their site. Different file permissions may need to be set for various applications (CHMOD 777/ 775/ 664…) depending on the security used. Another option is suPHP; it is designed like PHPsuxec to execute PHP scripts with permissions of their owner [10].

Another advantage to using PHP as an Apache module is the ability to manipulate PHP using .htaccess – since this is an Apache feature. This allows you set PHP configurations in the form of php_value settings and applies to all directories and subdirectories where .htaccess is used.

PHP as CGI does not allow this feature. Instead, a php.ini file must be included in every directory for these custom settings to be affected. As an example:

.htaccess

php_value magic_quotes_gpc on

php.ini

magic_quotes_gpc = on

You can still use .htaccess for Apache directives but no PHP directives [11].
PHP itself provides some shared-server security in the form of Safe Mode. While their developers note it is architecturally-incorrect to solve problems as the PHP level, it is an alternative provided for many servers. Safe mode provides user permissions security and defines limits to the file structure that PHP scripts can access. It also provides the ability to disable certain functions. While Safe Mode is being removed from the next PHP 6.0.0 version, it is still prevalent in PHP 4 and PHP 5 and is used by many ISPs today [12].

One solution for securing PHP is in the mod_security addon. It is designed as a web application firewall and can block many attempts to do Cross-site Scripting (XSS) exploits, Remote File Inclusions (RFI), and other known attempts. It’s rules-based system allows easy configuration to provide flexibility to the user [13].

Another solution provided for security is the Hardened-PHP project’s Suhosin system and Hardening-Patch. These patch and protect PHP installations from known and unknown flaws in PHP applications and the PHP core. The Hardening-Patch is implemented onto PHP itself while Suhosin is an extension to be installed onto plain PHP [14].

References:

[1] - http://en.wikipedia.org/wiki/Apache_HTTP_Server

[2] - http://en.wikipedia.org/wiki/PHP

[3] - http://en.wikipedia.org/wiki/Common_Gateway_Interface

[4] - http://en.wikipedia.org/wiki/Perl

[5] - http://us.php.net/manual/en/features.persistent-connections.php

[6] - http://archiv.debianhowto.de/en/php_cgi/c_php_cgi.html

[7] - http://httpd.apache.org/docs/1.3/suexec.html

[8] - http://us.php.net/manual/en/security.cgi-bin.php

[9] - http://us.php.net/manual/en/security.apache.php

[10] - http://www.suphp.org

[11] - http://www.hostmagik.info/phpsuexec.php

[12] - http://us.php.net/manual/en/features.safe-mode.php

[13] - http://www.modsecurity.org/

[14] - http://www.hardened-php.net/

Section 0: Setup

I. File Setup

In the nas4112/Lab# directory, grab the php.tar.gz file and place in your Apache2/htdocs folder. Go to the folder and extract this file (tar xvzf php.tar.gz)

You should have one more folder in Apache2/htdocs

/php


Also grab the php-cgi.tar.gz file and place in your Apache2/cgi-bin folder. Go to this folder and extract this file (tar xvfz php-cgi.tar.gz)

You should have one more folder in Apache2/cgi-bin

/php

For your convenience, grab the files for the next two sections as well

mod_suphp-0.5.2-7.fc3.i386.rpm to your home directory

mod_unique_id.so to your Apache2 directory

modsecurity-apache_2.1.4.tar.tar to your Apache2 directory

modsecurity-core-rules_2.1-1.5.1.tar.tar to your Apache2 directory

If you don’t have a folder htdocs/rfi, the Web Security addition was not included. Please get these file csrf.tar.gz from this lab’s directory or previous web security directory and extract them to your htdocs folder.


Section 1: PHP Apache module

Part 1 – Testing Permissions:

This section will test various permissions for PHP scripts running in Apache.

First, start up your web browser and load

http://localhost/php/grabfile.php

This file attempts a number of superuser administrative privileges, mainly to add a new phpuser to the system.

Executing whoami – this returns the associated user that this script is running

Executing useradd phpuser – this uses the system command useradd to attempt to add a new user

Reading /etc/passwd file – this is the password file that displays all user accounts on the system
Writing newphproot:x:0:0:root:/root:/bin/bash to /etc/passwd file – this attempts to append a new entry to the user password file

Q1.1: What is the user account this script is running as?

Q1.2: Does our useradd command add a new user?

Q1.3: Does our addition to the password file add a new user?

Note that PHP scripts can still read these system files. This may allow vulnerable PHP scripts to compromise the server’s passwords.


Next try a script to write a text file to our script directory

http://localhost/php/newfile.php

This file users the is_writable function to determine whether we can write newfile.txt

In this case, nothing or false is returned meaning we cannot write to it.

Use your terminal to go into the htdocs/ directory and view permissions on this folder. (Use ls –la to retrieve all the details)

You should see something like

Drwxr-xr-x 2 root root 4096 Dec 4 16:39 php

Q1.4: Who is the owner of this directory?

Q1.5: What permissions does this owner have?

Q1.6: What permissions do other users have?

Try changing to the permissions to allow other users to write to this directory.

chmod 777 php

Now run newfile.php again.

Q1.7: Does this script now allow you to write this file? How can you check?

Q1.8: Who is the owner of newfile.txt?

While tedious to do sometimes, many scripts require 777 permissions on directories in order to write files out to the system. This may include script data, images, and other code that could be useful to store on the web server.

Create a simple FTP user that would have permissions to store files here. This is typical of the way most web hosts allow access to upload scripts. Telnet/ssh is rarely allowed.

useradd ftpuser –d [path/to/htdocs]

passwd ftpuser

Use the full path to the Apache2/htdocs and give a simple password you want to use.

Make sure you are in the /htdocs/php/newfile directory. Here we have a newfile.txt we are going to replace with the current one.

FTP using your new ftpuser account and then upload this new file.

ftp localhost

Name: ftpuser

Password: (your password)

ftp> send newfile.txt

Q1.9: Can you write to this file? Why or why not?

As you can see, permissions for PHP running as an Apache module can present some problems. Running as the user nobody may prevent scripts from writing to critical files, but it can just as easily stop a webmaster from modifying his own files. FTP users have different permissions from the Apache server, so programmers must take caution whenever they are writing files out to the system.

Part 2 – Safe Mode:

PHP provides a level of security for shared systems called Safe Mode. It restricts certain functions and sets a directory that the PHP scripts can access. While PHP Group calls it “architecturally incorrect” to solve at the PHP level, it is still provided up to PHP 5 (PHP 6 will remove Safe Mode).

To enable Safe Mode, edit /etc/php.ini and edit the following lines:

safe_mode = On

open_basedir = /home/apache2/htdocs

display_errors = On

disable_functions = exec

Restart Apache to use these settings. (Ideally we would not turn on display_errors – hackers could use such knowledge to their benefit, but it is good to show why PHP is not executing certain code)

Now visit our scripts and see what they do.

http://localhost/cgi-bin/php/grabfile.php

http://localhost/cgi-bin/php/newfile.php

Q1.10: Do we get any return value from executing whoami? Why or why not?

Q1.11: Can we execute useradd? Why or why not?

Q1.12: Can we read the /etc/passwd file? Why or why not?

Q1.13: Can we generate a newfile.txt? Why or why not?

Create a new test.php and put in the following code

<?

include(‘grabfile.php’);

?>

Change the permissions on this file to our FTP user

chown ftpuser:ftpuser test.php

Execute test.php in your browser.

Q1.14: What happens when our script tries to include another PHP script (grabfile.php) owned by root?

Q1.15: How does this help security (especially on a shared user server)?

Go ahead and disable safe mode (undo your php.ini changes) before heading to the next section.
Section 2: PHP CGI & suPHP