[cifs-protocol] Cannot uncompress SMB3 LZ77 payload

Matthieu Suiche msuiche at gmail.com
Thu Jul 4 19:52:03 UTC 2019


Isn't it using the LZXPRESS algorithm instead?

On Thu, Jul 4, 2019, 8:14 PM Aurélien Aptel via cifs-protocol <
cifs-protocol at lists.samba.org> wrote:

>
> 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)
>
>
> _______________________________________________
> cifs-protocol mailing list
> cifs-protocol at lists.samba.org
> https://lists.samba.org/mailman/listinfo/cifs-protocol
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.samba.org/pipermail/cifs-protocol/attachments/20190704/33b763f3/attachment.htm>


More information about the cifs-protocol mailing list