Skip to content

Commit

Permalink
Fix SMB2 compoud response signing
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jborean93 committed Jan 7, 2025
1 parent 2d2e562 commit 0704387
Showing 1 changed file with 18 additions and 21 deletions.
39 changes: 18 additions & 21 deletions impacket/smbserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -4403,10 +4403,11 @@ def signSMBv1(self, connData, packet, signingSessionKey, signingChallengeRespons
packet['SecurityFeatures'] = m.digest()[:8]
connData['SignSequenceNumber'] += 2

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

Expand Down Expand Up @@ -4624,34 +4625,30 @@ def processRequest(self, connId, data):
else:
respPacket['Data'] = str(respCommand)

if connData['SignatureEnabled']:
self.signSMBv2(respPacket, connData['SigningSessionKey'])

packetsToSend.append(respPacket)
else:
# The SMBCommand took care of building the packet
packetsToSend = respPackets

if isSMB2 is True:
# Let's build a compound answer
finalData = b''
i = 0
for i in range(len(packetsToSend) - 1):
packet = packetsToSend[i]
# Align to 8-bytes
padLen = (8 - (len(packet) % 8)) % 8
packet['NextCommand'] = len(packet) + padLen
# Let's build a compound answer and sign it
finalData = []
totalPackets = len(packetsToSend)
for idx, packet in enumerate(packetsToSend):
padLen = 0
if idx + 1 < totalPackets:
padLen = -len(packet) % 8
packet['NextCommand'] = len(packet) + padLen

if connData['SignatureEnabled']:
self.signSMBv2(packet, connData['SigningSessionKey'], padLength=padLen)

if hasattr(packet, 'getData'):
finalData += packet.getData() + padLen * b'\x00'
finalData.append(packet.getData() + padLen * b'\x00')
else:
finalData += packet + padLen * b'\x00'
finalData.append(packet + padLen * b'\x00')

# Last one
if hasattr(packetsToSend[len(packetsToSend) - 1], 'getData'):
finalData += packetsToSend[len(packetsToSend) - 1].getData()
else:
finalData += packetsToSend[len(packetsToSend) - 1]
packetsToSend = [finalData]
packetsToSend = [b"".join(finalData)]

# We clear the compound requests
connData['LastRequest'] = {}
Expand Down

0 comments on commit 0704387

Please sign in to comment.