scapy.layers.spnego
SPNEGO
Implements parts of:
GSSAPI SPNEGO: RFC4178 > RFC2478
GSSAPI SPNEGO NEGOEX: [MS-NEGOEX]
Note
You will find more complete documentation for this layer over at GSSAPI
- class scapy.layers.spnego.NEGOEX_BYTE_VECTOR(_pkt, /, *, ByteArrayBufferOffset=0, ByteArrayLength=0)[source]
Bases:
Packet- aliastypes = [<class 'scapy.layers.spnego.NEGOEX_BYTE_VECTOR'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.NEGOEX_CHECKSUM(_pkt, /, *, cbHeaderLength=20, ChecksumScheme=1, ChecksumType=None, ChecksumValue=b'')[source]
Bases:
Packet- aliastypes = [<class 'scapy.layers.spnego.NEGOEX_CHECKSUM'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.NEGOEX_EXCHANGE_MESSAGE(_pkt, /, *, Signature=b'NEGOEXTS', MessageType=0, SequenceNum=0, cbHeaderLength=None, cbMessageLength=None, ConversationId=None, AuthScheme=None, ExchangeBufferOffset=0, ExchangeLen=0, Payload=[])[source]
Bases:
_NTLMPayloadPacket- OFFSET = 64
- aliastypes = [<class 'scapy.layers.spnego.NEGOEX_EXCHANGE_MESSAGE'>, <class 'scapy.layers.ntlm._NTLMPayloadPacket'>, <class 'scapy.packet.Packet'>]
- fields_desc: ClassVar[List[Field[Any, Any] | _FieldContainer]] = [<StrFixedLenField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).Signature>, <LEIntEnumField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).MessageType>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).SequenceNum>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).cbHeaderLength>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).cbMessageLength>, <UUIDField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).ConversationId>, <UUIDEnumField (NEGOEX_EXCHANGE_MESSAGE).AuthScheme>, <LEIntField (NEGOEX_EXCHANGE_MESSAGE).ExchangeBufferOffset>, <LEIntField (NEGOEX_EXCHANGE_MESSAGE).ExchangeLen>, <_NTLMPayloadField (NEGOEX_EXCHANGE_MESSAGE).Payload>]
- show_indent = 0
- class scapy.layers.spnego.NEGOEX_EXTENSION_VECTOR(_pkt, /, *, ExtensionArrayOffset=0, ExtensionCount=0)[source]
Bases:
Packet- aliastypes = [<class 'scapy.layers.spnego.NEGOEX_EXTENSION_VECTOR'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.NEGOEX_MESSAGE_HEADER(_pkt, /, *, Signature=b'NEGOEXTS', MessageType=0, SequenceNum=0, cbHeaderLength=None, cbMessageLength=None, ConversationId=None)[source]
Bases:
Packet- aliastypes = [<class 'scapy.layers.spnego.NEGOEX_MESSAGE_HEADER'>, <class 'scapy.packet.Packet'>]
- fields_desc: ClassVar[List[Field[Any, Any] | _FieldContainer]] = [<StrFixedLenField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).Signature>, <LEIntEnumField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).MessageType>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).SequenceNum>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).cbHeaderLength>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).cbMessageLength>, <UUIDField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).ConversationId>]
- class scapy.layers.spnego.NEGOEX_NEGO_MESSAGE(_pkt, /, *, Signature=b'NEGOEXTS', MessageType=0, SequenceNum=0, cbHeaderLength=None, cbMessageLength=None, ConversationId=None, Random=b'', ProtocolVersion=0, AuthSchemeBufferOffset=None, AuthSchemeCount=None, ExtensionBufferOffset=None, ExtensionCount=None, Payload=[])[source]
Bases:
_NTLMPayloadPacket- OFFSET = 92
- aliastypes = [<class 'scapy.layers.spnego.NEGOEX_NEGO_MESSAGE'>, <class 'scapy.layers.ntlm._NTLMPayloadPacket'>, <class 'scapy.packet.Packet'>]
- fields_desc: ClassVar[List[Field[Any, Any] | _FieldContainer]] = [<StrFixedLenField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).Signature>, <LEIntEnumField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).MessageType>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).SequenceNum>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).cbHeaderLength>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).cbMessageLength>, <UUIDField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).ConversationId>, <XStrFixedLenField (NEGOEX_NEGO_MESSAGE).Random>, <LELongField (NEGOEX_NEGO_MESSAGE).ProtocolVersion>, <LEIntField (NEGOEX_NEGO_MESSAGE).AuthSchemeBufferOffset>, <LEShortField (NEGOEX_NEGO_MESSAGE).AuthSchemeCount>, <LEIntField (NEGOEX_NEGO_MESSAGE).ExtensionBufferOffset>, <LEShortField (NEGOEX_NEGO_MESSAGE).ExtensionCount>, <_NTLMPayloadField (NEGOEX_NEGO_MESSAGE).Payload>]
- payload_guess: List[Tuple[Dict[str, Any], Type[Packet]]] = [({}, <class 'scapy.layers.spnego.NEGOEX_NEGO_MESSAGE'>)]
- show_indent = 0
- class scapy.layers.spnego.NEGOEX_VERIFY_MESSAGE(_pkt, /, *, Signature=b'NEGOEXTS', MessageType=0, SequenceNum=0, cbHeaderLength=None, cbMessageLength=None, ConversationId=None, AuthScheme=None, Checksum=<NEGOEX_CHECKSUM |>)[source]
Bases:
Packet- aliastypes = [<class 'scapy.layers.spnego.NEGOEX_VERIFY_MESSAGE'>, <class 'scapy.packet.Packet'>]
- fields_desc: ClassVar[List[Field[Any, Any] | _FieldContainer]] = [<StrFixedLenField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).Signature>, <LEIntEnumField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).MessageType>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).SequenceNum>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).cbHeaderLength>, <LEIntField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).cbMessageLength>, <UUIDField (NEGOEX_MESSAGE_HEADER,NEGOEX_NEGO_MESSAGE,NEGOEX_EXCHANGE_MESSAGE,NEGOEX_VERIFY_MESSAGE).ConversationId>, <UUIDEnumField (NEGOEX_VERIFY_MESSAGE).AuthScheme>, <PacketField (NEGOEX_VERIFY_MESSAGE).Checksum>]
- show_indent = 0
- class scapy.layers.spnego.SPNEGOSSP(ssps: List[SSP], **kwargs)[source]
Bases:
SSPThe SPNEGO SSP
- Parameters:
ssps – a dict with keys being the SSP class, and the value being a dictionary of the keyword arguments to pass it on init.
Example:
from scapy.layers.ntlm import NTLMSSP from scapy.layers.kerberos import KerberosSSP from scapy.layers.spnego import SPNEGOSSP from scapy.layers.smbserver import smbserver from scapy.libs.rfc3961 import Encryption, Key ssp = SPNEGOSSP([ NTLMSSP( IDENTITIES={ "User1": MD4le("Password1"), "Administrator": MD4le("Password123!"), } ), KerberosSSP( SPN="cifs/server2.domain.local", KEY=Key( Encryption.AES256, key=hex_bytes("5e9255c907b2f7e969ddad816eabbec8f1f7a387c7194ecc98b827bdc9421c2b") ) ) ]) smbserver(ssp=ssp)
- class CONTEXT(ssps: List[SSP], req_flags=None)[source]
Bases:
CONTEXT- first_choice
- property flags
- negotiate_ssp() None[source]
Perform SSP negotiation.
This updates our context and sets it with the first SSP that is common to both client and server. This also applies rules from [MS-SPNG] and RFC4178 to determine if mechListMIC is required.
- other_mechtypes
- raw
- req_flags
- require_mic
- sent_mechtypes
- ssp
- ssp_context
- ssp_mechtype
- ssps
- verified_mic
- GSS_Accept_sec_context(Context: CONTEXT, input_token=None, req_flags: GSS_S_FLAGS | None = <GSS_S_FLAGS.GSS_S_ALLOW_MISSING_BINDINGS: 268435456>, chan_bindings: GssChannelBindings = b'\x00')[source]
- GSS_Init_sec_context(Context: CONTEXT, input_token=None, target_name: str | None = None, req_flags: GSS_C_FLAGS | None = None, chan_bindings: GssChannelBindings = b'\x00')[source]
- GuessOtherMechtypes(Context: CONTEXT, input_token)[source]
Guesses the mechtype of the peer when the “raw” fallback is used.
- auth_type = 9
- classmethod from_cli_arguments(UPN: str, target: str, password: str = None, HashNt: bytes = None, HashAes256Sha96: bytes = None, HashAes128Sha96: bytes = None, kerberos_required: bool = False, ST=None, TGT=None, KEY=None, ccache: str = None, debug: int = 0, use_krb5ccname: bool = False, use_winssp: bool = False)[source]
Initialize a SPNEGOSSP from a list of many arguments.
This is useful in a CLI, as it will try to build the best SPNEGOSSP with NTLM and Kerberos based on the various parameters.
- Parameters:
UPN – the UPN of the user to use.
target – the target IP/hostname entered by the user.
kerberos_required – require kerberos
password – (string) if provided, used for auth
HashNt – (bytes) if provided, used for auth (NTLM)
HashAes256Sha96 – (bytes) if provided, used for auth (Kerberos)
HashAes128Sha96 – (bytes) if provided, used for auth (Kerberos)
ST – if provided, the service ticket to use (Kerberos)
TGT – if provided, the TGT to use (Kerberos)
KEY – if ST provided, the session key associated to the ticket (Kerberos). This can be either for the ST or TGT. Else, the user secret key.
ccache – (str) if provided, a path to a CCACHE (Kerberos)
use_krb5ccname – (bool) if true, the KRB5CCNAME environment variable will be used if available.
use_winssp – (bool) (only works on Windows). Use implicit authentication through WinSSP.
- ssps
- class scapy.layers.spnego.SPNEGO_MechListMIC(_pkt, /, *, value=<ASN1_STRING['']>)[source]
Bases:
ASN1_Packet- ASN1_codec = <ASN1Codec BER[1]>
- ASN1_root = <scapy.asn1fields.ASN1F_STRING_ENCAPS object>
- aliastypes = [<class 'scapy.layers.spnego.SPNEGO_MechListMIC'>, <class 'scapy.asn1packet.ASN1_Packet'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.SPNEGO_MechType(_pkt, /, *, oid=None)[source]
Bases:
ASN1_Packet- ASN1_codec = <ASN1Codec BER[1]>
- ASN1_root = <scapy.asn1fields.ASN1F_OID object>
- aliastypes = [<class 'scapy.layers.spnego.SPNEGO_MechType'>, <class 'scapy.asn1packet.ASN1_Packet'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.SPNEGO_MechTypes(_pkt, /, *, mechTypes=None)[source]
Bases:
ASN1_Packet- ASN1_codec = <ASN1Codec BER[1]>
- ASN1_root = <ASN1F_SEQUENCE_OF mechTypes>
- aliastypes = [<class 'scapy.layers.spnego.SPNEGO_MechTypes'>, <class 'scapy.asn1packet.ASN1_Packet'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.SPNEGO_Token(_pkt, /, *, value=None)[source]
Bases:
ASN1_Packet- ASN1_codec = <ASN1Codec BER[1]>
- ASN1_root = <scapy.layers.spnego._SPNEGO_Token_Field object>
- aliastypes = [<class 'scapy.layers.spnego.SPNEGO_Token'>, <class 'scapy.asn1packet.ASN1_Packet'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.SPNEGO_negHints(_pkt, /, *, hintName=<ASN1_GENERAL_STRING['not_defined_in_RFC4178@please_ignore']>, hintAddress=None)[source]
Bases:
ASN1_Packet- ASN1_codec = <ASN1Codec BER[1]>
- ASN1_root = <ASN1F_SEQUENCE(<scapy.asn1fields.ASN1F_optional object>, <scapy.asn1fields.ASN1F_optional object>)>
- aliastypes = [<class 'scapy.layers.spnego.SPNEGO_negHints'>, <class 'scapy.asn1packet.ASN1_Packet'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.SPNEGO_negToken(_pkt, /, *, token=<SPNEGO_negTokenInit |>)[source]
Bases:
ASN1_Packet- ASN1_codec = <ASN1Codec BER[1]>
- ASN1_root = <scapy.asn1fields.ASN1F_CHOICE object>
- aliastypes = [<class 'scapy.layers.spnego.SPNEGO_negToken'>, <class 'scapy.asn1packet.ASN1_Packet'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.SPNEGO_negTokenInit(_pkt, /, *, mechTypes=None, reqFlags=None, mechToken=None, negHints=None, mechListMIC=None, _mechListMIC=None)[source]
Bases:
ASN1_Packet- ASN1_codec = <ASN1Codec BER[1]>
- ASN1_root = <ASN1F_SEQUENCE(<scapy.asn1fields.ASN1F_optional object>, <scapy.asn1fields.ASN1F_optional object>, <scapy.asn1fields.ASN1F_optional object>, <scapy.asn1fields.ASN1F_optional object>, <scapy.asn1fields.ASN1F_optional object>, <scapy.asn1fields.ASN1F_optional object>)>
- aliastypes = [<class 'scapy.layers.spnego.SPNEGO_negTokenInit'>, <class 'scapy.asn1packet.ASN1_Packet'>, <class 'scapy.packet.Packet'>]
- class scapy.layers.spnego.SPNEGO_negTokenResp(_pkt, /, *, negState=0x0 <ASN1_ENUMERATED[0]>, supportedMech=<SPNEGO_MechType |>, responseToken=None, mechListMIC=None)[source]
Bases:
ASN1_Packet- ASN1_codec = <ASN1Codec BER[1]>
- ASN1_root = <ASN1F_SEQUENCE(<scapy.asn1fields.ASN1F_optional object>, <scapy.asn1fields.ASN1F_optional object>, <scapy.asn1fields.ASN1F_optional object>, <scapy.asn1fields.ASN1F_optional object>)>
- aliastypes = [<class 'scapy.layers.spnego.SPNEGO_negTokenResp'>, <class 'scapy.asn1packet.ASN1_Packet'>, <class 'scapy.packet.Packet'>]
- scapy.layers.spnego.mechListMIC(oids)[source]
Implementation of RFC 4178 - Appendix D. mechListMIC Computation
NOTE: The documentation on mechListMIC isn’t super clear, so note that:
The mechListMIC that the client sends is computed over the list of mechanisms that it requests.
the mechListMIC that the server sends is computed over the list of mechanisms that the client requested.
This also means that NegTokenInit2 added by [MS-SPNG] is NOT protected. That’s not necessarily an issue, since it was optional in most cases, but it’s something to keep in mind.