Kerberos : où et comment signaler un bug d’encodage ASN.1/DER (AP‑REQ/AP‑REP, RFC 4120, MSRC)

Vous suspectez un bug Kerberos lié à l’encodage ASN.1/DER et hésitez entre un signalement confidentiel au MSRC et une discussion publique ? Voici un guide concret, orienté diagnostic terrain, pour trancher vite et corriger proprement.

Sommaire

Où signaler un supposé bug d’encodage DER dans Kerberos ?

Vue d’ensemble de la question

Lors d’une implémentation Kerberos, un développeur observe que, dans certains échanges, le champ ctime de AP‑REP EncAPRepPart ne reflète pas le ctime de AP‑REQ Authenticator, ce qui semble contredire la RFC 4120 (§ 3.2.5). Il se demande alors où déclarer ce « bug » : auprès du Microsoft Security Response Center (MSRC) ou sur un forum public. Il craint par ailleurs un impact sécurité.

Réponse & solution

  • Le désalignement ne venait pas du KDC : l’erreur provenait du code local d’encodage/décodage DER INTEGER.
  • Aucun ticket MSRC ni rapport public n’était nécessaire.

Bonnes pratiques pour de futurs signalements

  1. Isoler le problème : confrontez la trame fautive à une capture générée par un encodeur DER de référence (ex. via openssl asn1parse). Vérifiez les classiques : octet de bourrage 0x00, bit de signe, longueur TLV, encodage minimal.
  2. Qualifier la gravité :
    • Faille de sécurité avérée dans un produit Microsoft → signalement au MSRC.
    • Non‑conformité aux spécifications sans impact sécurité → ouvrez un ticket produit (ex. dépôt GitHub/Issues, forums Microsoft) ou postez sur la liste kerberos@ietf.org pour validation communautaire.
  3. Fournir les artefacts utiles : PCAP filtrées, extraits de code, versions logicielles et configuration (KDC, client, OS, bibliothèques, horloge système, NTP).

Pourquoi ce n’était pas un bug KDC : comprendre DER et ses pièges

En ASN.1/DER, l’INTEGER se code en complément à deux avec un encodage minimal. Deux erreurs récurrentes provoquent des lectures erronées :

  • Signe et octet de bourrage : si l’octet de poids fort a le bit 7 à 1, un octet 0x00 doit être préfixé pour indiquer un entier positif. Exemple : la valeur 0x80 se code 02 02 00 80, pas 02 01 80.
  • Longueur TLV incorrecte : une longueur mal calculée décale le parseur et fait « glisser » la lecture sur le champ suivant, donnant l’illusion d’un ctime différent ou d’une structure corrompue.

Important : dans Kerberos, ctime est un KerberosTime (ASN.1 GeneralizedTime, pas un INTEGER). En pratique, un bug sur un INTEGER adjacent (par ex. cusec, seq-number) ou sur la longueur DER du TLV précédent suffit à décaler le décodage et à faire croire à une divergence de ctime. D’où l’intérêt d’auditer tous les TLV, pas seulement ctime.

Procédure de diagnostic express

  1. Capturer une trace propre : utilisez un filtre « host KDC and tcp.port==88 » ou « udp.port==88 ». Conservez l’échange AS‑REQ/AS‑REP si pertinent, mais focalisez‑vous sur AP‑REQ/AP‑REP.
  2. Isoler les blobs DER : exportez l’Authenticator et l’EncAPRepPart en binaire.
  3. Valider la structure : passez les blobs dans un parseur ASN.1 (ex. openssl asn1parse -inform DER -in blob.der -i -dump) et vérifiez :
    • balises (tags) attendues ;
    • longueurs (L) minimales cohérentes ;
    • valeurs (V) : notamment cusec, seq-number, kvno.
  4. Comparer ctime/cusec : dans l’Authenticator et l’EncAPRepPart, les paires (ctime, cusec) doivent se correspondre. Un cusec négatif ou mal encodé est un indicateur fort.
  5. Essai croisé : rejouez le même AP‑REQ vers un KDC de référence (MIT Kerberos ou Heimdal). Si le bogue disparaît, votre KDC précédent est plus strict ; s’il persiste, votre encodeur DER est en cause.
  6. Vérifier l’horloge : assurez‑vous que la dérive NTP est sous le seuil du royaume (souvent ±5 min). Une dérive peut introduire des erreurs KRB_AP_ERR_SKEW masquant la vraie cause.

Tableau récapitulatif : symptômes DER et correctifs

Symptôme observéCause DER probableDiagnostic rapideCorrection
ctime différent entre Authenticator et EncAPRepPartLongueur TLV précédente erronée, parseur décalé ; cusec mal encodéComparer offsets TLV et recalculer longueursRecalculer L ; garantir l’encodage minimal DER
KRB_AP_ERR_BAD_INTEGRITYStructure ASN.1 altérée avant MAC/chiffrementVérifier exactitude des octets avant chiffrementFixer l’encodeur et régénérer l’Authenticator
KRB_AP_ERR_SKEWHeure système en dehors de la toléranceComparer NTP client/KDCResynchroniser NTP, rejouer AP‑REQ
Entier signé interprété comme négatifOctet 0x00 de bourrage manquantValeur INT attendue > 127 codée sur 1 octetPréfixer 0x00 et ajuster la longueur
Rejet avec MODIFIED ou BADMATCHOrdre des champs ou tags non conformeComparer séquence TLV à une trace de référenceRespect strict des tags/classes/ordres DER

Exemples concrets d’encodage INTEGER en DER

Rappel : INTEGER en DER est encodé en complément à deux et minimisé.

Valeur décimale   Encodage DER (hex)
127               02 01 7F
128               02 02 00 80           (octet 0x00 requis)
255               02 02 00 FF
256               02 02 01 00
999999            02 03 0F 42 3F

Erreurs typiques :

  • Encodage sur‑dimensionné (octets inutiles) : refuse par non‑minimalité DER.
  • Encodage sous‑dimensionné : perte de bit de poids fort ⇒ signe inversé.

Conséquence sur Kerberos

Un cusec (Microseconds) mal encodé peut perturber le parseur et conduire à une lecture faussée de ctime, ou à l’échec de vérification d’intégrité. Vous voyez alors un ctime « différent » côté EncAPRepPart alors que la source est un INTEGER avoisinant.

Quand contacter le MSRC, quand poster en public ?

La bonne destination dépend de l’impact et de l’étendue.

ScénarioImpactCanal recommandéPreuves à joindre
Exécution de code, élévation de privilèges, contournement d’authentCritiqueMSRC (privé)PCAP, PoC, versions, étendue (clients/serveurs)
Non‑respect DER causé par votre librairieLocal, pas sécuritéTicket produit / dépôt GitHub / forumsDiff binaire, tests unitaires, patch proposé
Comportement ambigu vis‑à‑vis de la RFCInteropListe kerberos@ietf.orgExtrait ASN.1 minimal, attentes vs. lecture

Ce qu’il faut fournir dans un signalement utile

  • Traces réseau : PCAP filtrées (AP‑REQ/AP‑REP), horodatées, avec la clé si vous pouvez légalement déchiffrer pour l’analyse.
  • Extraits de code : fonctions d’encodage/décodage ASN.1, calcul des longueurs, gestion du signe.
  • Versions : KDC (distribution et version), client (OS, build), bibliothèques (OpenSSL, ASN.1), fuseau horaire, décalage NTP.
  • Pas‑à‑pas de reproduction : commandes (kinit, kvno, application test), paramètres (SPN, realm), variations testées.

Exemple reproductible minimal : encoder correctement un INTEGER

Le pseudo‑code ci‑dessous illustre l’ajout conditionnel de l’octet 0x00 pour les entiers positifs dont le bit 7 du premier octet serait à 1.

// Pseudo‑code
bytes encodeDERInteger(unsigned value) {
  // Convertir en big‑endian minimal
  bytes be = toBigEndianMinimal(value);  // supprime les 0x00 de tête inutiles
  if (be[0] & 0x80) {
    be = concat(0x00, be);               // préfixer pour forcer un signe positif
  }
  return concat(0x02, encodeLength(be.len), be);
}

Assurez‑vous réciproquement que le décodage accepte uniquement les représentations minimales et rejette celles non canoniques.

Vérifier ctime et cusec côté AP‑REQ / AP‑REP

Attendus de cohérence (simplifiés) :

  • Authenticator : contient ctime (KerberosTime) et cusec (INTEGER 0‑999999).
  • EncAPRepPart : renvoie ctime et cusec du client. Ces valeurs doivent correspondre à celles de l’Authenticator validé.

Si ctime semble diverger :

  1. Confirmer l’encodage GeneralizedTime : format YYYYMMDDHHMMSSZ, sans fraction.
  2. Contrôler la longueur TLV entourant ctime et le TLV précédent (souvent source de décalage).
  3. Vérifier le champ cusec et tout INTEGER attenant (ex. seq-number).

Outils et commandes utiles (sans liens)

  • openssl asn1parse -in blob.der -inform DER -i -dump : inspection TLV, offsets, longueurs et valeurs.
  • tshark/wireshark : décodage Kerberos, extraction des champs ctime/cusec.
  • kinit, kvno, klist : génération et vérification de tickets côté client.
  • dumpcap : capture de trafic minimale, stable pour la repro.

Modèles de messages pour un signalement

Exemple – Discussion communautaire (liste Kerberos)

Objet : Vérification d’encodage DER – divergence ctime AP‑REQ/AP‑REP

Bonjour,

Nous observons une divergence apparente entre ctime(Auth) et ctime(EncAPRepPart).
Analyse initiale : INTEGER voisin (cusec) encodé sans octet 0x00 de bourrage.
Artefacts : PCAP jointe, blob DER, asn1parse, extraits code.

Question : la lecture côté KDC doit-elle rejeter ce non-canonique ?
Merci pour vos retours d’implémenteurs.

Cordialement, 

Exemple – Ticket produit (sans impact sécurité)

Résumé : Encodage DER INTEGER non minimal provoquant une divergence ctime perçue

Étapes :

1. Construire AP‑REQ via notre librairie ASN.1 (commit X).
2. Envoyer au KDC ; obtenir AP‑REP.
3. Comparer ctime/cusec ; divergence.

Attendu :
Encodage DER minimal pour INTEGER et cohérence ctime.

Réel :
cusec encodé 02 01 80 au lieu de 02 02 00 80.

Pièces :
PCAP, blobs DER, asn1parse, patch de correction. 

Exemple – Signalement MSRC (si vulnérabilité)

Résumé : Faille potentielle – acceptation d’encodage non canonique causant bypass d’intégrité

Impact :
Possibilité de contourner la vérification d’un champ protégé (détails en pièce jointe).

Repro :
Étapes détaillées + PoC, versions affectées, matrices d’impact.

Demande :
Canal privé pour coordination et attribution CVE si confirmé. 

FAQ ciblée

Est‑ce grave si mon INTEGER est encodé avec trop d’octets ?

Oui : DER impose un encodage minimal. Un KDC strict doit rejeter un INTEGER sur‑dimensionné. Même si certains parseurs tolèrent, votre code n’est pas interopérable.

Pourquoi un bug INTEGER peut‑il impacter ctime qui est un GeneralizedTime ?

Parce qu’une longueur TLV erronée sur un champ précédent décale le parseur : il lit alors un morceau de ctime à un mauvais offset, ou réinterprète des octets comme s’ils appartenaient à un autre tag.

Je vois KRB_AP_ERR_BAD_INTEGRITY. C’est forcément l’ASN.1 ?

Non. L’erreur peut aussi venir d’une clé ou d’un checksum incorrect. Mais si le problème disparaît avec un encodeur DER de référence, la piste encodage est privilégiée.

Dois‑je publier immédiatement un rapport public ?

Non. Évaluez l’impact. Pas d’impact sécurité → débat public/issue produit. Impact sécurité plausible → canal privé (MSRC) jusqu’à clarification.

Checklist finale avant d’ouvrir un ticket

  • Reproduction stable sur au moins deux environnements.
  • Comparaison binaire avec un AP‑REQ « propre » encodé par un outil de référence.
  • Validation des longueurs DER et du signe des INTEGER.
  • Preuve que le KDC répond différemment selon l’encodage (tolérant vs strict).
  • Paquet d’artefacts : PCAP, blobs DER, asn1parse, extraits de code, versions.

Cas d’école : de la divergence apparente à la vraie cause

Observation initiale : ctime(EncAPRepPart) semble décaler de quelques secondes par rapport à ctime(Authenticator) sur certains échanges.

Enquête : inspection TLV → cusec encodé 02 01 80 (manque de 0x00), longueur calculée comme si 1 octet, alors que la valeur requiert 2 octets. Le TLV suivant (qui contient ctime) est lu au mauvais offset par le code local, mais le KDC strict recalcule correctement côté serveur et renvoie un EncAPRepPart cohérent avec l’Authenticator qu’il a validé.

Résolution : correctif d’encodage INTEGER (préfixe 0x00 conditionnel + vérification d’encodage minimal) et tests unitaires couvrant les seuils 127/128/255/256/999999.

Résumé opérationnel

  • La divergence ctime perçue n’est, le plus souvent, qu’un effet de bord d’un encodage DER fautif (souvent sur cusec ou la longueur TLV précédente).
  • Corrigez l’encodeur/décodeur INTEGER local avant toute escalade.
  • Ne sollicitez MSRC que si un impact sécurité est plausible et reproductible.
  • Pour l’interop ou la conformité, privilégiez une discussion publique (ticket produit, liste kerberos@ietf.org) avec artefacts et analyses.

Annexe : table « quick‑win » sur les entiers sensibles

Champ KerberosType ASN.1Plage attenduePiège DERTest seuil recommandé
cusec (Authenticator/EncAPRepPart)INTEGER0–999 9990x80, 0xFF : bourrage 0x00127↔128, 255↔256, 999 999
seq-numberINTEGER / UInt320–232−1Non‑minimalité, dépassement231−1↔231
kvnoINTEGER≥ 0Interprétation signée127↔128

Conclusion

Avant d’accuser le KDC, examinez votre chaîne ASN.1/DER : un INTEGER mal encodé, une longueur TLV imprécise ou un non‑respect du caractère minimal peuvent suffire à fausser l’interprétation de ctime. Si le problème n’a pas d’impact sécurité, le MSRC n’est pas la bonne porte ; documentez, reproduisez, comparez avec un encodeur de référence et discutez en public (ticket ou liste d’implémenteurs). Réservez le canal MSRC aux vraies vulnérabilités. Cette discipline vous fera gagner du temps et préservera la qualité de vos intégrations Kerberos.

Sommaire