public PA_FOR_USER(byte[] key, string name, string realm) { userName = new PrincipalName(name); userName.name_type = 10; userRealm = realm.ToUpper(); // now build the checksum auth_package = "Kerberos"; byte[] nameTypeBytes = new byte[4]; nameTypeBytes[0] = 0xa; byte[] nameBytes = Encoding.UTF8.GetBytes(name); byte[] realmBytes = Encoding.UTF8.GetBytes(userRealm); byte[] authPackageBytes = Encoding.UTF8.GetBytes(auth_package); byte[] finalBytes = new byte[nameTypeBytes.Length + nameBytes.Length + realmBytes.Length + authPackageBytes.Length]; Array.Copy(nameTypeBytes, 0, finalBytes, 0, nameTypeBytes.Length); Array.Copy(nameBytes, 0, finalBytes, nameTypeBytes.Length, nameBytes.Length); Array.Copy(realmBytes, 0, finalBytes, nameTypeBytes.Length + nameBytes.Length, realmBytes.Length); Array.Copy(authPackageBytes, 0, finalBytes, nameTypeBytes.Length + nameBytes.Length + realmBytes.Length, authPackageBytes.Length); byte[] outBytes = Crypto.KerberosChecksum(key, finalBytes); Checksum checksum = new Checksum(outBytes); cksum = checksum; }
//KDC-REQ-BODY::= SEQUENCE { // kdc-options[0] KDCOptions, // cname[1] PrincipalName OPTIONAL // -- Used only in AS-REQ --, // realm[2] Realm // -- Server's realm // -- Also client's in AS-REQ --, // sname[3] PrincipalName OPTIONAL, // from[4] KerberosTime OPTIONAL, // till[5] KerberosTime, // rtime[6] KerberosTime OPTIONAL, // nonce[7] UInt32, // etype[8] SEQUENCE OF Int32 -- EncryptionType // -- in preference order --, // addresses[9] HostAddresses OPTIONAL, // enc-authorization-data[10] EncryptedData OPTIONAL // -- AuthorizationData --, // additional-tickets[11] SEQUENCE OF Ticket OPTIONAL // -- NOTE: not empty //} public KDCReqBody(bool c = true) { // defaults for creation kdcOptions = Interop.KdcOptions.FORWARDABLE | Interop.KdcOptions.RENEWABLE | Interop.KdcOptions.RENEWABLEOK; // added ability to remove cname from request // seems to be useful for cross domain stuff // didn't see a cname in "real" S4U request traffic if (c) { cname = new PrincipalName(); } sname = new PrincipalName(); // date time from kekeo ;) HAI 2037! till = DateTime.ParseExact("20370913024805Z", "yyyyMMddHHmmssZ", System.Globalization.CultureInfo.InvariantCulture); // kekeo/mimikatz nonce ;) //nonce = 12381973; nonce = 1818848256; additional_tickets = new List <Ticket>(); etypes = new List <Interop.KERB_ETYPE>(); }
//Ticket::= [APPLICATION 1] SEQUENCE { // tkt-vno[0] INTEGER(5), // realm[1] Realm, // sname[2] PrincipalName, // enc-part[3] EncryptedData -- EncTicketPart //} public Ticket(AsnElt body) { foreach (AsnElt s in body.Sub) { switch (s.TagValue) { case 0: tkt_vno = Convert.ToInt32(s.Sub[0].GetInteger()); break; case 1: realm = Encoding.ASCII.GetString(s.Sub[0].GetOctetString()); break; case 2: sname = new PrincipalName(s.Sub[0]); break; case 3: enc_part = new EncryptedData(s.Sub[0]); break; default: break; } } }
public KRB_ERROR(AsnElt body) { foreach (AsnElt s in body.Sub) { switch (s.TagValue) { case 0: pvno = Convert.ToUInt32(s.Sub[0].GetInteger()); break; case 1: msg_type = Convert.ToUInt32(s.Sub[0].GetInteger()); break; case 2: ctime = s.Sub[0].GetTime(); break; case 3: cusec = Convert.ToUInt32(s.Sub[0].GetInteger()); break; case 4: stime = s.Sub[0].GetTime(); break; case 5: susec = Convert.ToUInt32(s.Sub[0].GetInteger()); break; case 6: error_code = Convert.ToUInt32(s.Sub[0].GetInteger()); break; case 7: crealm = Encoding.ASCII.GetString(s.Sub[0].GetOctetString()); break; case 8: cname = new PrincipalName(s.Sub[0]); break; case 9: realm = Encoding.ASCII.GetString(s.Sub[0].GetOctetString()); break; case 10: sname = new PrincipalName(s.Sub[0]); break; default: break; } } }
private void Decode(AsnElt asn_AS_REP) { // AS-REP::= [APPLICATION 11] KDC-REQ if (asn_AS_REP.TagValue != 11) { throw new System.Exception("AS-REP tag value should be 11"); } if ((asn_AS_REP.Sub.Length != 1) || (asn_AS_REP.Sub[0].TagValue != 16)) { throw new System.Exception("First AS-REP sub should be a sequence"); } // extract the KDC-REP out AsnElt[] kdc_rep = asn_AS_REP.Sub[0].Sub; foreach (AsnElt s in kdc_rep) { switch (s.TagValue) { case 0: pvno = s.Sub[0].GetInteger(); break; case 1: msg_type = s.Sub[0].GetInteger(); break; case 2: // sequence of pa-data //padata = new PA_DATA(s.Sub[0]); break; case 3: crealm = Encoding.ASCII.GetString(s.Sub[0].GetOctetString()); break; case 4: cname = new PrincipalName(s.Sub[0]); break; case 5: ticket = new Ticket(s.Sub[0].Sub[0]); break; case 6: enc_part = new EncryptedData(s.Sub[0]); break; default: break; } } }
public KrbCredInfo(AsnElt body) { foreach (AsnElt s in body.Sub) { switch (s.TagValue) { case 0: key = new EncryptionKey(s); break; case 1: prealm = Encoding.ASCII.GetString(s.Sub[0].GetOctetString()); break; case 2: pname = new PrincipalName(s.Sub[0]); break; case 3: UInt32 temp = Convert.ToUInt32(s.Sub[0].GetInteger()); byte[] tempBytes = BitConverter.GetBytes(temp); flags = (Interop.TicketFlags)BitConverter.ToInt32(tempBytes, 0); break; case 4: authtime = s.Sub[0].GetTime(); break; case 5: starttime = s.Sub[0].GetTime(); break; case 6: endtime = s.Sub[0].GetTime(); break; case 7: renew_till = s.Sub[0].GetTime(); break; case 8: srealm = Encoding.ASCII.GetString(s.Sub[0].GetOctetString()); break; case 9: sname = new PrincipalName(s.Sub[0]); break; default: break; } } }
//KrbCredInfo ::= SEQUENCE { // key [0] EncryptionKey, // prealm [1] Realm OPTIONAL, // pname [2] PrincipalName OPTIONAL, // flags [3] TicketFlags OPTIONAL, // authtime [4] KerberosTime OPTIONAL, // starttime [5] KerberosTime OPTIONAL, // endtime [6] KerberosTime OPTIONAL, // renew-till [7] KerberosTime OPTIONAL, // srealm [8] Realm OPTIONAL, // sname [9] PrincipalName OPTIONAL, // caddr [10] HostAddresses OPTIONAL //} public KrbCredInfo() { key = new EncryptionKey(); prealm = ""; pname = new PrincipalName(); flags = 0; srealm = ""; sname = new PrincipalName(); }
//Authenticator ::= [APPLICATION 2] SEQUENCE { // authenticator-vno [0] INTEGER (5), // crealm [1] Realm, // cname [2] PrincipalName, // cksum [3] Checksum OPTIONAL, // cusec [4] Microseconds, // ctime [5] KerberosTime, // subkey [6] EncryptionKey OPTIONAL, // seq-number [7] UInt32 OPTIONAL, // authorization-data [8] AuthorizationData OPTIONAL //} // NOTE: we're only using: // authenticator-vno [0] // crealm [1] // cname [2] // cusec [4] // ctime [5] public Authenticator() { authenticator_vno = 5; crealm = ""; cname = new PrincipalName(); cusec = 0; ctime = DateTime.UtcNow; subkey = null; seq_number = 0; }
//EncKDCRepPart::= SEQUENCE { // key[0] EncryptionKey, // last-req[1] LastReq, // nonce[2] UInt32, // key-expiration[3] KerberosTime OPTIONAL, // flags[4] TicketFlags, // authtime[5] KerberosTime, // starttime[6] KerberosTime OPTIONAL, // endtime[7] KerberosTime, // renew-till[8] KerberosTime OPTIONAL, // srealm[9] Realm, // sname[10] PrincipalName, // caddr[11] HostAddresses OPTIONAL, // encrypted-pa-data[12] SEQUENCE OF PA-DATA OPTIONAL //} public EncKDCRepPart(AsnElt body) { foreach (AsnElt s in body.Sub) { switch (s.TagValue) { case 0: key = new EncryptionKey(s); break; case 1: lastReq = new LastReq(s.Sub[0]); break; case 2: nonce = Convert.ToUInt32(s.Sub[0].GetInteger()); break; case 3: key_expiration = s.Sub[0].GetTime(); break; case 4: UInt32 temp = Convert.ToUInt32(s.Sub[0].GetInteger()); byte[] tempBytes = BitConverter.GetBytes(temp); flags = (Interop.TicketFlags)BitConverter.ToInt32(tempBytes, 0); break; case 5: authtime = s.Sub[0].GetTime(); break; case 6: starttime = s.Sub[0].GetTime(); break; case 7: endtime = s.Sub[0].GetTime(); break; case 8: renew_till = s.Sub[0].GetTime(); break; case 9: realm = Encoding.ASCII.GetString(s.Sub[0].GetOctetString()); break; case 10: // sname (optional) sname = new PrincipalName(s.Sub[0]); break; case 11: // HostAddresses, skipped for now break; case 12: // encrypted-pa-data, skipped for now break; default: break; } } }
public KDCReqBody(AsnElt body) { foreach (AsnElt s in body.Sub) { switch (s.TagValue) { case 0: UInt32 temp = Convert.ToUInt32(s.Sub[0].GetInteger()); byte[] tempBytes = BitConverter.GetBytes(temp); kdcOptions = (Interop.KdcOptions)BitConverter.ToInt32(tempBytes, 0); break; case 1: // optional cname = new PrincipalName(s.Sub[0]); break; case 2: realm = Encoding.ASCII.GetString(s.Sub[0].GetOctetString()); break; case 3: // optional sname = new PrincipalName(s.Sub[0]); break; case 4: // optional from = s.Sub[0].GetTime(); break; case 5: till = s.Sub[0].GetTime(); break; case 6: // optional rtime = s.Sub[0].GetTime(); break; case 7: nonce = Convert.ToUInt32(s.Sub[0].GetInteger()); break; case 8: //etypes = new Enums.KERB_ETYPE[s.Sub[0].Sub.Length]; etypes = new List <Interop.KERB_ETYPE>(); for (int i = 0; i < s.Sub[0].Sub.Length; i++) { //etypes[i] = (Enums.KERB_ETYPE)Convert.ToUInt32(s.Sub[0].Sub[i].GetInteger()); etypes.Add((Interop.KERB_ETYPE)Convert.ToUInt32(s.Sub[0].Sub[i].GetInteger())); } break; case 9: // addresses (optional) break; case 10: // enc authorization-data (optional) break; case 11: // additional-tickets (optional) break; default: break; } } }