PhpBB Security

From Solstmas Wiki
Jump to navigation Jump to search

We have a large, old (over 10 years) community server where users are allowed to install (most) any software they like. phpBB has been a security challenge and we recently had a fairly serious problem with a highlight-worm finding an old phpBB install.


step 1: locate all installs of phpBB. Simple version for 2.0.x : "locate admin_board", chop off filename and admin/ off full path.

foreach install:

NOT USED step 2: grab db info from INSTALL/config.php - I decided against this to simplify it and I wasn't sure if I was going to get anything useful.

step 3: look for INSTALL/docs/CHANGELOG.html file , check version number in the html title tag

NOT USED step 4: compare version numbers from file against db. If different, log warning.

step 5 : check the version number against a known version number of latest release (unsure how to do this without hand codeing, on freebsd I appear to be able to look in /usr/ports/www/phpbb/Makefile

step 6: generate log of not-up-to-date installs and possibly email a warning if anything isnt up to date, send in email.

Unfortunately this has to be run as root because it needs to look in directories that are not necessarily viewable by me...


Ideally this would pull a list of softwares to check and a pull in some kind of config or perl to be able to check them, but that isn't going to happen today. Perhaps someone else out there has already written such a beast.


check_versions.pl 
#!/usr/bin/perl
#
# check_versions.pl looks for installs of phpBB on the system and prints messages
# about out-of-date installs it finds.
#
# Probably needs to run as root to look in other people's directories.
#
# works on freebsd only currently (gets canonical version number from ports dir)
# 

my @IgnoreRegexs;
push(@IgnoreRegexs, "/usr/local/www");


sub MyQuit()
{
    if (-f $TempFileFullPath) { system ("rm " . $TempFileFullPath); }
    exit;

}

sub IgnorePath($)
{ my ($PathToCheck) = @_;
  my $Rval = 0;
 foreach my $Ignore (@IgnoreRegexs) 
 {  
     if ($PathToCheck =~ /$Ignore/) 
     { $Rval = 1; 
       #print "ignoring: $PathToCheck\n"; 
       last;
     }

 }
  return $Rval;

}
sub MakeTmpFileName($)
{ my ($Base) = @_;

  my $Path = "/tmp/";
  my $Rval = "";
  for (my $i = 1; $i < 100; $i++)
  { my $TestFileName = $Path . $Base . "." . $i . ".txt";
      if (! -f $TestFileName) 
      { 
	  $Rval = $TestFileName;
	  last;
	  
      }
  }
  return $Rval;
}


my $i = 0;
my @LimitSet;
  foreach $arg1 (@ARGV)
  {	#print "Arg[$i] = $arg1\n";
	if ($arg1 =~ /^-i$/)
	{
	    #$CaseInsensitive = 1;
	#	print "CaseInsensitive\n";
	}
	else
	{
    $LimitSet[$#LimitSet+1] = $arg1;
	 }
	$i++;
  }

print "Check Versions Script\n";
my $Err = 0;
  if ($Err)
  {	PrintUsage();
	exit;
  }

print "Checking for  phpBB installs.\n";

$TempFileFullPath = MakeTmpFileName("check_versions");
if ($TempFileFullPath eq "")
{ print "Unable to create temp file??\n";
  print "FATAL ERROR\n";
  exit;
}

my $PortFile = "/usr/ports/www/phpbb/Makefile";
open PORT , "<" . $PortFile or die "Unable to open port file: $PortFile\n";

my $CanonicalVersion = "";
while (<PORT>)
{my $Line = $_;
 chop $Line;
 if ($Line =~ /PORTVERSION=\s*([^\s]+)/) { $CanonicalVersion = $1; last;}

}
print "Canonical Version from ports: $CanonicalVersion \n\n";



my $Command1 = "locate admin_board.php > $TempFileFullPath";
my $Locate = system($Command1);
open FILE, "<" . $TempFileFullPath;
while (<FILE>)
{ my $File1 = $_;
  chop $File1;
#  print "File: $File1 \n";
  if (IgnorePath($File1) ) { next;}
#  my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($File1);
  if (stat($File1) && -r $File1)
  {
      my $Path1 = $File1;
      $Path1 =~ s/\/[^\/]+\/admin_board.php$/\//;
      my $Conf = $Path1 . "config.php";
      my $Doc = $Path1 . "docs/CHANGELOG.html";
      
#      print "Found: $Path1 - $File1 \n";

      open CONF , "<" . $Conf or die "Unable to open conf file: $Conf\n";
      
      close CONF;
      my $Err = 0;
      open DOC , "<" . $Doc or $Err++;
      if ($Err) { print "Weird or incomplete install at : $Path1, can't find doc file for version, unable to continue.\n\n"; next;}
      my $DocFile;
      while (<DOC>) {  $DocFile .= $_;}
      my $Ver = "";
      if ($DocFile =~ /<title>\s*phpBB\s(.*)\s::.*<\/title>/i)
      {
	  $Ver = $1;
#	  print "Ver: $Ver\n";
      }
      close DOC;
 #     print "Found: $Conf \n $Doc \n";
      if ($Ver eq "") { print "Unable to find version\n"; }
      if ($Ver ne $CanonicalVersion) { 
	  print "Found phpBB install at $Path1\n";
	  print "WARNING : Not up to date : Version = $Ver\n\n"; 
      }

  }


}
MyQuit();