1616 `GSSAPI <https://scapy.readthedocs.io/en/latest/layers/gssapi.html#spnego>`_
1717"""
1818
19+ import os
1920import struct
2021from uuid import UUID
2122
@@ -640,9 +641,11 @@ def from_cli_arguments(
640641 HashAes128Sha96 : bytes = None ,
641642 kerberos_required : bool = False ,
642643 ST = None ,
644+ TGT = None ,
643645 KEY = None ,
644646 ccache : str = None ,
645647 debug : int = 0 ,
648+ use_krb5ccname : bool = False ,
646649 ):
647650 """
648651 Initialize a SPNEGOSSP from a list of many arguments.
@@ -656,9 +659,12 @@ def from_cli_arguments(
656659 :param HashAes256Sha96: (bytes) if provided, used for auth (Kerberos)
657660 :param HashAes128Sha96: (bytes) if provided, used for auth (Kerberos)
658661 :param ST: if provided, the service ticket to use (Kerberos)
662+ :param TGT: if provided, the TGT to use (Kerberos)
659663 :param KEY: if ST provided, the session key associated to the ticket (Kerberos).
660- Else, the user secret key.
664+ This can be either for the ST or TGT. Else, the user secret key.
661665 :param ccache: (str) if provided, a path to a CCACHE (Kerberos)
666+ :param use_krb5ccname: (bool) if true, the KRB5CCNAME environment variable will
667+ be used if available.
662668 """
663669 kerberos = True
664670 hostname = None
@@ -682,6 +688,10 @@ def from_cli_arguments(
682688 # not a UPN: NTLM only
683689 kerberos = False
684690
691+ # If we're asked, check the environment for KRB5CCNAME
692+ if use_krb5ccname and ccache is None and "KRB5CCNAME" in os .environ :
693+ ccache = os .environ ["KRB5CCNAME" ]
694+
685695 # Do we need to ask the password?
686696 if all (
687697 x is None
@@ -691,6 +701,7 @@ def from_cli_arguments(
691701 HashNt ,
692702 HashAes256Sha96 ,
693703 HashAes128Sha96 ,
704+ ccache ,
694705 ]
695706 ):
696707 # yes.
@@ -702,19 +713,42 @@ def from_cli_arguments(
702713 # Kerberos
703714 if kerberos and hostname :
704715 # Get ticket if we don't already have one.
705- if ST is None and ccache is not None :
716+ if ST is None and TGT is None and ccache is not None :
706717 # In this case, load the KerberosSSP from ccache
707718 from scapy .modules .ticketer import Ticketer
708719
709720 # Import into a Ticketer object
710721 t = Ticketer ()
711722 t .open_ccache (ccache )
712723
713- # Look for the ticketer that we'll use
714- raise NotImplementedError
715-
716- ssps .append (t .ssp ())
717- elif ST is None :
724+ # Look for the ticket that we'll use. We chose:
725+ # - either a ST if the SPN matches our target
726+ # - else a TGT if we got nothing better
727+ tgts = []
728+ for i , (tkt , key , upn , spn ) in enumerate (t .iter_tickets ()):
729+ # Check that it's for the correct user
730+ if upn .lower () == UPN .lower ():
731+ # Check that it's either a TGT or a ST to the correct service
732+ if spn .lower ().startswith ("krbtgt/" ):
733+ # TGT. Keep it, and see if we don't have a better ST.
734+ tgts .append (t .ssp (i ))
735+ elif hostname in spn :
736+ # ST. We're done !
737+ ssps .append (t .ssp (i ))
738+ break
739+ else :
740+ # No ST found
741+ if tgts :
742+ # Using a TGT !
743+ ssps .append (tgts [0 ])
744+ else :
745+ # Nothing found
746+ t .show ()
747+ raise ValueError (
748+ f"Could not find a ticket for { upn } , either a "
749+ f"TGT or towards { hostname } "
750+ )
751+ elif ST is None and TGT is None :
718752 # In this case, KEY is supposed to be the user's key.
719753 from scapy .libs .rfc3961 import Key , EncryptionType
720754
@@ -748,6 +782,7 @@ def from_cli_arguments(
748782 KerberosSSP (
749783 UPN = UPN ,
750784 ST = ST ,
785+ TGT = TGT ,
751786 KEY = KEY ,
752787 debug = debug ,
753788 )
0 commit comments