Skip to content

Commit 72648af

Browse files
authored
Fix SMB2 compoud response signing (#1834)
* Fix SMB2 compoud response signing Fix the signing the logic when responding with an SMB2 compount response. The signature will include the padding of each compound element and include the next offset value before signing the data. * Pad all SMB2 packets, even the last in a compound response
1 parent 2d2e562 commit 72648af

File tree

1 file changed

+17
-21
lines changed

1 file changed

+17
-21
lines changed

impacket/smbserver.py

+17-21
Original file line numberDiff line numberDiff line change
@@ -4403,10 +4403,11 @@ def signSMBv1(self, connData, packet, signingSessionKey, signingChallengeRespons
44034403
packet['SecurityFeatures'] = m.digest()[:8]
44044404
connData['SignSequenceNumber'] += 2
44054405

4406-
def signSMBv2(self, packet, signingSessionKey):
4406+
def signSMBv2(self, packet, signingSessionKey, padLength=0):
44074407
packet['Signature'] = b'\x00' * 16
44084408
packet['Flags'] |= smb2.SMB2_FLAGS_SIGNED
4409-
signature = hmac.new(signingSessionKey, packet.getData(), hashlib.sha256).digest()
4409+
packetData = packet.getData() + b'\x00' * padLength
4410+
signature = hmac.new(signingSessionKey, packetData, hashlib.sha256).digest()
44104411
packet['Signature'] = signature[:16]
44114412
# print "%s" % packet['Signature'].encode('hex')
44124413

@@ -4624,34 +4625,29 @@ def processRequest(self, connId, data):
46244625
else:
46254626
respPacket['Data'] = str(respCommand)
46264627

4627-
if connData['SignatureEnabled']:
4628-
self.signSMBv2(respPacket, connData['SigningSessionKey'])
4629-
46304628
packetsToSend.append(respPacket)
46314629
else:
46324630
# The SMBCommand took care of building the packet
46334631
packetsToSend = respPackets
46344632

46354633
if isSMB2 is True:
4636-
# Let's build a compound answer
4637-
finalData = b''
4638-
i = 0
4639-
for i in range(len(packetsToSend) - 1):
4640-
packet = packetsToSend[i]
4641-
# Align to 8-bytes
4642-
padLen = (8 - (len(packet) % 8)) % 8
4643-
packet['NextCommand'] = len(packet) + padLen
4634+
# Let's build a compound answer and sign it
4635+
finalData = []
4636+
totalPackets = len(packetsToSend)
4637+
for idx, packet in enumerate(packetsToSend):
4638+
padLen = -len(packet) % 8
4639+
if idx + 1 < totalPackets:
4640+
packet['NextCommand'] = len(packet) + padLen
4641+
4642+
if connData['SignatureEnabled']:
4643+
self.signSMBv2(packet, connData['SigningSessionKey'], padLength=padLen)
4644+
46444645
if hasattr(packet, 'getData'):
4645-
finalData += packet.getData() + padLen * b'\x00'
4646+
finalData.append(packet.getData() + padLen * b'\x00')
46464647
else:
4647-
finalData += packet + padLen * b'\x00'
4648+
finalData.append(packet + padLen * b'\x00')
46484649

4649-
# Last one
4650-
if hasattr(packetsToSend[len(packetsToSend) - 1], 'getData'):
4651-
finalData += packetsToSend[len(packetsToSend) - 1].getData()
4652-
else:
4653-
finalData += packetsToSend[len(packetsToSend) - 1]
4654-
packetsToSend = [finalData]
4650+
packetsToSend = [b"".join(finalData)]
46554651

46564652
# We clear the compound requests
46574653
connData['LastRequest'] = {}

0 commit comments

Comments
 (0)