What We Will Cover
Log Tails
From Last Lab
Quiz Review
back to top
Introduction
- Need CGI for most Web sites
- Unfortunately, CGI is one of the largest security risks
- Risk comes from poor programming or poorly configured CGI environment
- Risks can be reduced if some safe guidelines are followed
back to top
11.1: Who to Run CGI As
Objectives
At the end of the lesson the student will be able to:
- Determine a safe user to run cgi as
|
- Any program is run with the permissions and access rights of the user account running the program
- Important to run the Web server as an unprivileged user
- Same is true for CGI programs and scripts
- They too have a user with various access rights associated with them
- Should be run as a user with very few privileges
back to top
11.1.1: CGI User
- Many Web servers do not have separate CGI users
- Web server itself runs the CGI programs
- User chosen to run CGI is almost more important than the Web server user
- CGI programs and scripts can be written to do anything imaginable
- Format the hard disk
- E-mail the password file
- Control the air conditioning of the building
- But only if the CGI user has permissions and access rights for these tasks
back to top
11.1.2: For Example
- How many people would allow the following CGI script on their Web server?
#!/usr/bin/perl
print "Content-type: text/plain\n\n";
print "Removing all files from the file system.\n";
print "Have a nice day!\n";
system("rm -rf /*");
This script runs the command rm -rf /*
- UNIX command to recursively remove all files and directories
- Equivalent to the Windows 95/98/NT or DOS command
deltree \
- Deletes all files in the Web server host’s file system
User running this script would require permission to remove all the files
Only the superuser should have this privilege
- Superuser is one user you should not run CGI as
CGI programs often require a great deal of functionality
- Query or update a database,
- Read or write to files
- Send e-mail
- ...
CGI user will require access rights and permissions to perform these tasks
back to top
11.1.3: Modifying CGI User
- Modifying CGI user will depend on your Web server software
- Apache provides a utility called suEXEC to change the CGI user
- Similar programs, such as cgiwrap, also exist
- Sometimes known as "wrapper programs"
- Modifies the user a CGI program runs as prior to its execution
- Allows users to run CGI with their own permissions rather than as Web server
back to top
Lab Exercise 11.1
Use the next 15 minutes to complete the following.
- Start a text file named exercise11.txt
Will be adding to this file during the lesson -- save it often.
- Prepare the exercise header as described in the HowTo on submitting exercises
- Label this exercise: Lab 11.1
- Answer the following questions.
Determine a Safe User to Run CGI As
Note: You will get different results than the textbook reports because we have installed Apache as a user with no permissions to any files except the actual Web server. Also, Apache is started by the superuser. As a result, I have changed some of the exercises.
Save the following CGI script as hello.pl in the CGI directory of Apache: /usr/local/apache2/cgi-bin. Make sure the script is executable by everyone.
#!/usr/bin/perl
print "Content-Type: text/html\n\n";
print "<html>\n";
print "Hello CGI World!\n";
print "</html>\n";
Download it here.
If not already started, start Apache or IIS. Run the above script by clicking the link or typing in the address bar of the browser:
localhost/cgi-bin/hello.pl
- What happens when the script is run?
Change the permissions on the script to not be readable by everyone and rerun the script.
cd /usr/local/apache2/cgi-bin
chmod 750 hello.pl
- What happens when the script is run?
Change the CGI user to be the same as the Web server user and rerun the script.
chown nobody hello.pl
- What happens when the script is run?
Optionally, you may write some simple CGI scripts that attempt to read, modify, or delete a file owned by the CGI/Web server user. If you decide to modify or delete any files, make sure to save copies of any files first. Make the scripts executable and accessible through CGI on the Web server. To run your scripts via the Web server, simply load the URL that references them.
- What happens when the scripts are run?
Use the following PERL script, or a similar script if you are not on a UNIX system, to answer the next question. For our classroom, save the script in cgi-bin and name it kill.pl.
#!/usr/bin/perl
#system("kill `ps -e | grep httpd | cut -d\" \" -f2`");
system("kill `ps -e | grep httpd` 2> /dev/null");
print "Content-type: text/html\n\n";
print "<HTML>\n";
print "<HEAD>\n";
print "<TITLE>Success</TITLE>\n";
print "</HEAD>\n";
print "<BODY>\n";
print "Script completed successfully.\n";
print "</BODY>\n";
print "</HTML>\n";
Download it here.
Make sure the script is executable by everyone.
cd /usr/local/apache2/cgi-bin
chmod 755 kill.pl
Run the script from the command line:
./kill.pl
- What happens to the Web server when you run the script?
Restart Apache or IIS and run the script from the browser:
localhost/cgi-bin/kill.pl
- What happens to the Web server when you run the script?
Repeat the same tests after changing the CGI user to that which the Web server runs as.
- What happens to the Web server when you run the script now?
back to top
11.2: Poor CGI Programming
Objectives
At the end of the lesson the student will be able to:
- Identify risks from poor programming
|
- Programs that successfully complete their intended task still may not be correct
- Many use poor programming practices that have potential security risks
- If you need to evaluate a script, try inputing extreme or even ridiculous values
- Will often cause the program to crash or have unintended side effects
- Crackers often try to exploit these types of bugs
back to top
Lab Exercise 11.2
Use the next 15 minutes to complete the following.
Label this exercise: Lab 11.2
Identify Risks from Poor Programming
Create a CGI script using the PERL code below and save it as "mail.pl" the CGI directory of your Web server.
Note: script modified by instructor.
Cannot find file: /home/edparr2/public_html/cis164/03s/supplements/mail.pl
Download it here.
Make sure the script is executable by everyone.
chmod 755 mail.pl
Create an motd file in /etc:
echo My message > /etc/motd
Use the following form to collect a mail address to use in this script. Use your logon (e.g. cis164) as your mail address for our classroom.
What happens when you submit your e-mail address via the form?
You can check your mail at the command prompt by typing: mail -u cis164. Use "n" to look at the mail, "d" to delete the mail, and "q" to quit the mail program.
mail -u cis164
...
n
...
d
...
q
What happens if you submit "yourLogon < /etc/passwd ; mail yourLogon"?
cis164 < /etc/passwd ; mail cis164
Create a CGI script using the PERL code below and save it as "getfile.pl" the CGI directory of your server.
Note: script modified by instructor.
#!/usr/bin/perl
%ARGS = ();
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
$buflen = length($buffer);
if ($buflen > 0) {
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack "C", hex($1)/eg;
$value =~ tr/+/ /;
$ARGS{$name} = $value;
}
}
print "Content-type: text/plain\n\n";
open(AFILE, "$ARGS{afile}");
while($line = <AFILE>) {
print $line;
};
close(AFILE);
Download it here.
Don't forget to set execute permissions.
chmod 755 getfile.pl
Use the following form to enter a filename into the script such as hello.pl
What does the CGI script return?
Now enter in a relative pathname that traverses back to the true root directory and then references a file.
../../../../etc/passwd
You should see the /etc/password file.
Why is a script such as getfile.pl a bad idea?
back to top
11.3: Tainted CGI Variables
Objectives
At the end of the lesson the student will be able to:
- Check for unsafe characters in CGI input
- Check for safe characters in CGI input
- Work around unsafe characters in CGI input
|
- Checking the format of input is a good programming practice
- For instance, most e-mail addresses have the form:
username@domainname
- Username and domainname may have letters a-z and A-Z, numbers, special characters such as "_"
- They do not include: ! $ % ; # * < > | & /
- Many of these symbols have special meanings to operating system shell
- Variables containing special interpreted characters are called tainted variables
- Tainted variables can cause all sorts of problems and are easily overlooked
- Crackers may use these special characters to exploit their special meaning
- Important that each CGI script and program check for tainted variables
- Must protect from any harm they may cause
- PERL version 5 or better has the "-T" option to automatically check the input for tainted variables
For Example
- The first line of a PERL script in Linux is:
#!/usr/bin/perl
/usr/bin is the path to the PERL interpreter
Here is a portion of a typical CGI script written in PERL:
#!/usr/bin/perl
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
$buflen = length($buffer);
if($buflen > 0) {
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$ARGS{$name} = $value;
}
}
To use the taint check, simply change the first line to:
#!/usr/bin/perl -T
If a variable contains a special shell interpreted character, PERL will now protect against it
If your CGI programming is done in C, BASIC, or a UNIX shell, you will want to explicitly check for taints
back to top
Lab Exercise 11.3
Use the next 15 minutes to complete the following.
Label this exercise: Lab 11.3
Check for Unsafe Characters in CGI Input
Create a CGI script using the PERL code below and save it as "readvars.pl" in the CGI directory of your Web server.
#!/usr/bin/perl
%ARGS = ();
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
$buflen = length($buffer);
if ($buflen > 0) {
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
$value =~ s/~!/ ~!/g;
$ARGS{$name} = $value;
}
}
print "Content-type: text/html\n\n";
print "<HTML>\n";
print "<HEAD>\n";
print " <TITLE>Tainted Variables</TITLE>\n";
print "</HEAD>\n";
print "<BODY>\n";
print "The variables received were:\n";
print "<PRE>\n";
print " NAME ==> VALUE\n\n";
foreach $name (var1, var2, var3) {
print " $name ==> $ARGS{$name}\n";
}
print "</PRE>\n";
print "The variables will be interpretted as:\n";
print "<PRE>\n";
print " NAME ==> VALUE\n\n";
foreach $name (var1, var2, var3) {
### TAINT-CHECK ###
print " $name ==> $ARGS{$name}\n";
}
print "</BODY>\n";
print "</HTML>\n";
Download it here.
Don't forget to set execute permissions.
chmod 755 readvars.pl
Use the following form to enter variable names into the script. Experiment with the form submitting different values.
Please submit three variables to be interpreted.
What does this CGI script do?
What happens when you submit a tainted CGI variable such as a$b?
Now add the following lines after the ### TAINT CHECK ### line:
# define unsafe chars
if($ARGS{$name} =~ /[!\$%;#*<>|&\/]/) {
$ARGS{$name} = "TAINTED";
}
What happens now when you submit input containing one of the defined unsafe characters (!,$,%,;,#,*,<,>,|,&,/)?
Check for Safe Characters in CGI Input
Replace the new lines of code you added to the PERL script in Exercise 11.3.1 with the following lines:
# define safe chars
unless($ARGS{$name} =~ /^[a-z,A-Z,0-9]/) {
$ARGS{$name} = "TAINTED";
}
What happens when you submit input containing one of the previously defined unsafe characters (!,$,%,;,#,*,<,>,|,&,/)?
What happens if you submit input that does not contain one of the newly defined safe characters (a-z,A-Z,0-9)?
Work Around Unsafe Characters in CGI Input
Replace the new lines of code you added to the PERL script in Exercise 11.3.2 with the following lines:
# escape unsafe chars
$ARGS{$name} =~ s/([!\$%;#\*<>\|&\/])/\\$1/g;
What happens when you submit input containing one of the previously defined unsafe characters (!,$,%,;,#,*,<,>,|,&,/)?
What is this newly added code doing to the interpretation of the variables?
back to top
11.4: Buffer Overflows
Objectives
At the end of the lesson the student will be able to:
- Describe what happens with a buffer overflow
|
- Both data and program instructions are stored together in memory
- Variables are given a location in memory to store any assigned data
- If the data type needs four bytes then four bytes of memory will be set aside for that variable

- If we assigned more than four bytes, it writes to adjacent memory

- This space could contain other variables, programs or nothing
- Some programming languages, such as Java, provide bounds checking to prevent this problem
- For other languages, such as C, we need to perform our own bounds checking
back to top
Lab Exercise 11.4
Use the next 10 minutes to complete the following.
Label this exercise: Lab 11.4
Understand What Happens with a Buffer Overflow
Copy the following C program into your /home/cis164 directory.
#include <stdio.h>
void displayit(char* str2) {
char buffer[20];
strcpy(buffer, str2);
printf("You Entered: %s\n",buffer);
}
main() {
char str1[100];
gets(str1);
displayit(str1);
exit(0);
}
Download it here.
Compile the code.
gcc buffer.c -o buffer
Run the code as follows:
./buffer
- What happens when you input a value longer than 20 characters?
- How can you fix this program?
Make the appropriate modifications to this program and recompile it.
#include <stdio.h>
void displayit(char* str2) {
char buffer[20];
if(strlen(str2) >= 20)
{
printf("Input too large\n");
exit(1);
}
strcpy(buffer, str2);
printf("You Entered: %s\n",buffer);
}
main() {
char str1[100];
gets(str1);
displayit(str1);
exit(0);
}
Download it here.
- What happens now when you input a value longer than 20 characters?
- What do you think could potentially happen if the memory being overwritten were the program’s instructions?
back to top
11.5: Other CGI Risks
Objectives
At the end of the lesson the student will be able to:
- Use referrers for added CGI protection
- Describe the risks of .cgi file extensions
|
- CGI has other risks than bugs in programs
- Configuration of CGI
- General use of CGI on the Web server
- How to label a file as a CGI script is one issue
- Another issue is how can we prevent other sites from calling our scripts and using our Web server’s resources
- CGI environment variables and HTML file HIDDEN variables that are passed to CGI scripts also have some concerns regarding security
- Will take a look at all of these and the risks they pose
back to top
11.5.1: What Constitutes a CGI Script?
- Not every executable file on the Web server is meant to be a CGI program
- Different ways of specifying which files should be treated as CGI programs and scripts
- Each method has different risks involved
back to top
11.5.2: cgi-bin Method
- Most common method for classifying CGI scripts is a
/cgi-bin directory
- Typically an alias to a directory off the server root directory
- Any file in this directory or its subdirectories is automatically considered a CGI program
- The file must be a program of some sort
- Must allow the CGI user read and execute access before it can be run
- Standard convention is to name a directory of this type
cgi-bin
- But it could effectively be named anything
back to top
11.5.3: .cgi Extension Method
- Another method is to allow all files with a certain extension to be treated as CGI programs
- Standard convention is to use a
.cgi file extension as a CGI security CGI program
- The
.cgi extension is just the standard convention
- Any file extension or multiple extensions could be used
- One of the issues that arise when using the
.cgi file extension method is what to do when there exists a generic CGI program that is used by many forms
- For instance, a very popular CGI script is the standard formmail script
- Does nothing more than process the form data and then e-mail it to someone
- Would not want to have multiple copies residing in many directories
- Whenever a change was needed, would have to change them all
- Textbook suggests using hidden variables
back to top
Lab Exercise 11.5
Use the next 15 minutes to complete the following.
Label this exercise: Lab 11.5
Use Referrers for Added CGI Protection
Create a CGI script using the PERL code below and save it as "referer.pl" in the CGI directory of your Web server. Don't forget to set execute permissions.
@referers = (
'nonexistent.host.somedomain.com',
);
$permission = 0;
if($ENV{'HTTP_REFERER'}) {
foreach $referer (@referers) {
if($ENV{'HTTP_REFERER'} =~ m/https?://([^/]*)$referer/i) {
$permission = 1;
last;
}
}
}
if (! $permission) {
print "Content-type: text/plain\n\n";
print "Permission to use this script denied.\n";
exit;
}
Download it here.
Save a copy of one of the source HTML files of the form available here to your local machine. A second example is available here. Edit the file and remove the third HIDDEN variable, named rcpt. Load the modified HTML file into your Web browser and submit a completed form.
- What is different about the response?
- What happens now when you try to submit the form using your saved copy of the HTML file?
Older Web clients may not send referrer information.
- What would happen to the script if a Web client did not send the referrer information?
Understand the Risks of .cgi File Extensions
Enable the use of .cgi file extensions for CGI scripts on your Web server. Create a simple CGI script in the document root with the correct extension.
- What happens when you load this file?
Modify the script slightly and save a backup copy of the original file with a .bak extension.
- What happens when you load the backup copy of the script?
back to top
Wrap Up
- When class is over, please shut down your computer
=> Logout => Shut Down
Due Next: N/A
- You may complete unfinished exercises at any time before the next class.
- Be sure to submit the file to the instructor before the beginning of the next class to receive credit.
- Instructions on submitting exercises are available from the HowTo's page.
back to top
Home
| WebCT
| Announcements
| Schedule
| Expectations
| Syllabus
| Help
| FAQ's
| HowTo's
| Links
Last Updated: 7/16/2003 4:45:44 PM
|