[cifs-protocol] Cannot uncompress SMB3 LZ77 payload

Aurélien Aptel aaptel at suse.com
Thu Jul 4 17:55:05 UTC 2019


Hello,

I've been able to trigger a LZ77 compressed Read response against the latest
Windows Server 2019 but I am unable to decompress it.

Request
=======

SMB2 (Server Message Block Protocol version 2)
    [....]
    Read Request (0x08)
        StructureSize: 0x0031
            0000 0000 0011 000. = Fixed Part Length: 24
            .... .... .... ...1 = Dynamic Part: True
        Padding: 0x00
        Flags: 0x02, Compressed
            .... ...0 = Unbuffered: Client is NOT asking for UNBUFFERED read
            .... ..1. = Compressed: Client is asking for COMPRESSED data
        Read Length: 131072
        File Offset: 0
        GUID handle File: a
            File Id: 00000012-0004-0000-0100-000004000000
            [Frame handle opened: 52]
        Min Count: 0
        Channel: None (0x00000000)
        Remaining Bytes: 0
        Blob Offset: 0x00000000
        Blob Length: 0
        Channel Info Blob: NO DATA


Response
========

0000  fc 53 4d 42 00 00 02 00  02 00 00 00 50 00 00 00   .SMB.... ....P...
0010  fe 53 4d 42 40 00 02 00  00 00 00 00 08 00 0a 00   .SMB at ... ........
0020  01 00 00 00 00 00 00 00  07 00 00 00 00 00 00 00   ........ ........
0030  ff fe 00 00 01 00 00 00  35 00 00 00 00 10 00 00   ........ 5.......
0040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
0050  11 00 50 00 00 00 02 00  00 00 00 00 00 00 00 00   ..P..... ........
0060  ff ff ff 7f ff 07 00 0f  ff 00 00 fc ff 01 00      ........ .......

NetBIOS Session Service
    Message Type: Session message (0x00)
    Length: 111
SMB2 (Server Message Block Protocol version 2)
    SMB2 Compression Transform Header
    ProtocolId: fc534d42
    OriginalSize: 131072
    CompressionAlgorithm: LZ77 (0x0002)
    Reserved: 0000
    Offset: 0x00000050


Let's look again and annotate...


0000  fc 53 4d 42 00 00 02 00  02 00 00 00 50 00 00 00   .SMB.... ....P...
      ^^^^^^^^^^^                          ^^^^^^^^^^^
 compression transform header            compressed data offset = 0x50


   SMB2 header follows                     READ
      vvvvvvvvvvv                          vvvvv
0010  fe 53 4d 42 40 00 02 00  00 00 00 00 08 00 0a 00   .SMB at ... ........
0020  01 00 00 00 00 00 00 00  07 00 00 00 00 00 00 00   ........ ........
0030  ff fe 00 00 01 00 00 00  35 00 00 00 00 10 00 00   ........ 5.......
0040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
0050  11 00 50 00 00 00 02 00  00 00 00 00 00 00 00 00   ..P..... ........
            ^^
  read data offset from SMB2 header is 0x50 again


0060  ff ff ff 7f ff 07 00 0f  ff 00 00 fc ff 01 00      ........ .......
      ^^
    compressed data starts here (0x10 + 0x50 = 0x60)

So the LZ77 compressed data is

    ff ff ff 7f ff 07 00 0f ff 00 00 fc ff 01 00

I've tried to decode it using [MS-XCA] 2.4.4 "Plain LZ77 Decompression"
[1] which has pseudo code that is easily runnable in python. I can
decode the examples on that page fine:

  >>> decode(bytes.fromhex(" ff ff ff 1f 61 62 63 17 00 0f ff 26 01"))
  bytearray(b'abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc'+
            b'abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc'+
            b'abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc'+
            b'abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc'+
            b'abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc')

But if I try to decode my compressed payload it is invalid:

  >>> decode(bytes.fromhex(" ff ff ff 7f ff 07 00 0f  ff 00 00 fc ff 01 00"))
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "lz.py", line 54, in decode
      raise Exception("error")

This corresponds to this line in the pseudo-code:

                     If MatchLength < 15 + 7
                        Return error.

And it fails in the very beggining after only outputting 1 byte
(ff). The uncompressed payload should be all 0xFF.

You can see and run the script online here [2].

So, any ideas on what I'm missing? Is the LZ77 encoding used in the
packet different? Am I missinterpreting some fields?

1: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-xca/34cb9ab9-5ce6-42d7-a518-107c1c7c65e7
2: https://ideone.com/7Lr6tN

Cheers,
-- 
Aurélien Aptel / SUSE Labs Samba Team
GPG: 1839 CB5F 9F5B FB9B AA97  8C99 03C8 A49B 521B D5D3
SUSE Linux GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah HRB 21284 (AG Nürnberg)




More information about the cifs-protocol mailing list