📄 ssh_func.inc
字号:
{ 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 isvulnerable to Man-In-The-Middle attack, that implies your keysare useless (a "malicious server" will just reject your publickey 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, messid_data, ret_payload; # Flash error buffer _ssh_cmd_error = ""; # Message id flag messid_data = 0; # 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; ret_payload += payload; val = update_window_size(socket:socket,size:strlen(payload)); if (val != 0) break; } payload = recv_ssh_packet(socket:socket, timeout:timeout); if("exit-signal" >< payload) ret_payload += string(payload); } 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; messid_data = 1; } val = update_window_size(socket:socket,size:strlen(tempbuf)); if(val != 0) { break; } } else if(ord(payload[0]) == 96){ if(messid_data == 0){ ret += ret_payload; } } 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 happened during ssh_cmd() ##-----------------------------------------------------------------#function ssh_cmd_error(){ return _ssh_cmd_error;}#------------------------------------------------------------------## Connection re-use ##------------------------------------------------------------------## Internalfunction 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;## First acquire the shared socket, then do reuse_connection_init()# This change is done in order to avoid getting same local_channel # when multiple processes are involved.# # if ( reuse_connection_init() < 0 )# {# _reuse_connection = 0;# return 0;# }# soc = shared_socket_acquire("Secret/SSH/socket"); if ( reuse_connection_init() < 0 ) { _reuse_connection = 0; return 0; } 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -