📄 ssh_func.inc
字号:
raw_int32(i:strlen(key_exchange_algo)) + key_exchange_algo + # server host key algorithms (length + string) raw_int32(i:strlen(server_host_key_algo)) + server_host_key_algo + # encryption algorithms client to server (length + string) raw_int32(i:strlen(enc_alg_client_to_server)) + enc_alg_client_to_server + # encryption algorithms server to client (length + string) raw_int32(i:strlen(enc_alg_server_to_client)) + enc_alg_server_to_client + # mac algorithms client to server (length + string) raw_int32(i:strlen(mac_alg_client_to_server)) + mac_alg_client_to_server + # mac algorithms server to client (length + string) raw_int32(i:strlen(mac_alg_server_to_client)) + mac_alg_server_to_client + # compression algorithms client to server (length + string) raw_int32(i:strlen(cmp_alg_client_to_server)) + cmp_alg_client_to_server + # compression algorithms server to client (length + string) raw_int32(i:strlen(cmp_alg_server_to_client)) + cmp_alg_server_to_client + # languages client to server (lenght) raw_int32(i:0) + # languages server to client (lenght) raw_int32(i:0) + # payload crap(data:raw_string(0x00), length:5); # msg code (20 = key exchange init) kex = kex_packet(payload:cinit,code:raw_string(0X14)); send(socket:socket, data:kex); seqn_w++; register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w); if (groupex) { ### Key exchange Request : Diffie-Hellman GEX Request ### payload = raw_string(0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x20,0x00); # msg code (34 = Diffie-Hellman GEX Request) kexr = kex_packet(payload:payload,code:raw_string(34)); send(socket:socket, data:kexr); seqn_w++; register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w); ### Key exchange Reply : Diffie-Hellman Key Exchange Reply ### skexr = ssh_recv(socket:socket, length:1000); # code = 31 (Diffie-Hellman Key Exchange Reply) payload = packet_payload(packet:skexr, code:31); if (!payload) { set_ssh_error(msg:"Received code was not SSH_MSG_KEXDH_REPLY (31)"); return -1; } # get p bignum for dh group p = getstring (buffer:payload,pos:0); # get g bignum for dh group start = 4+strlen(p); g = getstring(buffer:payload,pos:start); } else { p = raw_string (0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF); g = raw_int8(i:2); } # generate public and private keys ret = dh_gen_key(p:p,g:g); if (ret != 0) { set_ssh_error(msg:"Error during DH keys generation"); return -1; } register_data_in_kb(name:"Secret/SSH/dh_pub", data:dh_pub); register_data_in_kb(name:"Secret/SSH/dh_priv", data:dh_priv);### Diffie Hellman GEX Init ### payload = raw_int32(i:strlen(dh_pub)) + dh_pub; if (groupex) codereq = raw_int8(i:32); else codereq = raw_int8(i:30); # msg code (32 = Diffie-Hellman GEX Init) gex = kex_packet(payload:payload,code:codereq); send(socket:socket, data:gex); seqn_w++; register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w);### Diffie Hellman GEX Reply ### gexr = ssh_recv(socket:socket, length:2000); if (groupex) codereq = 33; else codereq = 31; payload = packet_payload(packet:gexr, code:codereq); if (!payload) { set_ssh_error(msg:"Received code was not SSH_MSG_KEXDH_REPLY (31 or 33)"); return -1; } # server host key blob server_host_key_blob = getstring (buffer:payload,pos:0); # extract server host key alg_type = getstring (buffer:server_host_key_blob, pos:0); next = 4 + strlen(alg_type); if (alg_type >< "ssh-rsa") { # rsa type == 0 type = 0; # e rsa_e = getstring (buffer:server_host_key_blob,pos:next); next = next + 4 + strlen(rsa_e); # n rsa_n = getstring (buffer:server_host_key_blob,pos:next); next = next + 4 + strlen(rsa_n); } else { if (alg_type >< "ssh-dss") { # dsa type == 1 type = 1; # p dsa_p = getstring (buffer:server_host_key_blob,pos:next); next = next + 4 + strlen(dsa_p); # q dsa_q = getstring (buffer:server_host_key_blob,pos:next); next = next + 4 + strlen(dsa_q); # g dsa_g = getstring (buffer:server_host_key_blob,pos:next); next = next + 4 + strlen(dsa_g); # pub key dsa_pub_key = getstring (buffer:server_host_key_blob,pos:next); next = next + 4 + strlen(dsa_pub_key); } else # bad key algo - should not occur { set_ssh_error(msg:"Server's host keys format is not supported"); return -1; } } # server dh public key start = 4 + strlen(server_host_key_blob); server_dh_public_key = getstring(buffer:payload,pos:start); # signed H start = start + 4 + strlen(server_dh_public_key); signed_h = getstring(buffer:payload,pos:start); if (!dh_valid_key(key:server_dh_public_key, p:p)) { set_ssh_error(msg:"Server DH public key is not valid!"); return -1; } # shared secret # shared = dh_compute_key(p:p,g:g,dh_server_pub:server_dh_public_key, pub_key:dh_pub,priv_key:dh_priv); if (!shared) { set_ssh_error(msg:"Error during shared secret computing"); return -1; } # hash data to_hash = # client version putstring(buffer:client_version) + # server version putstring(buffer:server_version) + # client cookie (cookielen,SSH_MSG_KEXINIT,cookie) raw_int32(i:(strlen(cinit)+1)) + raw_int8(i:20) + cinit + # server cookie (cookielen,SSH_MSG_KEXINIT,cookie) raw_int32(i:(strlen(sinit)+1)) + raw_int8(i:20) + sinit + # server host key blob putstring(buffer:server_host_key_blob); if (groupex) { to_hash += # min,wantbits,max raw_string(0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x20,0x00) + # p bignum putbignum(buffer:p) + # g bignum putbignum(buffer:g); } to_hash += # public key bignum putbignum(buffer:dh_pub) + # server dh public key bignum putbignum(buffer:server_dh_public_key) + # shared bignum putbignum(buffer:shared); hash = SHA1(to_hash); if (type == 0) correct = ssh_rsa_verify(e:rsa_e, n:rsa_n, signature:signed_h, data:hash); else # Not implemented correct = ssh_dss_verify(p:dsa_p, q:dsa_q, g:dsa_g, pub:dsa_pub_key, signature:signed_h, data:hash); if (!correct) { set_ssh_error(msg:"Server's signature is not valid!"); return -1; } session_id = hash; register_data_in_kb(name:"Secret/SSH/session_id", data:session_id); enc_keys = derive_keys(hash:hash,shared:shared,session_id:session_id); register_array_in_kb(array:enc_keys, name:"Secret/SSH/enc_keys");### New keys ### nkey = ssh_recv(socket:socket, length:1000); # msg code (21 = New keys) payload = packet_payload(packet:nkey, code:21); if (!payload) { set_ssh_error(msg:"Received code was not SSH_MSG_NEWKEYS (21)"); return -1; } payload = NULL; # msg code (21 = New keys) nk = kex_packet(payload:payload,code:raw_string(0x15)); send(socket:socket, data:nk); seqn_w++; register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w); # all is correct return 0; }#-----------------------------------------------------------------## Authenticate to SSH server ##-----------------------------------------------------------------#function ssh_userauth2(socket, server_user, password, pub, priv, passphrase){ local_var payload, buf, support, pass, pkey, kb, authenticated, blobpub, signature, blobpriv, privkey, typestr, next, e, n, hash2, hash, public, line, num, pubtab, i, crap, kb_ok; pass = pkey = authenticated = kb = 0; payload = putstring(buffer:"ssh-userauth"); # code 5 (SSH_MSG_SERVICE_REQUEST) send_ssh_packet(socket:socket, payload:payload, code:raw_string(0x05)); # code 6 (SSH_MSG_SERVICE_ACCEPT) payload = recv_ssh_packet(socket:socket); if (ord(payload[0]) != 6) { set_ssh_error(msg:string("Server does not support ssh-userauth service. Received code was : " , ord(payload[0]))); return -1; } # service accepted # code 50 (SSH_MSG_USERAUTH_REQUEST) # none request: we need to know what authentication server supports payload = putstring(buffer:server_user) + putstring(buffer:"ssh-connection") + putstring(buffer:"none"); send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:50)); # (51 == SSH_MSG_USERAUTH_FAILURE) payload = recv_ssh_packet(socket:socket); if (ord(payload[0]) != 51) { set_ssh_error(msg:string("Server did not reject none authentication method. Received code was : " , ord(payload[0]))); return -1; } support = getstring(buffer:payload,pos:1); _ssh_supported_authentication = support; if (pub && priv) { if (ereg(string:support, pattern:"publickey")) pkey = 1; else { set_ssh_error(msg:string("Error : Remote server does not support publickey authentication method! It supports : " , support)); return -1; } } else if (password) { if (ereg(string:support, pattern:"password")) pass = 1; else if (ereg(string:support, pattern:"keyboard-interactive")) kb = 1; else { set_ssh_error(msg:string("Error : Remote server does not support one of the following password authentication methods : password, keyboard-interactive. It supports : " , support)); return -1; } } else { set_ssh_error(msg:"OpenVAS needs public and private keys or a password!"); return -1; } if (pass) { # code 50 (SSH_MSG_USERAUTH_REQUEST) ###### need extra pad !!!! ###### ###### Is it usefull ?? ##### payload = putstring(buffer:server_user) + putstring(buffer:"ssh-connection") + putstring(buffer:"password") + raw_int8(i:0) + putstring(buffer:password) ; send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:50)); # code 52 (SSH_MSG_USERAUTH_SUCCESS) payload = recv_ssh_packet(socket:socket); if (ord(payload[0]) == 52) authenticated = 1; if (!authenticated) { set_ssh_error(msg:"Password authentication failed"); return -1; } } else if (kb) { # code 50 (SSH_MSG_USERAUTH_REQUEST) payload = putstring(buffer:server_user) + putstring(buffer:"ssh-connection") + putstring(buffer:"keyboard-interactive") + putstring(buffer:"en-US") + putstring(buffer:"") ; send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:50)); # code 60 (SSH_MSG_USERAUTH_INFO_REQUEST) payload = recv_ssh_packet(socket:socket); if (ord(payload[0]) != 60) { set_ssh_error(msg:string("Server did not reply with SSH_MSG_USERAUTH_INFO_REQUEST during keyboard-interactive exchange. It replied with :", ord(payload[0]))); return -1; } # Method name crap = getstring (buffer:payload,pos:1); next = 1 + 4 + strlen(crap); # Method name complement crap = getstring (buffer:payload,pos:next); next = next + 4 + strlen(crap); # Language crap = getstring (buffer:payload,pos:next); next = next + 4 + strlen(crap); # Number of request num = ntol(buffer:payload, begin:next); next += 4; kb_ok = 0; if (num > 0) { crap = getstring (buffer:payload,pos:next); if ("Password: " >< crap) kb_ok = 1; } if (!kb_ok) { set_ssh_error(msg:"Remote server keyboard-interactive method does not support Password."); return -1; } # code 61 (SSH_MSG_USERAUTH_INFO_RESPONSE) payload = raw_int32(i:1) + putstring(buffer:password); send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:61)); payload = recv_ssh_packet(socket:socket); # From draft-ietf-secsh-auth-kbdinteract-06.txt document : # Server should now send SSH_MSG_USERAUTH_INFO_REQUEST. # REQUEST can ask additionnal informations (like a new password). # But if all is correct num-prompts is set to 0 and client must # reply with an empty SSH_MSG_USERAUTH_INFO_RESPONSE. # So we just send an empty response and look if authentication # works. If remote server asked for additionnal informations, # authentication will just failed. if (ord(payload[0]) == 60) { # code 61 (SSH_MSG_USERAUTH_INFO_RESPONSE) payload = raw_int32(i:0); send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:61)); payload = recv_ssh_packet(socket:socket); } if (ord(payload[0]) != 52) { set_ssh_error(msg:string("Server did not reply with SSH_MSG_USERAUTH_SUCCESS during keyboard-interactive exchange. It replied with :",ord(payload[0]))); return -1; } authenticated = 1; } else if (!authenticated && pkey) { # SSH Public Key File Format (draft-ietf-secsh-publickeyfile-05.txt) # ---- BEGIN SSH2 PUBLIC KEY ---- # Comment: "1024-bit RSA, converted from OpenSSH by galb@test1" # AAAAB3NzaC1yc2EAAAABIwAAAIEA1on8gxCGJJWSRT4uOrR13mUaUk0hRf4RzxSZ1zRbYY # Fw8pfGesIFoEuVth4HKyF8k1y4mRUnYHP1XNMNMJl1JcEArC2asV8sHf6zSPVffozZ5TT4 # SfsUu/iKy9lUcCfXzwre4WWZSXXcPff+EHtWshahu3WzBdnGxm5Xoi89zcE= # ---- END SSH2 PUBLIC KEY ---- if ("---" >< pub) { public = ""; pubtab = split(pub, sep:'\n', keep:0); num = max_index(pubtab); for (i=0; i<num; i++) { line = pubtab[i]; if (("---" >!< line) && (":" >!< line)) { if ('\r' >< line) line -= '\r'; public += line; } } } else { # OpenSSH Public key file format public = ereg_replace(pattern:"[^ ]* ([^ ]*) [^ ]*$", string:pub, replace:"\1"); } blobpub = base64decode(str:public); # code 50 (SSH_MSG_USERAUTH_REQUEST) ###### need extra pad !!!! ###### ###### Is it usefull ?? ##### payload = putstring(buffer:server_user) + putstring(buffer:"ssh-connection") + putstring(buffer:"publickey") + raw_int8(i:1) ; to_hash = putstring(buffer:session_id) + raw_int8(i:50); typestr = getstring(buffer:blobpub, pos:0); if ("ssh-rsa" >< typestr) { next = 4 + strlen(typestr); e = getstring(buffer:blobpub, pos:next); next = next + 4 + strlen(e); n = getstring(buffer:blobpub, pos:next); privkey = pem_to_rsa(priv:priv, passphrase:passphrase); if (!privkey) { set_ssh_error(msg:"OpenVAS failed to load SSH private key (RSA)"); return -1; } payload += putstring(buffer:"ssh-rsa") + putstring(buffer:blobpub); to_hash += payload; hash = SHA1(to_hash); # FIXME: rsa_sign was changed to use the private key in priv # directly. The above code to extract the parameters n, e and # privkey can probably be removed. signature = rsa_sign(priv:priv, passphrase:passphrase, data:hash); if (!signature)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -