public static byte[] NewTGSReq(string userName, string domain, string sname, Ticket providedTicket, byte[] clientKey, Interop.KERB_ETYPE paEType, Interop.KERB_ETYPE requestEType = Interop.KERB_ETYPE.subkey_keymaterial, bool renew = false, string s4uUser = "") { TGS_REQ req = new TGS_REQ(); // create the PA-DATA that contains the AP-REQ w/ appropriate authenticator/etc. PA_DATA padata = new PA_DATA(domain, userName, providedTicket, clientKey, paEType); req.padata.Add(padata); // set the username req.req_body.cname.name_string.Add(userName); // the realm (domain) the user exists in req.req_body.realm = domain; // add in our encryption types if (requestEType == Interop.KERB_ETYPE.subkey_keymaterial) { // normal behavior req.req_body.etypes.Add(Interop.KERB_ETYPE.aes256_cts_hmac_sha1); req.req_body.etypes.Add(Interop.KERB_ETYPE.aes128_cts_hmac_sha1); req.req_body.etypes.Add(Interop.KERB_ETYPE.rc4_hmac); req.req_body.etypes.Add(Interop.KERB_ETYPE.rc4_hmac_exp); //req.req_body.etypes.Add(Interop.KERB_ETYPE.des_cbc_crc); } else { // add in the supported etype specified req.req_body.etypes.Add(requestEType); } if (!String.IsNullOrEmpty(s4uUser)) { // constrained delegation yo' PA_DATA s4upadata = new PA_DATA(clientKey, String.Format("{0}@{1}", s4uUser, domain), domain); req.padata.Add(s4upadata); req.req_body.sname.name_type = 1; req.req_body.sname.name_string.Add(userName); req.req_body.kdcOptions = req.req_body.kdcOptions | Interop.KdcOptions.ENCTKTINSKEY; } else { string[] parts = sname.Split('/'); if (parts.Length == 1) { // KRB_NT_SRV_INST = 2 // service and other unique instance (e.g. krbtgt) req.req_body.sname.name_type = 2; req.req_body.sname.name_string.Add(sname); req.req_body.sname.name_string.Add(domain); } else if (parts.Length == 2) { // KRB_NT_SRV_INST = 2 // SPN (sname/server.domain.com) req.req_body.sname.name_type = 2; req.req_body.sname.name_string.Add(parts[0]); req.req_body.sname.name_string.Add(parts[1]); } else if (parts.Length == 3) { // KRB_NT_SRV_HST = 3 // SPN (sname/server.domain.com/blah) req.req_body.sname.name_type = 3; req.req_body.sname.name_string.Add(parts[0]); req.req_body.sname.name_string.Add(parts[1]); req.req_body.sname.name_string.Add(parts[2]); } else { Console.WriteLine("[X] Error: invalid TGS_REQ sname '{0}'", sname); } if (renew) { req.req_body.kdcOptions = req.req_body.kdcOptions | Interop.KdcOptions.RENEW; } } return(req.Encode().Encode()); }
// To request a TGS for a foreign KRBTGT, requires 2 different domains public static byte[] NewTGSReq(string userName, string domain, string targetDomain, Ticket providedTicket, byte[] clientKey, Interop.KERB_ETYPE paEType, Interop.KERB_ETYPE requestEType) { // foreign domain "TGT" request TGS_REQ req = new TGS_REQ(cname: false); // create the PA-DATA that contains the AP-REQ w/ appropriate authenticator/etc. PA_DATA padata = new PA_DATA(domain, userName, providedTicket, clientKey, paEType); req.padata.Add(padata); req.req_body.realm = domain; // add in our encryption types if (requestEType == Interop.KERB_ETYPE.subkey_keymaterial) { // normal behavior req.req_body.etypes.Add(Interop.KERB_ETYPE.aes256_cts_hmac_sha1); req.req_body.etypes.Add(Interop.KERB_ETYPE.aes128_cts_hmac_sha1); req.req_body.etypes.Add(Interop.KERB_ETYPE.rc4_hmac); req.req_body.etypes.Add(Interop.KERB_ETYPE.rc4_hmac_exp); //req.req_body.etypes.Add(Interop.KERB_ETYPE.des_cbc_crc); } else { // add in the supported etype specified req.req_body.etypes.Add(requestEType); } PA_DATA padataoptions = new PA_DATA(false, true, false, false); req.padata.Add(padataoptions); req.req_body.sname.name_type = 2; req.req_body.sname.name_string.Add("krbtgt"); req.req_body.sname.name_string.Add(targetDomain); req.req_body.kdcOptions = req.req_body.kdcOptions | Interop.KdcOptions.CANONICALIZE | Interop.KdcOptions.FORWARDABLE; req.req_body.kdcOptions = req.req_body.kdcOptions & ~Interop.KdcOptions.RENEWABLEOK & ~Interop.KdcOptions.RENEW; return(req.Encode().Encode()); }