lsa_string/lsa_stringlarge null terminator and buffer size

View: New views
2 Messages — Rating Filter:   Alert me  

lsa_string/lsa_stringlarge null terminator and buffer size

by Matthieu Patou-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Dear all,

I find some strange things while creating patch for netlogon dissector
for wireshark I think it can (or lead already) to problems.

Samba is using type lsa_string and lsa_stringlarge for mapping the type
RPC_UNICODE_STRING as it used in MS-NRPC (but certainly not only here).
I guess that large is used when we want to have size > len (in order to
include null terminators), windows only use the same type but sometimes
len=size sometimes not, cf. Wkst Os entry of packet 13 (value Windows XP
Pro). Usually for the latter case it's indicated in the spec that the
string is null terminated, for instance with this entry which is OsName
described page 38 it is the case.

After a few chat on IRC and reading the idl for netlogon I have the
impression samba on reads the number of byte indicated by len (because
it's a lsa_string). In this case reading or not those bytes is harmless
because the next string is an empty dummy string but what would happen
if it wasn't the case ? the read is shifted by 2 bytes.
In the particular example of this call to GetDomainInfo is tomorrow the
dummy 3 entry starts to be used the Max Count and Actual Count will be
multiplied by 2^16 if I'm not wrong ...

It seems that the problem don't only appear in the case microsoft =>
samba but also in the opposite.
If we have a look at the Server Attribute of frame 40 (value TEST),
which corresponds to the "Logon server" attribute page 14 of MS-PAC or
page 57 of MS-NRPC is not stated to be null terminated, I think so that
len should be equal to size. It's not the case (first problem).
But what even worse is that samba4 advertise that the data can occupy 10
bytes where in fact in just use 8 (no terminators). I do not know the
heuristic of Windows but it can clearly break something (well at least
my dissector was broken for a 1/2 hours) if he really read the whole
thing ... (byte shifting).

Find attached the keytab of the workstation and the capture (you'll need
a recent wireshark svn with my patch for netlogon decryption in order to
see the traffic.

Matthieu



rpc (14K) Download Attachment
smb400001.keytab (94 bytes) Download Attachment

Re: lsa_string/lsa_stringlarge null terminator and buffer size

by Michael B Allen :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Thu, Jul 9, 2009 at 12:57 PM, Matthieu
Patou<mat+Informatique.Samba@...> wrote:

> Dear all,
>
> I find some strange things while creating patch for netlogon dissector for
> wireshark I think it can (or lead already) to problems.
>
> Samba is using type lsa_string and lsa_stringlarge for mapping the type
> RPC_UNICODE_STRING as it used in MS-NRPC (but certainly not only here).
> I guess that large is used when we want to have size > len (in order to
> include null terminators), windows only use the same type but sometimes
> len=size sometimes not, cf. Wkst Os entry of packet 13 (value Windows XP
> Pro). Usually for the latter case it's indicated in the spec that the string
> is null terminated, for instance with this entry which is OsName described
> page 38 it is the case.

Hi Matthieu,

Null terminatiors and the size / len of a string are two completely
different things.

Also, the strings you're asking about are not really LSA_STRING. Samba
just calls them that because that IDL was developed over a period of
many years through network analysis and no one really knew what things
were called at the time. As it turns out the real type is
UNICODE_STRING which has the IDL:

  typedef struct _UNICODE_STRING
      USHORT Length;
      USHORT MaximumLength;
      [size_is(MaximumLength / 2),length_is(Length / 2)] USHORT *Buffer;
  } UNICODE_STRING;

So Length is the length of the number of bytes of the string that
represent text (which might include a null term). The MaximumLength
(which is what you call size) is the size in bytes of the buffer that
the string is in. Buffer is a pointer to a conformant array which also
has it's own size and length which has the same meaning as
MaxiumumLength and Length. Of course this is all rather redundant and
confusing because the UNICODE_STRING data structure is also a C
language level type used by the OS but the IDL has to describe how to
transform the that data structure into NDR so it ends up encoding
conformance information twice.

Anyway, none of the above has anything to do with null termination.
After you decode the NDR and ultimately get a string, it will either
have a trailing 0 byte or not. Whether or not the string is null
terminated is defined in the documentation on a
structure-by-structure, field-by-field basis like OsName in
NETLOGON_WORKSTATION_INFO you mentioned.

I actually know very little about PIDL and the WireShark dissectors so
I don't know where they handle UNICODE_STRING null terminators. In my
code, I always deal with it outside of the NDR / DCERPC layer. For
example, in Java we have a UnicodeString class that takes the
UNICODE_STRING structure and a "boolean zterm" parameter that
indicates that the string is or is not be null terminated. This way
users just get a standard Java String.

> After a few chat on IRC and reading the idl for netlogon I have the
> impression samba on reads the number of byte indicated by len (because it's
> a lsa_string). In this case reading or not those bytes is harmless because
> the next string is an empty dummy string but what would happen if it wasn't
> the case ? the read is shifted by 2 bytes.
> In the particular example of this call to GetDomainInfo is tomorrow the
> dummy 3 entry starts to be used the Max Count and Actual Count will be
> multiplied by 2^16 if I'm not wrong ...

Again, I'm not really sure how WireShark dissectors handle
UNICODE_STRING but if the documentation says that a string is zero
terminated (or better still, you look at the "wire" and see the Length
includes two extra 0 bytes) then you will need to subtract 2 bytes
from Length when converting the string from UTF-16LE to UTF-8. If this
is all something handled by PIDL using an IDL extension (which sounds
like something PIDL would do), then you'll need to adjust the IDL.

I use WireShark all the time and the NETLOGON protocol is important to
one of my products. It's a great tool. Keep up the good work!

Mike

--
Michael B Allen
Java Active Directory Integration
http://www.ioplex.com/