R
Robert Stelmack
I posted this message also at: comp.inforsystems.www.authoring.cgi, but
after one day it did not show up, so I try here since it both a CGI and a
Perl question.
I am trying to make my Perl CGI script secure. Our non-profit web site was
hacked and the index page changed. This in itself is just an annoyance, but
it could have just as easily to alter or delete any file.
The web host system administration was kind enough to look over some logs
and identified the method used to hack the site. This was do to a "bug" in
the script ~/www/cgi-bin/index.cgi This CGI script is something I built and
functionally does what I want it to, but obviously poorly written. I have
blocked the script for the time being with a chmod 000 to disallow any
access.
Here is the way that the system administrator said that the script was
compromised:
xxx.xxx.xxx.xxx - - [09/Jul/2004:06:07:43 -0500] "GET
/cgi-bin/index.cgi?path=|echo%20\"<html><head><title>H@ck3d!</title></head><
body%20bgcolor=black%20text=yellow><h1>Hacked!%20What%20such%20a%20weak%20si
te!%20Please%20fix%20this%20as%20soon%20as%20possible!%20Or%20your%20site%20
will%20be%20more%20vunerable!</h1><center><h3><i>Nowhere%20Man</i></h3></cen
ter></body></html>\"%20>%20../index.htm|
He said that I would need additional input checking to prevent this from
happening again.
Here is the script, pared down to show what it basically does. Yes, and
before anyone says anything: it is a crap script, I didn't RTFM, and there
is a better way to do it ;-)
#!/usr/bin/perl
open(STDERR,'>&STDOUT'); ## Assign error messages to STDOUT to view
$| = 1;
print "Content-Type: text/html\n\n"; #live feed to browser
push(@INC, "../"); ## Location of cgi-lib.pl (located in this directory)
require "cgi-lib.pl" || die "Can't find cgi-bin.pl REASON: $! ";
## Looks up the files in the passed directory name with the suffix ".dbf"
&ReadParse(*input);
$PATH = @input{'path'}; ## The Name of the DIRECTORY
print "<html><head><title>Index Page</title></head><body>";
{foreach $file (<$PATH/*.dbf>)
{
$_ = $file;
print "PWD for files found: $_<br>\n";
}
}
print "</body></html>";
I have read several Perl and security references and I would like to see if
this is all I need to do:
&ReadParse(*input);
$PATH = @input{'path'}; ## The Name of the DIRECTORY
if ( $PATH =~ /[`\$\\"';&>]/ ) {die} ## Die if special characters are used
Not sure if the reg expression is correct, but is this the input checking
the system administrator was referring to? Or, do you have a good generic
suggestion to prevent this type of hacking that a simple user could
implement?
There were other ways to secure the script, but many of then required system
administrative access that I don't have.
I will add the -w -T for the perl execution and the "use strict; use
warnings;" once I clean up the script and use some of the OOP in the CGI.pm
module. And I will try to understand the scope (ie. "my variable") and
properly code the variables.
I will also add this, as suggested by perlsec:
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safe
----------------------------------------
References used:
http://www.oreilly.com/catalog/cgi2/chapter/ch08.html
http://search.cpan.org/~jhi/perl-5.8.0/lib/CGI.pm
perlsec
after one day it did not show up, so I try here since it both a CGI and a
Perl question.
I am trying to make my Perl CGI script secure. Our non-profit web site was
hacked and the index page changed. This in itself is just an annoyance, but
it could have just as easily to alter or delete any file.
The web host system administration was kind enough to look over some logs
and identified the method used to hack the site. This was do to a "bug" in
the script ~/www/cgi-bin/index.cgi This CGI script is something I built and
functionally does what I want it to, but obviously poorly written. I have
blocked the script for the time being with a chmod 000 to disallow any
access.
Here is the way that the system administrator said that the script was
compromised:
xxx.xxx.xxx.xxx - - [09/Jul/2004:06:07:43 -0500] "GET
/cgi-bin/index.cgi?path=|echo%20\"<html><head><title>H@ck3d!</title></head><
body%20bgcolor=black%20text=yellow><h1>Hacked!%20What%20such%20a%20weak%20si
te!%20Please%20fix%20this%20as%20soon%20as%20possible!%20Or%20your%20site%20
will%20be%20more%20vunerable!</h1><center><h3><i>Nowhere%20Man</i></h3></cen
ter></body></html>\"%20>%20../index.htm|
He said that I would need additional input checking to prevent this from
happening again.
Here is the script, pared down to show what it basically does. Yes, and
before anyone says anything: it is a crap script, I didn't RTFM, and there
is a better way to do it ;-)
#!/usr/bin/perl
open(STDERR,'>&STDOUT'); ## Assign error messages to STDOUT to view
$| = 1;
print "Content-Type: text/html\n\n"; #live feed to browser
push(@INC, "../"); ## Location of cgi-lib.pl (located in this directory)
require "cgi-lib.pl" || die "Can't find cgi-bin.pl REASON: $! ";
## Looks up the files in the passed directory name with the suffix ".dbf"
&ReadParse(*input);
$PATH = @input{'path'}; ## The Name of the DIRECTORY
print "<html><head><title>Index Page</title></head><body>";
{foreach $file (<$PATH/*.dbf>)
{
$_ = $file;
print "PWD for files found: $_<br>\n";
}
}
print "</body></html>";
I have read several Perl and security references and I would like to see if
this is all I need to do:
&ReadParse(*input);
$PATH = @input{'path'}; ## The Name of the DIRECTORY
if ( $PATH =~ /[`\$\\"';&>]/ ) {die} ## Die if special characters are used
Not sure if the reg expression is correct, but is this the input checking
the system administrator was referring to? Or, do you have a good generic
suggestion to prevent this type of hacking that a simple user could
implement?
There were other ways to secure the script, but many of then required system
administrative access that I don't have.
I will add the -w -T for the perl execution and the "use strict; use
warnings;" once I clean up the script and use some of the OOP in the CGI.pm
module. And I will try to understand the scope (ie. "my variable") and
properly code the variables.
I will also add this, as suggested by perlsec:
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safe
----------------------------------------
References used:
http://www.oreilly.com/catalog/cgi2/chapter/ch08.html
http://search.cpan.org/~jhi/perl-5.8.0/lib/CGI.pm
perlsec