Skip to content

Commit

Permalink
Cosmetic changes to Kerberos and SMB (#4326)
Browse files Browse the repository at this point in the history
  • Loading branch information
gpotter2 committed Mar 19, 2024
1 parent c36f929 commit d832890
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 13 deletions.
23 changes: 14 additions & 9 deletions scapy/layers/kerberos.py
Expand Up @@ -1737,8 +1737,9 @@ def m2i(self, pkt, s):
# 24: KDC_ERR_PREAUTH_FAILED
# 25: KDC_ERR_PREAUTH_REQUIRED
return MethodData(val[0].val, _underlayer=pkt), val[1]
elif pkt.errorCode.val in [18, 41, 60]:
elif pkt.errorCode.val in [18, 29, 41, 60]:
# 18: KDC_ERR_CLIENT_REVOKED
# 29: KDC_ERR_SVC_UNAVAILABLE
# 41: KRB_AP_ERR_MODIFIED
# 60: KRB_ERR_GENERIC
return KERB_ERROR_DATA(val[0].val, _underlayer=pkt), val[1]
Expand Down Expand Up @@ -3309,9 +3310,6 @@ def GSS_WrapEx(self, Context, msgs, qop_req=0):
"""
if Context.KrbSessionKey.etype in [17, 18]: # AES
confidentiality = Context.flags & GSS_C_FLAGS.GSS_C_CONF_FLAG
# Concatenate the data
Data = b"".join(x.data for x in msgs if x.sign or x.conf_req_flag)
DataLen = len(Data)
# Build token
tok = KRB_InnerToken(
TOK_ID=b"\x05\x04",
Expand All @@ -3327,6 +3325,9 @@ def GSS_WrapEx(self, Context, msgs, qop_req=0):
if confidentiality:
# Confidentiality is requested (see RFC4121 sect 4.3)
# {"header" | encrypt(plaintext-data | filler | "header")}
# 0. Concatenate the data
Data = b"".join(x.data for x in msgs if x.conf_req_flag)
DataLen = len(Data)
# 1. Add filler
tok.root.EC = (-DataLen) % Context.KrbSessionKey.ep.blocksize
Data += b"\x00" * tok.root.EC
Expand All @@ -3350,12 +3351,14 @@ def GSS_WrapEx(self, Context, msgs, qop_req=0):
msglen = len(msg.data)
if msg.conf_req_flag:
msg.data = Data[offset : offset + msglen]
if msg.sign or msg.conf_req_flag:
offset += msglen
return msgs, tok
else:
# No confidentiality is requested
# {"header" | plaintext-data | get_mic(plaintext-data | "header")}
# 0. Concatenate the data
Data = b"".join(x.data for x in msgs if x.sign)
DataLen = len(Data)
# 1. Add first 16 octets of the Wrap token "header"
ToSign = Data
ToSign += bytes(tok)[:16]
Expand Down Expand Up @@ -3391,10 +3394,10 @@ def GSS_UnwrapEx(self, Context, msgs, signature):
if Context.KrbSessionKey.etype in [17, 18]: # AES
confidentiality = Context.flags & GSS_C_FLAGS.GSS_C_CONF_FLAG
# Real separation starts now: RFC4121 sect 4.2.4
# Concatenate the data
Data = signature.root.Data
Data += b"".join(x.data for x in msgs if x.sign or x.conf_req_flag)
if confidentiality:
# 0. Concatenate the data
Data = signature.root.Data
Data += b"".join(x.data for x in msgs if x.conf_req_flag)
# 1. Un-Rotate
Data = strrot(Data, signature.root.RRC + signature.root.EC, right=False)
# 2. Decrypt
Expand All @@ -3418,11 +3421,13 @@ def GSS_UnwrapEx(self, Context, msgs, signature):
msglen = len(msg.data)
if msg.conf_req_flag:
msg.data = Data[offset : offset + msglen]
if msg.sign or msg.conf_req_flag:
offset += msglen
return msgs
else:
# No confidentiality is requested
# 0. Concatenate the data
Data = signature.root.Data
Data += b"".join(x.data for x in msgs if x.sign)
# 1. Un-Rotate
Data = strrot(Data, signature.root.RRC, right=False)
# 2. Split
Expand Down
19 changes: 15 additions & 4 deletions scapy/layers/smbclient.py
Expand Up @@ -255,6 +255,7 @@ def receive_negotiate_response(self, pkt):
else:
if SMB2_Negotiate_Protocol_Response in pkt:
self.Dialect = pkt.DialectRevision
self.update_smbheader(pkt)
raise self.NEGOTIATED(ssp_blob)
elif SMBNegotiate_Response_Security in pkt:
# Non-extended SMB1
Expand Down Expand Up @@ -291,6 +292,19 @@ def NEGOTIATED(self, ssp_blob=None):
)
return ssp_tuple

def update_smbheader(self, pkt):
"""
Called when receiving a SMB2 packet to update the current smb_header
"""
# Some values should not be updated when ASYNC
if not pkt.Flags.SMB2_FLAGS_ASYNC_COMMAND:
# [MS-SMB2] sect 3.2.5.1.4 - we charge what we are granted
self.smb_header.CreditCharge = pkt.CreditRequest
# Update IDs
self.smb_header.SessionId = pkt.SessionId
self.smb_header.TID = pkt.TID
self.smb_header.PID = pkt.PID

# DEV: add a condition on NEGOTIATED with prio=0

@ATMT.condition(NEGOTIATED, prio=1)
Expand Down Expand Up @@ -435,10 +449,7 @@ def incoming_data_received_smb(self, pkt):

@ATMT.action(incoming_data_received_smb)
def receive_data_smb(self, pkt):
if not pkt.Flags.SMB2_FLAGS_ASYNC_COMMAND:
# PID and TID are not set when ASYNC
self.smb_header.TID = pkt.TID
self.smb_header.PID = pkt.PID
self.update_smbheader(pkt)
resp = pkt[SMB2_Header].payload
if isinstance(resp, SMB2_Error_Response):
if pkt.Status == 0x00000103: # STATUS_PENDING
Expand Down

0 comments on commit d832890

Please sign in to comment.