COMMAND
wwwboard.pl
SYSTEMS AFFECTED
Systems using wwwboard.pl
PROBLEM
Sam found following. The commonly used wwwboard.pl program,
available for free from www.worldwidemart.com, is a suite that
appears to not have security as a serious consideration in its
design. Not only does the default location of passwords in the
wwwadmin.pl program allow anyone on the internet to perform
dictionary attacks on the board admin's password, there is
another, more subtle DOS attack. There is no input checking done
on the list of articles which a given article is a followup to.
This allows us to give it invalid input such that we can clobber
files that the web server has write permissions to.
For example, this HTML snippit, when read by Netscape (and the
button is pushed), will clobber articles 1 to 5 on the wwwboard
at some.poor.host.
<form method=POST action="http://some.poor.host/cgi-bin/wwwboard.pl">
<input type=hidden name="followup" value="1,2,3,4,5,|.|">
<input type=submit value="Clobber web board">
</form>
The included patch patches wwwboard.pl against this attack.
wwwboard.pl also does not log the IP that posts agiven message to
the board.
SOLUTION
Patch for wwwboard.pl (which requires perl5 to run) follows:
*** wwwboard.patch.pl Thu Sep 3 13:14:46 1998
--- wwwboard.pl Thu Sep 3 13:17:47 1998
***************
*** 1,4 ****
! #!/usr/local/bin/perl
##############################################################################
# WWWBoard Version 2.0 ALPHA 2 #
# Copyright 1996 Matt Wright mattw@worldwidemart.com #
--- 1,4 ----
! #!/usr/local/bin/perl -T
##############################################################################
# WWWBoard Version 2.0 ALPHA 2 #
# Copyright 1996 Matt Wright mattw@worldwidemart.com #
***************
*** 82,88 ****
sub get_number {
open(NUMBER,"$basedir/$datafile");
! $num = <NUMBER>;
close(NUMBER);
if ($num == 99999) {
$num = "1";
--- 82,90 ----
sub get_number {
open(NUMBER,"$basedir/$datafile");
! my($n) = <NUMBER>;
! $n =~ /(\d+)/;
! $num = $1;
close(NUMBER);
if ($num == 99999) {
$num = "1";
***************
*** 132,138 ****
if ($FORM{'followup'}) {
$followup = "1";
! @followup_num = split(/,/,$FORM{'followup'});
$num_followups = @followups = @followup_num;
$last_message = pop(@followups);
$origdate = "$FORM{'origdate'}";
--- 134,146 ----
if ($FORM{'followup'}) {
$followup = "1";
! my($item);
! my(@list) = split(/,/,$FORM{'followup'});
! @followup_num = ();
! foreach $item (@list) {
! $item =~ /(\d+)/;
! push(@followup_num,$1);
! }
$num_followups = @followups = @followup_num;
$last_message = pop(@followups);
$origdate = "$FORM{'origdate'}";
A better and much simpler solution is to simply rip the &check_url
subroutine from Matt Wright's FormMail.pl script and use that
instead. Not only does it fix this security hole, but it also
solves any other problems or worries associated with remote
execution of the wwwboard.pl script.
----------begin patch----------
Patch (ripped directly from Matt Wright's ForMail.pl)
-----------------------------------------------------
In the "Define Variables" section add:
-----
# security fix for post deletion
# check http://worldwidemart.com/scripts/ for more details
@referers = ('www.ncsu.edu','152.1.2.244');
-----
In the section that calls the subroutines right after "Configure
Options" add the following:
-----
# Check Referring URL - remote post security fix
&check_url;
-----
At the beginning of the subroutines, add the following:
-----
# security fix for remote post deletion
sub check_url {
# Localize the check_referer flag which determines if user is valid. #
local($check_referer) = 0;
# If a referring URL was specified, for each valid referer, make sure #
# that a valid referring URL was passed to FormMail. #
if ($ENV{'HTTP_REFERER'}) {
foreach $referer (@referers) {
if ($ENV{'HTTP_REFERER'} =~ m|https?://([^/]*)$referer|i) {
$check_referer = 1;
last;
}
}
}
else {
$check_referer = 1;
}
# If the HTTP_REFERER was invalid, send back an error. #
if ($check_referer != 1) { &error('bad_referer') }
}
-----
In the "error" subroutine, add the following, or roll your own:
-----
# error message to print out to ppl trying to delete posts via patched remote post exploit
elsif ($error eq 'bad_referer') {
print "<html><head><title>Nice try, script kiddy</title></head>\n";
print "<body>Nice try, script kiddy. No posting from remote URLs.</body></html>\n";
exit;
}
-----
Quick patch to write the IP to the HTML documents created. Add
this in the "Define Variables" section:
$ipaddy = $ENV{'REMOTE_ADDR'};
Then, just tack it $ipaddy on after all instances of $name in the
new_file subroutine.