Actuellement je suis en train de développer un script qui utilise la lib impacket, ce script consiste à faire du targeted ASREPRoasting. J’ai appris pas mal de chose en faisant ce scripts notamment comment fonctionne vraiment kerberos et plus particulièrement lors qu’on envoie un message AS-REQ.

Pour faire un ptit rappel, l’attaque ASREProasting consiste à demander un TGT au KDC pour un user qui n’a pas la preauth d’activé. Pour ce faire on doit crafter le message AS-REQ pour demander un TGT au KDC. Une fois la requête envoyé, on obtiens la réponse AS-REP qui contient le TGT et la clé de session chiffré avec le hash NT de l’utilisateur, on peut cracker cette clé de session hors ligne.

On va commencer par parler du script en général puis on verra de quoi est composé le message AS-REQ avec wireshark et des print() :D

à noté que la version de mon script pour l’asreproasting ne supporte pas les mdp.

Déjà on va commencer par parler des libs utilisées qui m’a permis de craft le message AS-REQ

Untitled

du coté d’impacket on importe tout ce qui viens de kerberos version 5 comme les constantes, Fonctions, Erreurs. Ensuite on va utiliser pyasn1 qui joue un rôle plus qu’important, cette lib implémente le standard ASN.1 dans ça globalité. Pour ceux qui savent pas, l’ASN.1 (Abstract Syntax Notation 1) est une notation utilisé pour décrire des structures de données, exemple:

Record ::= SEQUENCE {
  id        INTEGER,
  room  [0] INTEGER OPTIONAL,
  house [1] INTEGER DEFAULT 0
}

Cette notation possède plusieurs règles d'encodage pour les données décrites par l’ASN.1 comme DER (Distinguished Encoding Rules) pour les règles d’encodage élaborées ou encore BER (Basic Encoding Rules) pour les règles d’encodage de base. dans notre cas on va utilisé DER pour l’unicité des données. on importe aussi NoValue de pyasn1, c’est juste un type propre d’ASN.1.

https://github.com/etingof/pyasn1

on va aussi importer hexlify de binascii qui va nous permettre de diviser un string composée d'hex-tuples en bytes distincts. Pour random et datetime, on en parlera un peu plus tard.

Avant de construire le paquets on doit déclarer des informations qui vont être utiles par la suite:

domain = "SPOOKYSEC.LOCAL"
userName = "svc-admin"
clientName = Principal(userName, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
serverName = Principal('krbtgt/%s' % domain, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
asReq = AS_REQ()

on déclare clientName basé sur l’utilisateur svc-admin et qui sera construit à l’aide de la classe Principal() avec la constante NT_PRINCIPAL qui correspond au nom du principal qui a pour valeur 1. Pour le serverName, on va devoir concaténer le compte krbtgt et le domaine, car comme vous le savez surement le compte KRBTGT fait office de compte de service pour le KDC.