IkonBoard 3.1.2a arbitrary command execution
The IkonBoard 3.1.1 arbitrary command execution bug described in:
http://www.securityfocus.com/archive/1/317234
is also present in IkonBoard version 3.1.2a.
I have a full working exploit, which I'll publish next week.
Suggested fix
=============
Make the following two changes to the file Sources/Lib/FUNC.pm on the web
server:
On line 104 of Sources/Lib/FUNC.pm, replace the line:
$sid =~ s/^(\d+)$/$1/;
with the line:
$sid =~ s/^(\d+)$/$1/ or die 'invalid sid value';
and on line 192 of Sources/Lib/FUNC.pm, replace the line:
$iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'} =~ s/^([\d\w]+)$/$1/;
with the two lines:
$iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'} =~ s/^([\d\w]+)$/$1/
or die 'invalid lang cookie value';
Alternatively, upload and run the following CGI script. It will attempt to
make the required changes for you.
--------------8<----------------------8<----------------------8<---------------
#!/usr/bin/perl -w --
#
# ibfix.cgi
#
# This CGI attempts to fix a security problem in either IkonBoard 3.1.1 or
# IkonBoard 3.1.2a, by modifying Source/Lib/FUNC.pm on the web server.
#
# Instructions: Upload ibfix.cgi to the same directory as ikonboard.cgi and
# run ibfix.cgi from a web browser. Delete ibfix.cgi when done.
#
# THIS SCRIPT IS DISTRIBUTED WITH NO WARRANTY WHATSOEVER. YOU USE IT ENTIRELY
# AT YOUR OWN RISK. IT HAS HAD VERY LITTLE TESTING AND MAY NOT WORK FOR YOU.
#
# Nick Cleaton <nick@xxxxxxxxxxx>
#
###############################################################################
use strict;
my $file = find_cgi_bin() . "/Sources/Lib/FUNC.pm";
my $tmp = "$file.ibfixtmp";
my $save = "$file.ibfixsave";
result("FAILED: FUNC.pm not found at '$file'") unless -e $file;
open OLD, "<$file" or result("FAILED: unable to read $file");
open NEW, ">$tmp" or result("FAILED: unable to create $tmp: $!");
my $s =q!$sid =~ s/^(\d+)$/$1/!;
my $l =q!$iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'} =~ s/^([\d\w]+)$/$1/!;
my $sidhit = 0;
my $lanhit = 0;
while(<OLD>) {
$lanhit++ if s/^(\s*\Q$l\E);/$1 or die 'invalid lang cookie value';/;
$sidhit++ if s/^(\s*\Q$s\E);/$1 or die 'invalid sid value';/;
print NEW $_;
}
close NEW or result("FAILED: unable to close $tmp: $!");
close OLD;
if ( $sidhit == 0 and $lanhit == 0 ) {
unlink $tmp;
result("OK: no vulnerable code found, nothing to do");
}
elsif ( $sidhit == 1 and $lanhit == 1 ) {
rename $file, $save or result("FAILED: unable to rename $file to $save: $!");
rename $tmp, $file or result("FAILED: unable to rename $tmp to $file: $!");
result("OK: vulnerable code found and fixed");
}
else {
unlink $tmp;
result("FAILED: unable to identify the code to replace");
}
sub find_cgi_bin {
foreach my $env (qw(SCRIPT_FILENAME PATH_TRANSLATED)) {
my $cgibin = $ENV{$env} or next;
$cgibin =~ s#[/\\][^/\\]+$## or next;
return $cgibin;
}
result("FAILED: unable to determine my own location");
}
sub result {
my ($message) = @_;
print "Content-type: text/plain\r\n\r\nibfix $message\n";
if ( $message =~ /^FAIL/ ) {
print "\nServer Environment:\n\n", map "$_ => $ENV{$_}\n", keys %ENV;
}
exit 0;
}
--------------8<----------------------8<----------------------8<---------------
Detection
=========
This test script causes a syntax error in a perl eval() in a vulnerable
IkonBoard installation on a remote web server:
--------------8<----------------------8<----------------------8<---------------
#!/usr/bin/perl -w
use strict;
my $HOST = 'www.example.com';
my $PORT = 80;
my $PATH = '/cgi-bin/ikonboard.cgi';
use IO::Socket;
my $sock = IO::Socket::INET->new("$HOST:$PORT") or die "connect: $!";
$sock->print(
"GET $PATH HTTP/1.1\r\n",
"Host: $HOST\r\n",
"Cookie: lang=%2E%00%22\r\n",
"Connection: close\r\n",
"\r\n"
) or die "write: $!";
print while <$sock>;
--------------8<----------------------8<----------------------8<---------------
If your IkonBoard installation is vulnerable then you will see something like:
Can't find string terminator '"' anywhere before EOF
in the middle of the output produced when running this script against it. If
my suggested fix is in place then you should see:
invalid lang cookie value
in the middle of the output instead.
--
Nick Cleaton
nick@xxxxxxxxxxx