miketeo/pysmb

Error in CreateRequest for files with some unicode characters

theoharr opened this issue · 1 comments

I was trying to access some files with emoji characters on a Windows 2016 Server. In my test program I was doing:

sec_desc = smbconn.getSecurity(conn['share'], '👽.txt')

and receiving the following error:

smb.smb_structs.OperationFailure: Failed to get the security descriptor of 👽.txt on TEMP: Unable to open file or directory
==================== SMB Message 0 ====================
SMB Header:
-----------
Command: 0x05 (SMB2_COM_CREATE)
Status: 0x00000000
Flags: 0x00
PID: 8442
MID: 17
TID: 5
Data: 68 bytes
b'390000000200000000000000000000000000000000000000890012000000000007000000010000000000000078000a0000000000000000003dd87ddc2e00740078007400'
SMB Data Packet (hex):
----------------------
b'fe534d4240000000000000000500000000000000000000001100000000000000fa200000050000007500002c004c000000000000000000000000000000000000390000000200000000000000000000000000000000000000890012000000000007000000010000000000000078000a0000000000000000003dd87ddc2e00740078007400'
==================== SMB Message 1 ====================
SMB Header:
-----------
Command: 0x05 (SMB2_COM_CREATE)
Status: 0xC0000034
Flags: 0x01
PID: 8442
MID: 17
TID: 5
Data: 9 bytes
b'090000000000000000'
SMB Data Packet (hex):
----------------------
b'fe534d4240000000340000c00500010001000000000000001100000000000000fa200000050000007500002c004c000000000000000000000000000000000000090000000000000000'

Took a wireshark capture to see whats going on and saw:

image

Looks like we are missing the trailing t. Its actually in the payload ... but but the blob length is 10 (instead of 12) ... so the last character gets ignored.

I think the problem is the the alien emoji requires 4 bytes (instead of 2) to encode in UTF-16LE. So blob length calculation is incorrect in this example. I hacked up a fix and this seems to work:

diff --git a/python3/smb/smb2_structs.py b/python3/smb/smb2_structs.py
index 2246ab8..1ba0b4d 100644
--- a/python3/smb/smb2_structs.py
+++ b/python3/smb/smb2_structs.py
@@ -370,6 +370,7 @@ class SMB2CreateRequest(Structure):

     def prepare(self, message):
         buf = self.filename.encode('UTF-16LE')
+        buf_len = len(buf)  # FIX
         if self.create_context_data:
             n = SMB2Message.HEADER_SIZE + self.STRUCTURE_SIZE + len(buf)
             if n % 8 != 0:
@@ -397,7 +398,8 @@ class SMB2CreateRequest(Structure):
                                    self.create_disp,
                                    self.create_options,
                                    SMB2Message.HEADER_SIZE + self.STRUCTURE_SIZE,  # NameOffset
-                                   len(self.filename)*2,    # NameLength in bytes
+                                   buf_len,  # FIX
+                                   # len(self.filename)*2,    # NameLength in bytes
                                    create_context_offset,   # CreateContextOffset
                                    len(self.create_context_data)   # CreateContextLength
                                   ) + buf

image

Fixed in pysmb 1.2.5