miketeo / pysmb

pysmb is an experimental SMB/CIFS library written in Python. It implements the client-side SMB/CIFS protocol (SMB1 and SMB2) which allows your Python application to access and transfer files to/from SMB/CIFS shared folders like your Windows file sharing and Samba folders.
Other
341 stars 94 forks source link

Error in CreateRequest for files with some unicode characters #170

Open theoharr opened 4 years ago

theoharr commented 4 years ago

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

miketeo commented 4 years ago

Fixed in pysmb 1.2.5