📄 ssh_func.inc
字号:
#-----------------------------------------------------------------## decrypt data ##-----------------------------------------------------------------#function decrypt(data){ local_var decrypted; decrypted = bf_cbc_decrypt(data:data, key:enc_keys[3], iv:enc_keys[1]); enc_keys[1] = decrypted[1]; register_array_in_kb(array:enc_keys, name:"Secret/SSH/enc_keys"); return decrypted[0];}#-----------------------------------------------------------------## Send ssh packet ##-----------------------------------------------------------------#function send_ssh_packet(socket,payload,code){ local_var i, len, padding_len, full_len, buf, res, macbuf, crypted; len = # padding length 1 + # msg code 1 + # payload length strlen(payload); #padding (mod 8) = 8 - ( (len+packet_len(4) ) % 8 ) padding_len = 8 - ((len + 4) % 8); # if padding len is less than 4 add block size if (padding_len < 4) padding_len += 8; full_len = len + padding_len; padding = ""; for (i=0;i<padding_len;i++) padding = padding + raw_int8(i:(rand() % 256)); buf = # packet length raw_int32 (i:full_len) + # padding length raw_int8 (i:padding_len) + #msg code (32 = Diffie-Hellman GEX Init) code + # Payload (Pub key) payload + # Padding padding; macbuf = mac_compute(data:buf, type:0); crypted = crypt(data:buf); buf = crypted + macbuf; send(socket:socket, data:buf); seqn_w++; register_int_in_kb(name:"Secret/SSH/seqn_w", int:seqn_w);}#-----------------------------------------------------------------## Receive ssh packet ##-----------------------------------------------------------------#function recv_ssh_packet(socket, timeout){ local_var len, need, padding_len, full_len, buf, res, macbuf, decrypted; local_var hmac, hmacbuf, mac, payload, ret; payload = raw_int8(i:0); # blockbytes = 8 for blowfish-cbc buf = recv(socket:socket, length:8, min:8, timeout:timeout); if (strlen(buf) != 8) return payload; decrypted = decrypt(data:buf); len = ntol(buffer:decrypted, begin:0); # Maximum packet size is 32768 bytes if (len > 32768) return payload; # 8 = blocksize ... i know it is not generic and it will be hard to change all need = 4 + len - 8; buf = recv(socket:socket, length:need, min:need, timeout:timeout); if (strlen(buf) != need) return payload; decrypted = decrypted + decrypt(data:buf); # hmac-sha1 length = 20 ... same comment as before mac = recv(socket:socket, length:20, min:20, timeout:timeout); if (strlen(mac) != 20) return payload; macbuf = mac_compute(data:decrypted, type:1); hmac = hexstr(mac); hmacbuf = hexstr(macbuf); if (hmac >!< hmacbuf) return payload; payload = substr(decrypted, 5, strlen(decrypted)-ord(decrypted[4])-1); seqn_r++; register_int_in_kb(name:"Secret/SSH/seqn_r", int:seqn_r); # SSH servers can send IGNORE (code 2) or BANNER (code 53) msg ret = ord(payload[0]); if ((ret == 2) || (ret == 53) || ret == 4) { if (ret == 53) _ssh_banner += getstring (buffer:payload, pos:1); return recv_ssh_packet(socket:socket, timeout:timeout); } return payload;}#-----------------------------------------------------------------## Get payload from packet ##-----------------------------------------------------------------#function packet_payload(packet,code){ local_var packetlen, paddinglen, msgcode; packetlen = ntol(buffer:packet, begin:0); paddinglen = ord(packet[4]); msgcode = ord(packet[5]); # Diffie-Hellman Key Exchange Reply if (msgcode != code) return 0; payload = substr(packet,6,packetlen-1); return payload;}#-----------------------------------------------------------------## Get string (length,string) ##-----------------------------------------------------------------#function getstring(buffer,pos){ local_var buf_len, buf; buf_len = ntol (buffer:buffer,begin:pos); buf = substr(buffer,pos+4,pos+4+buf_len-1); return buf;}#-----------------------------------------------------------------## Put string (string) ##-----------------------------------------------------------------#function putstring(buffer){ local_var buf; buf = raw_int32(i:strlen(buffer)) + buffer; return buf;}#-----------------------------------------------------------------## Put bignum (string) ##-----------------------------------------------------------------#function putbignum(buffer){ local_var len, buf; if (ord(buffer[0]) & 0x80) { len = strlen(buffer)+1; buf = raw_int32(i:len) + raw_string(0x00) + buffer; } else buf = raw_int32(i:strlen(buffer)) + buffer; return buf;}#-----------------------------------------------------------------## RSA verify signature ##-----------------------------------------------------------------#function ssh_rsa_verify(e, n, signature, data){ local_var hash, id_sha1, sigtype, nlen, next, tmp_sig, siglen, len, sig, hdecoid, hshaoid, hhash, decrypted ;#comes directly from OpenBSD id_sha1 = raw_string( 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 ); if (!n) return 0; sigtype = getstring(buffer:signature, pos:0); if (sigtype >!< "ssh-rsa") return 0; nlen = strlen(n); if (ord(n[0]) == 0) nlen--; # check minimum n size if ( (nlen*8) < 768 ) return 0; next = 4 + strlen(sigtype); tmp_sig = getstring(buffer:signature,pos:next); siglen = strlen(tmp_sig); # bad signature (should be less than n) if (siglen > nlen) return 0; # Add padding if needed if (siglen < nlen) { len = nlen - siglen; sig = crap(data:raw_string(0x00), length:len) + tmp_sig; } else sig = tmp_sig; hash = SHA1(data); if (strlen(hash) != 20) return 0; # must call RSA_public_decrypt from openssl, so convert arg - see ssh-rsa.c decrypted = rsa_public_decrypt(sig:sig,e:e,n:n); if (!decrypted) return 0; if (strlen(decrypted) != (strlen(id_sha1)+20)) return 0; hdecoid = hexstr(substr(decrypted,0,strlen(id_sha1)-1)); hshaoid = hexstr(id_sha1); if (hdecoid >!< hshaoid) return 0; hdecoid = hexstr(substr(decrypted,strlen(id_sha1),strlen(decrypted)-1)); hhash = hexstr(hash); if (hdecoid >!< hhash) return 0; return 1;}#-----------------------------------------------------------------## DSA verify signature ##-----------------------------------------------------------------#function ssh_dss_verify(p, q, g, pub, signature, data){ local_var sigtype, next, tmp_sig, siglen, r, s, hash; sigtype = getstring(buffer:signature, pos:0); if (sigtype >!< "ssh-dss") return 0; next = 4 + strlen(sigtype); tmp_sig = getstring(buffer:signature,pos:next); siglen = strlen(tmp_sig); r = substr(tmp_sig, 20, 39); s = substr(tmp_sig, 40, 59); hash = SHA1(data); return dsa_do_verify(p:p,g:g,q:q,pub:pub,r:r,s:s,data:hash);}#-----------------------------------------------------------------## Derive keys (this function works because we only use sha1 and ## blowfish so keylen is 20 due to sha1) ##-----------------------------------------------------------------#function derive_keys(hash,shared,session_id){ local_var c, i, to_hash, keys; # c = 'A'; c = 65; for (i = 0;i < 6; i++) { to_hash = putbignum(buffer:shared) + hash + raw_int8(i:c) + session_id; keys[i] = SHA1(to_hash); c++; } # MODE OUT MODE IN # enc.iv 0 1 # enc.key 2 3 # mac.key 4 5 return keys;}#-----------------------------------------------------------------## Check is public key is correct ##-----------------------------------------------------------------#function dh_valid_key(key, p){ local_var val,i; if (ord(key[0]) > 0x80) return 0; val = 0; for(i=0;i<strlen(key);i++) { val = val + ord(key[i]); if (val > 1) break; } # ok if key < p if ((val>1) && (bn_cmp(key1:key,key2:p) == -1)) return 1; return 0;}#-----------------------------------------------------------------## Generate dh public & private keys ##-----------------------------------------------------------------#function dh_gen_key(p, g){ local_var tries,keys; dh_pub = dh_priv = ""; tries = 0; if (!p) return keys; # { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc } # hash = sha1 = 20 (len) = 20 * 8 (bits) need = 20 * 8; # need won't be > than INT_MAX / 2 # maybe we must test if 2*need >= numbits ... #if (need > INT_MAX / 2 || 2 * need >= BN_num_bits(dh->p)) # return keys; for (tries = 0; tries < 10; tries++) { dh_priv = bn_random(need:(need*2)); if (!dh_priv) return -1; dh_pub = dh_generate_key(p:p, g:g, priv:dh_priv); if (!dh_pub) return -1; if (dh_valid_key(key:dh_pub, p:p)) break; } if (tries++ >= 10) return -1; return 0;}#-----------------------------------------------------------------## Waits for the server identification string, and sends our own ## identification string. ##-----------------------------------------------------------------#function ssh_kex2(socket,server_version){ local_var packetlen, paddinglen, msgcode, len, len2; local_var a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p; local_var skexkex, kexr, skexr, gex, gexr, nk, nkey; local_var sinit, scookie, ccookie, cinit; local_var payload; local_var keys, server_host_key_blob, shared; local_var alg_type, type; local_var start, next, correct, groupex; local_var rsa_e, rsa_n, dsa_p, dsa_q, dsa_g, dsa_pub_key; local_var server_dh_public_key, signed_h, to_hash, hash; # supported algorithms key_exchange_algo = "diffie-hellman-group-exchange-sha1,diffie-hellman-group1-sha1"; server_host_key_algo = "ssh-rsa,ssh-dss"; enc_alg_client_to_server = "blowfish-cbc"; enc_alg_server_to_client = "blowfish-cbc"; mac_alg_client_to_server = "hmac-sha1"; mac_alg_server_to_client = "hmac-sha1"; cmp_alg_client_to_server = "none"; cmp_alg_server_to_client = "none"; # version client_version = "SSH-2.0-OpenVAS";### Key exchange send client Init ### skex = ssh_recv(socket:socket, length:2000); packetlen = ntol (buffer:skex, begin:0); paddinglen = ord(skex[4]); msgcode = ord(skex[5]); if (msgcode != 20) { set_ssh_error(msg:string("Received code was not SSH_MSG_KEXINIT (20). It was : ", msgcode)); return -1; } sinit = substr(skex,6,packetlen+4-paddinglen-1); scookie = substr(skex,6,21); len = check_pattern(buffer:skex, pattern:"diffie-hellman-group-exchange-sha1", length:22); if (len == -1) { len = check_pattern(buffer:skex, pattern:"diffie-hellman-group1-sha1", length:22); if (len == -1) { set_ssh_error(msg:"Remote SSH server does not support DH exchanges (bugged ?)"); return -1; } groupex = 0; } else { groupex = 1; } len2 = check_pattern(buffer:skex, pattern:"ssh-rsa", length:len); if (len2 == -1) { len2 = check_pattern(buffer:skex, pattern:"ssh-dss", length:len); if (len2 == -1) { set_ssh_error(msg:"Remote SSH server does not support DSA and RSA (bugged ?)"); return -1; } } len = check_pattern(buffer:skex, pattern:enc_alg_client_to_server, length:len2); if (len == -1) { set_ssh_error(msg:"Remote SSH server does not support blowfish-cbc encryption"); return -1; } len2 = check_pattern(buffer:skex, pattern:enc_alg_server_to_client, length:len); if (len2 == -1) { set_ssh_error(msg:"Remote SSH server does not support blowfish-cbc encryption"); return -1; } len = check_pattern(buffer:skex, pattern:mac_alg_client_to_server, length:len2); if (len == -1) { set_ssh_error(msg:"Remote SSH server does not support hmac-sha1 encryption"); return -1; } len2 = check_pattern(buffer:skex, pattern:mac_alg_server_to_client, length:len); if (len2 == -1) { set_ssh_error(msg:"Remote SSH server does not support hmac-sha1 encryption"); return -1; } len = check_pattern(buffer:skex, pattern:cmp_alg_client_to_server, length:len2); if (len == -1) { set_ssh_error(msg:"Remote SSH server only supports compressed packets"); return -1; } len2 = check_pattern(buffer:skex, pattern:cmp_alg_server_to_client, length:len); if (len2 == -1) { set_ssh_error(msg:"Remote SSH server only supports compressed packets"); return -1; }### Key exchange recv server Init ### ccookie = ""; for (i=0;i<16;i++) ccookie = ccookie + raw_int8(i:(rand() % 256)); cinit = # cookie (random) ccookie + # key algorithms (length + string)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -