[Openvas-commits] r1340 - trunk/openvas-plugins/scripts

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Fri Sep 12 14:58:50 CEST 2008


Author: reinke
Date: 2008-09-12 14:58:49 +0200 (Fri, 12 Sep 2008)
New Revision: 1340

Removed:
   trunk/openvas-plugins/scripts/ss_ssh_func.inc
Log:
Removed ss_ssh_func.inc

Deleted: trunk/openvas-plugins/scripts/ss_ssh_func.inc
===================================================================
--- trunk/openvas-plugins/scripts/ss_ssh_func.inc	2008-09-12 12:57:14 UTC (rev 1339)
+++ trunk/openvas-plugins/scripts/ss_ssh_func.inc	2008-09-12 12:58:49 UTC (rev 1340)
@@ -1,2036 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# (C) Nicolas Pouvesle
-# This script is released under the version 2 to the Gnu General Public Licence
-#
-#
-#
-#
-
-global_var session_id, enc_keys, seqn_w, seqn_r;
-global_var local_channel, remote_channel;
-global_var l_window_size, received_size;
-global_var r_window_size, r_packet_size;
-global_var dh_pub, dh_priv;
-global_var _ssh_banner;
-global_var _ssh_server_version;
-global_var _ssh_supported_authentication;
-global_var _ssh_cmd_error;
-global_var _ssh_error;
-global_var _reuse_connection;
-global_var bugged_sshd, bugged_first, bugged_channels, bugged_rws, bugged_rps;
-
-
-# ssh_hex2raw() copied from misc_func.inc as we don't want to taint ssh_func.inc with
-# a third-party include
-function ssh_hex2raw(s)
-{
- local_var i, j, ret, l;
-
- s = chomp(s);  # remove trailing blanks, CR, LF...
- l = strlen(s);
- if (l % 2) display("ssh_hex2raw: odd string: ", s, "\n");
- 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 register_int_in_kb(int, name)
-{
- if ( ! defined_func("replace_kb_item") || !_reuse_connection ) return 0;
- replace_kb_item(name:name, value:int);
-}
-
-function load_int_from_kb(name)
-{
- if ( ! defined_func("get_kb_fresh_item") || !_reuse_connection ) return NULL;
- return get_kb_fresh_item(name);
-}
-
-function register_data_in_kb(data, name)
-{
- local_var n, item;
- n = 0;
- if ( ! defined_func("replace_kb_item") || !_reuse_connection ) return 0;
- replace_kb_item(name:name, value:hexstr(data));
-}
-
-function load_data_from_kb(name)
-{
- local_var item;
- if ( ! defined_func("get_kb_fresh_item") || !_reuse_connection ) return NULL;
- item =  get_kb_fresh_item(name);
- if ( isnull(item) ) return NULL;
- return ssh_hex2raw(s:item);
-}
-
-function register_array_in_kb(array, name)
-{
- local_var i, item;
- if ( ! defined_func("replace_kb_item") || !_reuse_connection ) return 0;
- for ( i = 0 ; i < max_index(array); i ++ )
- {
-  replace_kb_item(name:name + "_" + i, value:hexstr(array[i]));
- }
-}
-
-function register_intarray_in_kb(array, name)
-{
- local_var i, item;
- if ( ! defined_func("replace_kb_item") || !_reuse_connection ) return 0;
- for ( i = 0 ; i < max_index(array); i ++ )
- {
-  replace_kb_item(name:name + "_" + i, value:string(array[i]));
- }
-}
-
-function load_array_from_kb(name)
-{
- local_var array, n, item;
-
- if ( ! defined_func("get_kb_fresh_item") || !_reuse_connection ) return NULL;
- n = 0;
- array = make_list();
- while ( TRUE )
- {
-  item = get_kb_fresh_item(name + "_" + n );
-  if ( isnull(item) ) break;
-  array[n] = ssh_hex2raw(s:item);
-  n ++;
- }
-
- return array;
-}
-
-function load_intarray_from_kb(name)
-{
- local_var array, n, item;
-
- if ( ! defined_func("get_kb_fresh_item") || !_reuse_connection ) return NULL;
- n = 0;
- array = make_list();
- while ( TRUE )
- {
-  item = get_kb_fresh_item(name + "_" + n );
-  if ( isnull(item) ) break;
-  array[n] = int(item);
-  n ++;
- }
-
- return array;
-}
-
-function kb_ssh_login()
-{
- return string(get_kb_item("Secret/SSH/login"));
-}
-
-function kb_ssh_password()
-{
- return string(get_kb_item("Secret/SSH/password"));
-}
-
-function kb_ssh_privatekey()
-{
- return string(get_kb_item("Secret/SSH/privatekey"));
-}
-
-function kb_ssh_publickey()
-{
- return string(get_kb_item("Secret/SSH/publickey"));
-}
-
-function kb_ssh_passphrase()
-{
- return string(get_kb_item("Secret/SSH/passphrase"));
-}
-
-function kb_ssh_transport()
-{
- local_var r;
- r = get_kb_item("Services/ssh");
-
- if ( r ) return int(r);
- else return 22;
-}
-
-
-#-----------------------------------------------------------------#
-# Set SSH debugging error msg                                     #
-#-----------------------------------------------------------------#
-function set_ssh_error(msg)
-{
- _ssh_error = msg;
-}
-
-
-#-----------------------------------------------------------------#
-# Get SSH debugging error msg                                     #
-#-----------------------------------------------------------------#
-function get_ssh_error()
-{
- return _ssh_error;
-}
-
-
-#-----------------------------------------------------------------#
-# Get SSH server's version                                        #
-#-----------------------------------------------------------------#
-function get_ssh_supported_authentication()
-{
- return _ssh_supported_authentication;
-}
-
-
-#-----------------------------------------------------------------#
-# Get SSH server's version                                        #
-#-----------------------------------------------------------------#
-function get_ssh_server_version()
-{
- return _ssh_server_version;
-}
-
-
-#-----------------------------------------------------------------#
-# Get SSH banner                                                  #
-#-----------------------------------------------------------------#
-function get_ssh_banner()
-{
- return _ssh_banner;
-}
-
-
-#-----------------------------------------------------------------#
-# Convert network long (buffer) to long                           #
-#-----------------------------------------------------------------#
-function ntol(buffer,begin)
-{
- local_var len;
-
- len = 16777216*ord(buffer[begin]) +
-       ord(buffer[begin+1])*65536 +
-       ord(buffer[begin+2])*256 +
-       ord(buffer[begin+3]);
-
- return len;
-}
-
-#-----------------------------------------------------------------#
-# Convert int to network long (raw_string)                        #
-#-----------------------------------------------------------------#
-function raw_int32(i)
-{
- local_var buf;
-
- buf = raw_string (
-		 (i>>24) & 255,
-        (i>>16) & 255,
-        (i>>8) & 255,
-        (i) & 255
-		 );
- return buf;
-}
-
-#-----------------------------------------------------------------#
-# Convert char to network char (raw_string)                       #
-#-----------------------------------------------------------------#
-function raw_int8(i)
-{
- local_var buf;
-
- buf = raw_string (
-        (i) & 255
-		 );
- return buf;
-}
-
-
-#-----------------------------------------------------------------#
-# Init packet sequence number and channel number                  #
-#-----------------------------------------------------------------#
-function init()
-{
- # sequence packet = 0
- seqn_w = seqn_r = 0;
- local_channel = 0;
- _ssh_banner = "";
- _ssh_server_version = "";
- _ssh_supported_authentication = "";
- _ssh_cmd_error = "";
- _ssh_error = "";
- bugged_sshd = 0;
- bugged_first = 1;
- register_int_in_kb (int:bugged_sshd, name:"Secret/SSH/bugged_sshd");
- #register_int_in_kb (int:bugged_first, name:"Secret/SSH/bugged_first");
-
-}
-
-
-#-----------------------------------------------------------------#
-# Decode base64 string - ported from public domain code           #
-#-----------------------------------------------------------------#
-function base64decode(str)
-{
- local_var len, i, j, k, ret, base64, b64;
- len = strlen(str);
- ret = "";
-
- base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- for (i = 0; i < 256; i++)
-   b64[i] = 0;
- for (i = 0; i < strlen(base64); i++)
-   b64[ord(base64[i])] = i;
-
- for(j=0;j<len;j+=4)
- {
-   for (i = 0; i < 4; i++)
-   {
-    c = ord(str[j+i]);
-    a[i] = c;
-    b[i] = b64[c];
-   }
- 
-   o[0] = (b[0] << 2) | (b[1] >> 4);
-   o[1] = (b[1] << 4) | (b[2] >> 2);
-   o[2] = (b[2] << 6) | b[3];
-   if (a[2] == ord('='))
-     i = 1;
-   else if (a[3] == ord('='))
-     i = 2;
-   else
-     i = 3;
-   for(k=0;k<i;k++)
-      ret += raw_int8(i:o[k]);
-   
-   if (i < 3) 
-     break;
- }
-
- return ret;
-}
-
-
-#-----------------------------------------------------------------#
-# Reads a SSH packet (comes from smb_nt.inc)                      #
-#-----------------------------------------------------------------#
-function ssh_recv(socket, length)
-{
-  local_var header, len, trailer, cmpt, payload, ret;
-
-  header = recv(socket:socket, length:4, min:4);
-  if (strlen(header) < 4)return(NULL);
-  len = ntol (buffer:header, begin:0);
-  if ((len == 0) || (len > 32768)) return(header);
-  trailer = recv(socket:socket, length:len, min:len);
-  if(strlen(trailer) < len )return(NULL);
- 
-  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(trailer[1]);
-  if ((ret == 2) || (ret == 53))
-  {
-    if (ret == 53)
-      _ssh_banner += getstring (buffer:trailer, pos:2);
-
-    return ssh_recv(socket:socket, length:length);
-  }
-
-  return strcat(header, trailer);
-}
-
-
-#-----------------------------------------------------------------#
-# Detect if remote ssh server is known to be bugged (SunSSH1.0)   #
-#-----------------------------------------------------------------#
-function is_sshd_bugged(banner)
-{
- if (ereg(string:banner, pattern:"^SSH-2\.0-Sun_SSH_1\.0"))
-   return 1;
-
- return 0;
-}
-
-
-#-----------------------------------------------------------------#
-# Waits for the server identification string, and sends our own   #
-# identification string.                                          #
-#-----------------------------------------------------------------#
-function ssh_exchange_identification(socket)
-{
- local_var buf, sshversion, num, prot;
-
- buf = recv_line(socket:socket, length:1024);
-
- if (!buf)
- {
-   set_ssh_error(msg: "OpenVAS did not receive server's version");
-   return 0;
- }
-
- # server ident : SSH-%d.%d-servername #
- if (!ereg(string:buf, pattern:"^SSH-*[0-9]\.*[0-9]-*[^\n]"))
- {
-   set_ssh_error(msg: "Remote service is not a valid SSH service");
-   return 0;
- }
-
- sshversion = split(buf, sep:"-", keep:0);
- num = split(sshversion[1], sep:".", keep:0);
-
- # version supported = 2 & 1.99
- if ((num[0] != 2) && !((num[0] == 1) && (num[1] == 99)))
- {
-   set_ssh_error(msg: "OpenVAS only supports SSHv2");
-   return 0;
- }
-
- # We use 2.0 protocol
- prot = "SSH-2.0-OpenVAS"+raw_string(0x0a);
- send(socket:socket, data:prot);
-
- if ( '\r\n' >< buf ) buf = buf - '\r\n';
-   else buf = buf - '\n';
-
- if (is_sshd_bugged(banner:buf))
- {
-   bugged_sshd = 1;
-   register_int_in_kb (int:bugged_sshd, name:"Secret/SSH/bugged_sshd");
- }
-
- # all is correct
- return buf;
-}
-
-
-#-----------------------------------------------------------------#
-# check pattern in buffer                                         #
-# return next len in buffer or -1                                 #
-#-----------------------------------------------------------------#
-function check_pattern(buffer,pattern,length)
-{
- local_var alglen, len, alg;
-
- alglen = ntol (buffer:buffer, begin:length);
- len = length+4+alglen;
- alg = substr(buffer,length+4,len-1);
- if (!ereg(string:alg, pattern:pattern))
-  return -1;
-
- return len;
-}
-
-#-----------------------------------------------------------------#
-# Create key exchange packet                                      #
-#-----------------------------------------------------------------#
-function kex_packet(payload,code)
-{
- local_var len, padding_len, full_len, kex;
-
- 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;
-
- kex =
-    # 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
-    crap(data:raw_string(0),length:padding_len);
-
- return kex;
-}
-
-
-#-----------------------------------------------------------------#
-# mac compute                                                     #
-#-----------------------------------------------------------------#
-function mac_compute(data, type)
-{
- local_var to_hash;
-
- # we only support sha1! enc_keys[5] == mac_out key
- if (!type)
- {
-  to_hash = raw_int32(i:seqn_w) + data;
-  hash = HMAC_SHA1(data:to_hash, key:enc_keys[4]);
- }
- else
- {
-  to_hash = raw_int32(i:seqn_r) + data;
-  hash = HMAC_SHA1(data:to_hash, key:enc_keys[5]);
- }
-
- return hash;
-}
-
-
-#-----------------------------------------------------------------#
-# crypt data                                                      #
-#-----------------------------------------------------------------#
-function crypt(data)
-{
- local_var crypted;
-
- crypted = bf_cbc_encrypt(data:data, key:enc_keys[2], iv:enc_keys[0]);
-
- enc_keys[0] = crypted[1];
-
- register_array_in_kb(array:enc_keys, name:"Secret/SSH/enc_keys"); 
- return crypted[0];
-}
-
-#-----------------------------------------------------------------#
-# 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 (lenght,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;
-}
-
-
-#-----------------------------------------------------------------#
-# Genereate 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)
-    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 authentification 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 at 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)
-    {
-      set_ssh_error(msg:"Error during client's RSA signature computing");
-      return -1;
-    }
-
-    signature = putstring(buffer:"ssh-rsa") + putstring(buffer:signature);
-  }
-  else if ("ssh-dss" >< typestr)
-  {
-    # p
-    next = 4 + strlen(typestr);
-    p = getstring (buffer:blobpub,pos:next);
-    next = next + 4 + strlen(p);
-
-    # q
-    q = getstring (buffer:blobpub,pos:next);
-    next = next + 4 + strlen(q);
-
-    # g
-    g = getstring (buffer:blobpub,pos:next);
-    next = next + 4 + strlen(g);
-
-    # pub key
-    pub_key = getstring (buffer:blobpub,pos:next);
- 
-    privkey = pem_to_dsa(priv:priv, passphrase:passphrase);
-    if (!privkey)
-    {
-      set_ssh_error(msg:"OpenVAS failed to load SSH private key (DSA)");
-      return -1;
-    }
-
-    payload += putstring(buffer:"ssh-dss") + putstring(buffer:blobpub);
-
-    to_hash += payload;
-
-    hash = SHA1(to_hash);
-    signature = dsa_do_sign(p:p, q:q, g:g, pub:pub_key, priv:privkey, data:hash);
-    if (!signature)
-     {
-      set_ssh_error(msg:"Error during client's DSA signature computing");
-      return -1;
-     }
-
-    signature = putstring(buffer:"ssh-dss") + putstring(buffer:signature);
-
-  }
-  else
-  {
-    set_ssh_error(msg:"Client's private key type is not supported");
-    return -1;
-  }
-
-  payload += putstring(buffer:signature);
-
-  send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:50));
-
-  # code 60 (SSH_MSG_USERAUTH_PK_OK)
-  payload = recv_ssh_packet(socket:socket);
-  if ((ord(payload[0]) == 52) || (ord(payload[0]) == 60))
-     authenticated = 1;
-
-  if (!authenticated)
-  {
-    payload = "Public key authentication failed.";
-    if (password)
-    {
-      payload += '
-It seems you provided both public/private keys and password.
-In this case OpenVAS only use your public and private keys.
-OpenVAS did not try both. As password authentication is
-vulnerable to Man-In-The-Middle attack, that implies your keys
-are useless (a "malicious server" will just reject your public
-key authentication and accept any provided password).
-';
-    }
-    set_ssh_error(msg:payload);
-
-    return -1;
-  }
- }
-
- # all is ok, user is authenticated
- return 0;
-}
-
-
-#-----------------------------------------------------------------#
-# Open channel                                                    #
-#-----------------------------------------------------------------#
-function ssh_open_channel(socket)
-{
- local_var payload, i;
-
- if (bugged_sshd && !bugged_first)
- {
-   local_channel++;
-   register_int_in_kb(name:"Secret/SSH/local_channel", int:local_channel);
-   if (local_channel > 10)
-     return -1;
-   l_window_size = 32768;
-   received_size = 0;
-   remote_channel = bugged_channels[local_channel];
-   r_window_size = bugged_rws[local_channel];
-   r_packet_size = bugged_rps[local_channel];
-   register_int_in_kb(name:"Secret/SSH/remote_channel", int:remote_channel);
-   return 0;
- }
-
- local_channel++;
- register_int_in_kb(name:"Secret/SSH/local_channel", int:local_channel);
-
- # session = "session"
- # initial window size = 32768
- # maximum packet size = 32768
- l_window_size = 32768;
- received_size = 0;
- payload = putstring(buffer:"session") + raw_int32(i:local_channel) +
-	raw_int32(i:32768) + raw_int32(i:32768);
-
- # SSH_MSG_CHANNEL_OPEN == 90
- send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:90));
-
- # SSH_MSG_CHANNEL_OPEN_CONFIRMATION == 91 (92 == failure)
- payload = recv_ssh_packet(socket:socket);
- if (ord(payload[0]) != 91)
- {
-   set_ssh_error(msg:string("Received code was not  SSH_MSG_CHANNEL_OPEN_CONFIRMATION (91). It was : " , ord(payload[0])));
-   return -1;
- }
-
- remote_channel = ntol(buffer:payload, begin:5);
- register_int_in_kb(name:"Secret/SSH/remote_channel", int:remote_channel);
- r_window_size = ntol(buffer:payload, begin:9);
- r_packet_size = ntol(buffer:payload, begin:13);
-
- # For bugged channel like Sun_SSH_1.0 we create 10 channels at startup 
- # Sun_SSH supports only 10 channels at the same time.
- if (bugged_sshd)
- {
-   bugged_first = 0;
-   register_int_in_kb(int:bugged_first, name:"Secret/SSH/bugged_first");
-   bugged_channels = bugged_rws = bugged_rps = NULL;
-   bugged_channels[0] = 0;
-   bugged_rws[0] = 0;
-   bugged_rps[0] = 0;
-   bugged_channels[local_channel] = remote_channel;
-   for (i=local_channel+1; i < 11; i++)
-   {
-      payload = putstring(buffer:"session") + raw_int32(i:i) +
-	  raw_int32(i:32768) + raw_int32(i:32768);
-
-      send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:90));
-
-      payload = recv_ssh_packet(socket:socket);
-      if (ord(payload[0]) != 91)
-      {
-        set_ssh_error(msg:string("Received code was not  SSH_MSG_CHANNEL_OPEN_CONFIRMATION (91). It was : " , ord(payload[0])));
-        return -1;
-      }
-
-      bugged_channels[i] = ntol(buffer:payload, begin:5);
-      bugged_rws[i] = ntol(buffer:payload, begin:9);
-      bugged_rps[i] = ntol(buffer:payload, begin:13);
-   }
-
-   register_intarray_in_kb(array:bugged_channels, name:"Secret/SSH/bugged_channels");
-   register_intarray_in_kb(array:bugged_rws, name:"Secret/SSH/bugged_rws");
-   register_intarray_in_kb(array:bugged_rps, name:"Secret/SSH/bugged_rps");
- }
-
- # all is ok, user is authenticated
- return 0;
-
-}
-
-#-----------------------------------------------------------------#
-# Close channel                                                   #
-#-----------------------------------------------------------------#
-function ssh_close_channel(socket,end)
-{
- local_var payload;
-
- # session = "session"
- # sender channel = 4444  / should we try different number on failure ?
- # initial window size = 32768
- # maximum packet size = 32768
- payload = raw_int32(i:remote_channel);
-
- # SSH_MSG_CHANNEL_CLOSE == 97
- send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:97));
-
- if (!end)
- {
-   # SSH_MSG_CHANNEL_CLOSE == 97
-   payload = recv_ssh_packet(socket:socket);
-   while((ord(payload[0]) != 97) && (ord(payload[0]) != 0))
-     payload = recv_ssh_packet(socket:socket);
-
-   if (ord(payload[0]) != 97)
-   {
-     set_ssh_error(msg:string( "Received code was not  SSH_MSG_CHANNEL_CLOSE (97). It was : " , ord(payload[0])));
-     return -1;
-   }
- }
-
- # all is ok, user is authenticated
- return 0;
-
-}
-
-
-#-----------------------------------------------------------------#
-# Login to SSH server                                             #
-#-----------------------------------------------------------------#
-function ssh_login(socket, login, password, pub, priv, passphrase)
-{
- local_var server_user, ret;
-
- server_user = tolower(login);
-
- init();
-
- # Exchange protocol version identification strings with the server.
- server_version = ssh_exchange_identification(socket:socket);
- if (!server_version)
-  return -1;
-
- _ssh_server_version = server_version;
-
- # key exchange
- # authenticate user
- ret = ssh_kex2(socket:socket, server_version:server_version);
- if (ret != 0)
-   return -1;
-
- ret = ssh_userauth2(socket:socket, server_user:server_user, password:password, pub:pub, priv:priv, passphrase:passphrase);  
- if (ret != 0)
-   return -1;
-
- # all is ok
- return 0;
-}
-
- 
-#-----------------------------------------------------------------#
-# Return size we can send on the channel and in the packet        #
-#-----------------------------------------------------------------#
-function get_data_size()
-{
- local_var len;
- 
- if (r_window_size <= r_packet_size)
-    len = r_window_size;
- else
-    len = r_packet_size;
-
- # packet option ~= 50 bytes
- len -= 50;
-
- # Remote server has not reajusted his window 
- if (len <= 0)
-    return -1;
-
- return len;
-}
-
- 
-#-----------------------------------------------------------------#
-# Update Window channel size on SSH server                        #
-#-----------------------------------------------------------------#
-function update_window_size(socket,size)
-{
- local_var len;
-
- l_window_size -= size;
- received_size += size;
-
- # Maximum allocated memory is 20 MB
- # A correct server will send 32768 bytes packet. So we stop before
- # to get data.
- # A non standard server will just be stopped by openvasd.
- if (received_size > 19000000)
-   return -1;
-
- if (l_window_size < 1000)
- {
-   len = 32768 - l_window_size;
-   payload = raw_int32(i:remote_channel) + raw_int32(i:len);
-
-   # SSH_MSG_CHANNEL_WINDOW_ADJUST == 93
-   send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:93));
-
-   l_window_size += len;   
- }
-
- return 0;
-}
-
-
-
-#-----------------------------------------------------------------#
-# Execute command on SSH server                                   #
-#-----------------------------------------------------------------#
-function ssh_cmd(socket,cmd,timeout)
-{
- local_var payload, ret, tempbuf, end, cret;
-
- # Flash error buffer
- _ssh_cmd_error = "";
-
- # Open channel
- ret = ssh_open_channel(socket:socket);
- if (ret != 0)
- {
-   _ssh_cmd_error = "OpenVAS failed to open a new SSH channel. " + get_ssh_error();
-   return NULL;
- }
-
- payload = raw_int32(i:remote_channel) + putstring(buffer:"exec") + raw_int8(i:0) +
-	 putstring(buffer:cmd);
-
- # SSH_MSG_CHANNEL_REQUEST == 98
- send_ssh_packet(socket:socket, payload:payload, code:raw_int8(i:98));
-
- ret = NULL;
-
- # SSH_MSG_CHANNEL_SUCCESS == 99
- # while for previous useless messages (SSH_MSG_CHANNEL_WINDOW_ADJUST, ...)
- payload = recv_ssh_packet(socket:socket, timeout:timeout);
- while((ord(payload[0]) == 93) || (ord(payload[0]) == 95) || (ord(payload[0])  == 98))
- {
-  if (ord(payload[0]) == 95)
-  {
-    payload = getstring(buffer:payload, pos:9);
-    _ssh_cmd_error += payload;
-    val = update_window_size(socket:socket,size:strlen(payload));
-    if (val != 0)
-      break;
-  }
-  payload = recv_ssh_packet(socket:socket, timeout:timeout);
- }
-
- while ((ord(payload[0]) != 97) && (ord(payload[0]) != 0))
- {
-  if (ord(payload[0]) == 98)
-  {
-    payload = getstring(buffer:payload, pos:5);
-    if ("exit-status" >!< payload)
-      break;
-  }
-  else if ((ord(payload[0]) == 94) || (ord(payload[0]) == 95))
-  {
-    tempbuf = getstring(buffer:payload, pos:5);
-    if (ord(payload[0]) == 94)
-    {
-      ret += tempbuf;
-    }
-    val = update_window_size(socket:socket,size:strlen(tempbuf));
-    if (val != 0)
-    {
-      break;
-    }
-  }
-  payload = recv_ssh_packet(socket:socket, timeout:timeout);
- }
-
- end = 0;
- if (ord(payload[0]) == 97)
-   end = 1;
-
- # Close channel
- cret = ssh_close_channel(socket:socket, end:end);
- if (cret != 0)
- {
-   _ssh_cmd_error = "OpenVAS failed to close SSH channel. " + get_ssh_error();
-   return NULL;
- }
-
-
- return ret;
-
-}
-
-
-#-----------------------------------------------------------------#
-# Return errors happended during ssh_cmd()                        #
-#-----------------------------------------------------------------#
-function ssh_cmd_error()
-{
- return _ssh_cmd_error;
-}
-
-
-
-#------------------------------------------------------------------#
-# Connection re-use                                                #
-#------------------------------------------------------------------#
-
-# Internal
-function reuse_connection_init()
-{
- _reuse_connection = 1;
- seqn_w = load_int_from_kb(name:"Secret/SSH/seqn_w");
- seqn_r = load_int_from_kb(name:"Secret/SSH/seqn_r");
- local_channel = load_int_from_kb(name:"Secret/SSH/local_channel");
- session_id = load_data_from_kb(name:"Secret/SSH/session_id");
- remote_channel = load_int_from_kb(name:"Secret/SSH/remote_channel");
- enc_keys = load_array_from_kb(name:"Secret/SSH/enc_keys"); 
- dh_pub = load_data_from_kb(name:"Secret/SSH/dh_pub"); 
- dh_priv = load_data_from_kb(name:"Secret/SSH/dh_priv");
- bugged_sshd = load_int_from_kb(name:"Secret/SSH/bugged_sshd");
- if (bugged_sshd)
- {
-   bugged_channels = load_intarray_from_kb(name:"Secret/SSH/bugged_channels"); 
-   bugged_rws = load_intarray_from_kb(name:"Secret/SSH/bugged_rws"); 
-   bugged_rps = load_intarray_from_kb(name:"Secret/SSH/bugged_rps"); 
-   bugged_first = load_int_from_kb(name:"Secret/SSH/bugged_first"); 
- }
- if ( isnull(enc_keys) || isnull(dh_pub) || isnull(dh_priv) || isnull(session_id) ) return -1;
- return 0;
-}
-
-
-# Returns a socket to an already established connection 
-function ssh_reuse_connection()
-{
- local_var soc;
-
- if ( ! defined_func("shared_socket_acquire") ) 
-	return 0;
-
- if ( reuse_connection_init() < 0 )
-	{
-	_reuse_connection = 0;
-	return 0;
-	}
-
- soc = shared_socket_acquire("Secret/SSH/socket");
- if ( soc == NULL ) 
-  {
-  _reuse_connection = 0;
-  return 0;
-  }
- else 
-  return soc;
-}
-
-
-#
-# Release the shared SSH connection so that another script can write to
-# it
-#
-function ssh_close_connection()
-{
- if ( _reuse_connection ) shared_socket_release("Secret/SSH/socket");
-}
-
-
-
-function ssh_login_or_reuse_connection()
-{
- local_var soc;
- local_var login, password, pub, priv, passphrase;
-
-
- soc = ssh_reuse_connection();
- if ( soc > 0 ) return soc;
-
- login = kb_ssh_login();
- password = kb_ssh_password();
- pub = kb_ssh_publickey();
- priv = kb_ssh_privatekey();
- passphrase = kb_ssh_passphrase();
-
-
- if ( ! login || (! password &&  (! pub || ! priv))) return 0;
-
-
- soc = open_sock_tcp(kb_ssh_transport());
- if ( ! soc ) return 0;
- _reuse_connection = 1;
- if ( ssh_login(socket:soc, login:login, password:password, pub:pub, priv:priv, passphrase:passphrase) != 0 )
- {
-  close(soc);
-  return 0;
- }
-
- shared_socket_register(name:"Secret/SSH/socket", socket:soc);
- return soc;
-}



More information about the Openvas-commits mailing list