📄 kerberos_func.inc
字号:
enc_part = seq[6]; if (!enc_part) return NULL; # ENC-Part is a SEQUENCE seq = der_parse_sequence (seq:enc_part, num:3, list:FALSE); if (isnull(seq)) return NULL; # Encryption type enc_type = der_parse_int (i:seq[0]); if (isnull(enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) return NULL; # (OPTIONAL) Kvno == 2 kvno = der_parse_int (i:seq[1]); if (kvno && ((kvno != 2) && (kvno != 1))) return NULL; # encrypted data encrypted = der_parse_octet_string (string:seq[2]); if (!encrypted) return NULL; # We have enc-part in _encrypted[1] here. realm = der_parse_data(tag:0x1b, data:crealm); seq = der_parse_sequence (seq:cname, num:5, list:FALSE); if (isnull(seq)) return NULL; seq = der_parse_sequence (seq:seq[1], num:5, list:TRUE); if (isnull(seq)) return NULL; principal = der_parse_data(tag:0x1b, data:seq[1]); decrypted = kerberos_decrypt (key:password, type:raw_dword(d:8), data:encrypted, real_key:real_key, enc_type:enc_type, realm:realm, principal:principal); if (isnull(decrypted)) return NULL; enc_part = der_decode (data:decrypted); if (isnull(enc_part) || ((enc_part[0] != 0x79) && (enc_part[0] != 0x7A))) return NULL; enc_part = der_parse_sequence (seq:enc_part[1], num:12, list:FALSE); if (isnull (enc_part)) return NULL; enc_key = der_parse_sequence (seq:enc_part[0], num:2, list:FALSE); if (isnull (enc_key)) return NULL; # We parse encryption key # Encryption type enc_type = der_parse_int (i:enc_key[0]); if (isnull (enc_type) || (supported_encryption_type(type:enc_type) == FALSE)) return NULL; resp[4] = enc_type; # Encryption key enc_key = der_parse_octet_string (string:enc_key[1]); if (isnull (enc_key)) return NULL; # We store the session key resp[1] = enc_key; return resp;}#---------------------------------------------------------## Function : der_decode_asrep ## Description : Return der decoded AP-REP ##---------------------------------------------------------#function der_decode_asrep (password, data){ return der_decode_kdcrep (type:0x0B, password:password, data:data, real_key:FALSE);}#---------------------------------------------------------## Function : der_decode_tgsrep ## Description : Return der decoded TGS-REP ##---------------------------------------------------------#function der_decode_tgsrep (session, data){ return der_decode_kdcrep (type:0x0D, password:session[1], data:data, real_key:TRUE);}#---------------------------------------------------------## Function : der_encode_apreq ## Description : Return der encoded AP-REQ ##---------------------------------------------------------#function der_encode_apreq (session, req_body, type, _checksum, _seqnum){ local_var list, options, encoded, authenticator, authenticators, checksum, auth, realm, principal, seq, cksum; authenticator = authenticators = checksum = NULL;# checksum[0] = der_encode_int (i:-138);# checksum[1] = der_encode (tag:0x04, data:rc4_hmac_checksum(key:session[1],type:raw_dword(d:6),data:req_body)); realm = der_parse_data(tag:0x1b, data:session[2]); seq = der_parse_sequence (seq:session[3], num:5, list:FALSE); if (isnull(seq)) return NULL; seq = der_parse_sequence (seq:seq[1], num:5, list:TRUE); if (isnull(seq)) return NULL; principal = der_parse_data(tag:0x1b, data:seq[1]); options = der_encode (tag:0x03, data:raw_string (0x00,0x20,0x00,0x00,0x00)); authenticator[0] = der_encode_int(i:5); authenticator[1] = session[2]; authenticator[2] = session[3]; if (!isnull(req_body)) { cksum = kerberos_checksum(key:session[1],type:raw_dword(d:6),data:req_body,real_key:TRUE,realm:realm,principal:principal,enc_type:session[4]); checksum[0] = der_encode_int (i:get_checksum_type(enc_type:session[4])); checksum[1] = der_encode (tag:0x4, data:cksum); authenticator[3] = der_encode_sequence (seq:checksum); } else if (!isnull(_checksum)) authenticator[3] = _checksum; else authenticator[3] = NULL; authenticator[4] = der_encode_int(i:0); authenticator[5] = der_encode_time (time:kerberostime()); if (!isnull(_seqnum)) { authenticator[6] = NULL; authenticator[7] = der_encode_int32 (i:_seqnum); } auth = der_encode_sequence (seq:authenticator); authenticators = der_encode_crypt (key:session[1], type:type, data:der_encode (tag:0x62, data:auth), real_key:TRUE, realm:realm, principal:principal, enc_type:session[4]); list = NULL; list[0] = der_encode_int(i:5); # Pvno = 5 list[1] = der_encode_int(i:0x0E); # MSG-Type = AP-REQ list[2] = options; list[3] = session[0]; list[4] = authenticators; encoded = der_encode_sequence (seq:list); return der_encode (tag:0x6E, data:encoded);}#---------------------------------------------------------## Function : der_encode_tgsreq ## Description : Return der encoded TGS-REQ ##---------------------------------------------------------#function der_encode_tgsreq (session,name){ local_var realm, req_body, encoded, padata, service, apreq; realm = der_decode (data:session[2]); service = der_encode_name (type:3, name1:"host", name2:name); # Microsoft uses "cifs" for "host" req_body = der_encode_kdc_req_body (realm:realm[1], service:service); apreq = der_encode_apreq (session:session,req_body:req_body,type:7); padata = der_encode_padata (type:1, value:apreq); encoded = der_encode_kdcreq (pvno:5, msg_type:0x0C, list:padata, req_body:req_body); return der_encode (tag:0x6C, data:encoded);}#---------------------------------------------------------## Function : der_encode_negtokeninit ## Description : Return der encoded NegTokenInit ##---------------------------------------------------------## ## NegTokenInit ::= SEQUENCE { ## mechTypes [0] MechTypeList OPTIONAL, ## reqFlags [1] ContextFlags OPTIONAL, ## mechToken [2] OCTET STRING OPTIONAL, ## mechListMIC [3] OCTET STRING OPTIONAL ## } ## # #---------------------------------------------------------#function der_encode_negtokeninit (mechtypes, reqflags, mechtoken, mechlistmic){ local_var seq, encoded, list, negtokeninit, spnego_oid; encoded = list = NULL; if (mechtypes) list[0] = mechtypes; if (reqflags) list[1] = reqflags; if (mechtoken) list[2] = mechtoken; if (mechlistmic) list[3] = mechlistmic; seq = der_encode_sequence (seq:list); # NegTokenInit Tag = 0xA0 negtokeninit = der_encode (tag:0xA0, data:seq); # SPNEGO OID spnego_oid = der_encode_oid (oid:"1.3.6.1.5.5.2"); # Application Constructed Object Tag = 0x60 return der_encode (tag:0x60, data: spnego_oid + negtokeninit);}#---------------------------------------------------------## Function : der_parse_spnego_init ## Description : Return der decoded SPNEGO BLOB ##---------------------------------------------------------#function der_parse_spnego_init (sdata){ local_var tmp, data, oid, list, seq, mechtypes, mechseq, mechlistmic; local_var negtokeninit; data = der_parse_data (tag:0x60, data:sdata); if (isnull(data)) return NULL; list = der_parse_list (list:data); if (isnull(list) || (list[0] != 2)) return NULL; oid = der_parse_oid (oid:list[1]); if (!oid || (oid != "1.3.6.1.5.5.2")) return NULL; negtokeninit = NULL; negtokeninit[0] = negtokeninit[1] = negtokeninit[2] = negtokeninit[4] = NULL; # negTokenInit data = der_parse_data (tag:0xA0, data:list[2]); if (data) { seq = der_parse_sequence (seq:data, num:4, list:FALSE); if (isnull(seq)) return NULL; #mechType if (seq[0] != NULL) { mechtypes = der_parse_list_oid (list:seq[0]); if (!mechtypes) return NULL; negtokeninit[0] = mechtypes; } #mechListMIC if (seq[3] != NULL) { mechseq = der_parse_sequence (seq:seq[3], num:1, list:FALSE); if (isnull (mechseq)) return NULL; tmp = der_decode (data:mechseq[0]); if (isnull(tmp) || (tmp[0] != 0x1B)) return NULL; mechlistmic = tmp[1]; negtokeninit[3] = mechlistmic; } } else return NULL; return negtokeninit;}#---------------------------------------------------------## Function : der_parse_spnego_resp ## Description : Return der decoded SPNEGO BLOB ##---------------------------------------------------------#function der_parse_spnego_resp (sdata){ local_var data, seq, negresult, supportedmech, responsetoken; local_var negtokentarg; negtokentarg = NULL; negtokentarg[0] = negtokentarg[1] = negtokentarg[2] = negtokentarg[3] = NULL; data = der_parse_data (tag:0xA1, data:sdata); if (isnull(data)) return NULL; seq = der_parse_sequence (seq:data, num:4, list:FALSE); if (isnull(seq)) return NULL; #negresult if (seq[0] != NULL) { negresult = der_parse_data (tag:0x0A,data:seq[0]); if (isnull (negresult)) return NULL; negresult = ord(negresult[0]); negtokentarg[0] = negresult; } if (seq[1] != NULL) { supportedmech = der_parse_oid (oid:seq[1]); if (!supportedmech) return NULL; negtokentarg[1] = supportedmech; } if (seq[2] != NULL) { responsetoken = der_parse_data (tag:0x04, data:seq[2]); if (!responsetoken) return NULL; negtokentarg[2] = responsetoken; } return negtokentarg;}function acquired_ticket (){ if (get_kb_item ("SMB/kerberos/tgs_ticket")) return 1; else return 0;}function save_tgs_session (session){ set_kb_item (name:"SMB/kerberos/tgs_session_0", value:hexstr(session[0])); set_kb_item (name:"SMB/kerberos/tgs_session_1", value:hexstr(session[1])); set_kb_item (name:"SMB/kerberos/tgs_session_2", value:hexstr(session[2])); set_kb_item (name:"SMB/kerberos/tgs_session_3", value:hexstr(session[3])); set_kb_item (name:"SMB/kerberos/tgs_session_4", value:session[4]); set_kb_item (name:"SMB/kerberos/tgs_ticket", value:1);}function _hex2raw(s){ local_var i, j, ret, l; s = chomp(s); # remove trailing blanks, CR, LF... l = strlen(s); for(i=0;i<l;i+=2) { if(ord(s[i]) >= ord("0") && ord(s[i]) <= ord("9")) j = int(s[i]); else j = int((ord(s[i]) - ord("a")) + 10); j *= 16; if(ord(s[i+1]) >= ord("0") && ord(s[i+1]) <= ord("9")) j += int(s[i+1]); else j += int((ord(s[i+1]) - ord("a")) + 10); ret += raw_string(j); } return ret;}function load_tgs_session (){ local_var session; session[0] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_0")); session[1] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_1")); session[2] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_2")); session[3] = _hex2raw(s:get_kb_item ("SMB/kerberos/tgs_session_3")); session[4] = get_kb_item ("SMB/kerberos/tgs_session_4"); return session;}#---------------------------------------------------------## Function : kerberos_securityblob ## Description : Return kerberos/GSSAPI/SPNEGO blob ##---------------------------------------------------------#function kerberos_securityblob (login,password,realm,host){ local_var ret, mechtypes, mechtoken, apreq, soc2, pass, req, resp, session, i; # We only support Microsoft Kerberos # mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.2.840.48018.1.2.2") + der_encode_oid (oid:"1.2.840.113554.1.2.2")); mechtypes = der_encode (tag:0x30, data:der_encode_oid (oid:"1.2.840.48018.1.2.2")); if (!acquired_ticket()) { soc2 = open_sock_kdc (); if (isnull (soc2)) return NULL; pass = NULL; for (i = 0; i < strlen (password); i++) pass += password[i] + raw_string(0x00); req = der_encode_asreq (principal:login, realm:realm, password:pass, enc_type:23); send (socket:soc2, data:req); resp = recv (socket:soc2, length:4096); if (!resp) { close (soc2); return NULL; } session = der_decode_asrep(password:pass, data:resp); if (isnull(session)) { close (soc2); return NULL; } req = der_encode_tgsreq (session:session,name:host); send (socket:soc2, data:req); resp = recv (socket:soc2, length:4096); close (soc2); if (!resp) return NULL; session = der_decode_tgsrep(session:session, data:resp); if (isnull (session)) return NULL; save_tgs_session(session:session); } else { session = load_tgs_session(); } apreq = der_encode_apreq (session:session, type:11); mechtoken = der_encode_oid (oid:"1.2.840.113554.1.2.2") + raw_word (w:1)+ apreq; mechtoken = der_encode (tag:0x60, data:mechtoken); mechtoken = der_encode_octet_string (string:mechtoken); # MS KRB5 has no init flags and no mechListMIC ret = NULL; ret[0] = session[1]; ret[1] = der_encode_negtokeninit (mechtypes:mechtypes, reqflags:NULL, mechtoken:mechtoken, mechlistmic:NULL); return ret;}#---------------------------------------------------------## Function : check_kerberos_response ## Description : Return 1 if trusted/accepted ##---------------------------------------------------------#function check_kerberos_response (data, key, realm, principal){ local_var negtokentarg, negresult, supportedmech, responsetoken, init, msg, challenge, kerberosblob, name; local_var list, oid, seq, kid, aprep, pvno, msg_type, enc_part, enc_type, encrypted, decrypted, enc_key, ret; negtokentarg = der_parse_spnego_resp (sdata:data); if (isnull (negtokentarg)) return NULL; negresult = negtokentarg[0]; if (negresult != 0) # Accept Complete return NULL; supportedmech = negtokentarg[1]; if ("1.2.840.48018.1.2.2" >!< supportedmech) return NULL; responsetoken = negtokentarg[2]; if (!responsetoken) return NULL; kerberosblob = der_parse_data (tag:0x60, data:responsetoken); if (isnull (kerberosblob)) return NULL; list = der_parse_list (list:kerberosblob); if (isnull (list)) return NULL; if (list[0] != 3) return NULL; oid = der_parse_oid (oid:list[1]); if (!oid || ("1.2.840.113554.1.2.2" >!< oid)) return NULL; kid = list[2];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -