Nessus was able to identify the remote service by its banner or by looking at the error message it sends when it receives an HTTP request.
#TRUSTED 30831b7353f48e0e4d9694c177d3cba02f9f79db7499986a5c099735df58009d9d5af9707ccd5ef473b90843e7a25a41d8d478ca060f9322906e2ec9acd8272e36916b0952e1e37792b87ddbba70a292eb1eb59ea9903e97d4418d5c18d326311147c44d588e15582322af9bf1699b455ccf4e01815bdf7e974ec53b85c5eb83aff333191f07265e8f7d86d8c5b54df92bd338f1a4a0b137a25008b053f70aae17723d977791c5ab0a5e37dbfef1f550983415db3b95eb4253f2482f2f6824f37c172749b5a491bf7baf7edbfe7158270b0d926f4c1534a6defabd4e5442ea3b7dadc27c6934352d948c3126ca3ec9722e7d2675774018f82b1c3dd32fdc0949013e05bcc6420a0d9d2a18498c9c5a5e752998860771f1b1c69b441f2cf77d7a1f0665059df1d29f75d662b9c5c345d7a398a3b5e2f5b1b2ef698d01613be826a16adae3af9a0b9c0df83d1e2a384576e31e63f699d4a906294ada5ec38076ae094a152005c35db737ba708d09c7215ad1c7f4813319e3446c37d4c42919301d5eb7f53d64e7c865120c862a2b5e3c5fc482bda77f398a888327fcefe51cb01e1c16285945a3f2c532a7d8396fb10ca63d8fc0ef70cf7143ac26fdb1415ba8fe9ace5402f2cba9fe6aa80bb0eeef0686a955e6d6f281137f1d07d51fe3048c43408be543ec379fdc449d203581220d3d5b54f99965377db259c779519ae62d1e
#TRUST-RSA-SHA256 2612f16aed1408b114ec7eb12add6d379a843b6c9b84311ec3cad44d3fbfca412f9a8a9d8768642fb7da2d5af41dea9d8950f58b41cc39e5f21f7d9323167e2212685c8cfd5a12e0cb5947bca92ff2a1fb193f12f69b696ca9cbee93991367cd59e09155e675d5df3750737770e6a688e99e48653e28bb9416f98aefdd0817802d6adafaed15dfb68ebc9a299d5000be9cb7bbc865c76d0e75b960a617dd5a8d696f35865752974c66065e86669188e3b7dc9cd41c6e56a9ae7c8b40f9689735638e3c34b3a4756bc5556e3852033ffb0dbfdba3ce3f312025028eed369a7214429d2b25e9cd54f563eccbc0c4cf04a78553d0439fc54dc61385fb5272ca4606d7fea8f1dd28cb38618e3d2ed4ac5c46b6d9313496cd214569a7e34b1a938010741b6c9d7358c2bde15dcfda42a95ae745407a33414a0e46723ec23fa2ec695d91007d494e4024b35d6aa3816970ff8ed7f8fcb1eb35fd9d3d41f0513163c87d706cfc3890aab44df559aa5b289e34c9f6dea3b85d556344c7f238154dc4d982714b18998f9ed8240a7c08fc6ff3bad44df65042ce73b55962e98d88c474314ac8d309525b309104f191e45f9d64fdd8952be7e68cf034842cfb5d96cc8774563f00de621c796f70071c57e2336773553e0d6fd2dd94138e71e015066e4ba90aee99bcc31847d23f27e7a07c9ea65a9993fedec151a4493817b228ea6ef1b137
#
# (C) Tenable Network Security, Inc.
#
#
# @PREFERENCES@
include("compat.inc");
if (description)
{
script_id(22964);
script_version("1.194");
script_set_attribute(attribute:"plugin_modification_date", value:"2024/03/26");
script_name(english:"Service Detection");
script_summary(english:"Sends 'GET' to unknown services and looks at the answer.");
script_set_attribute(attribute:"synopsis", value:
"The remote service could be identified.");
script_set_attribute(attribute:"description", value:
"Nessus was able to identify the remote service by its banner or by
looking at the error message it sends when it receives an HTTP
request.");
script_set_attribute(attribute:"solution", value:"n/a");
script_set_attribute(attribute:"risk_factor", value:"None");
script_set_attribute(attribute:"plugin_publication_date", value:"2007/08/19");
script_set_attribute(attribute:"plugin_type", value:"remote");
script_end_attributes();
script_category(ACT_GATHER_INFO);
script_family(english:"Service detection");
script_copyright(english:"This script is Copyright (C) 2004-2024 and is owned by Tenable, Inc. or an Affiliate thereof.");
script_timeout(0);
script_add_preference(name:"Test SSL based services", type:"radio", value:"All ports");
script_dependencies(
"dcetest.nasl",
"rpcinfo.nasl",
"pjl_detect.nasl",
"dont_scan_printers.nasl",
"dont_scan_printers2.nasl",
"zend_server_java_bridge_code_exec.nasl",
"veritas_vxsvc_detect.nbin",
"find_smtp.nasl",
"emc_autostart_ftagent_detect.nbin",
"hp_imc_dbman_detect.nbin",
"dont_scan_ot.nasl"
);
exit(0);
}
include("global_settings.inc");
include("telnet_func.inc");
include("misc_func.inc");
include("byte_func.inc");
include("ssl_funcs.inc");
include("datetime.inc");
include("debug.inc");
include('nessusd_product_info.inc');
if ( get_kb_item("global_settings/disable_service_discovery") ) exit(0, "Service discovery has been disabled.");
# Clients sometime hit the default limit of 40MB allocations, especially with over 1000 ports open.
# We need to increase it. 200MB should be plenty for 1500 65k banners.
var mem = 200 * 1024 * 1024;
set_mem_limits(max_alloc_size:mem, max_program_size:mem);
#
# Global variables and constants
#
global_var g_sock, g_transport_state, g_sock_state, g_banners, g_timestamps, g_sock_conn_tries;
global_var g_port_pool, g_port_pool_idx, g_port_pool_max, state_to_transport, g_methods;
global_var g_ssl_ports, g_ssl_ports_H;
global_var g_ssl_ports_to_try, g_ssl_ports_to_try_idx;
global_var g_port_start_time, g_port_state_time;
global_var TLSv1_1_AVAILABLE = FALSE;
global_var TLSv1_2_AVAILABLE = FALSE;
global_var TLSv1_3_AVAILABLE = FALSE;
if (ENCAPS_TLSv1_1)
TLSv1_1_AVAILABLE = TRUE;
if (ENCAPS_TLSv1_2)
TLSv1_2_AVAILABLE = TRUE;
if (ENCAPS_TLSv1_3)
TLSv1_3_AVAILABLE = TRUE;
global_var E_STATE_TLSv1 = 1;
global_var E_STATE_SSLv3 = 2;
global_var E_STATE_SSLv23 = 3;
global_var E_STATE_SSLv2 = 4;
global_var E_STATE_TLSv11 = 5;
global_var E_STATE_TLSv12 = 6;
global_var E_STATE_TLSv13 = 7;
global_var E_STATE_TLS_HELLO = 8;
global_var E_STATE_SSL3_HELLO = 9;
global_var E_STATE_SSL2_HELLO = 10;
global_var E_STATE_IP = 11;
global_var E_STATE_SSL_START = E_STATE_TLSv1;
global_var TIMEOUT = 5;
global_var SPONTANEOUS_TIMEOUT = 2;
global_var CONNECT_TIMEOUT = 4;
global_var CONNECT_RETRIES = 10;
global_var MAX_SIMULT_CONNECTIONS = 5;
global_var S_STATE_CONNECTING = 1;
global_var S_STATE_READING = 2;
global_var S_STATE_READING_W_GET = 3;
global_var S_STATE_DONE = 4;
global_var S_STATE_DESCRIPTIONS = ['', 'S_STATE_CONNECTING', 'S_STATE_READING', 'S_STATE_READING_W_GET', 'S_STATE_DONE'];
global_var SSL_CONNECT_NONE = 0;
global_var SSL_CONNECT_ALL = 1;
global_var SSL_CONNECT_KNOWN = 2;
global_var SSL_PORT_TO_CONNECT = SSL_CONNECT_KNOWN;
state_to_transport = [];
if (nasl_level() >= 80900)
{
state_to_transport[E_STATE_SSLv23] = ENCAPS_SSLv23 | ENCAPS_DISABLE_TLSv1_1 | ENCAPS_DISABLE_TLSv1_2 | ENCAPS_DISABLE_TLSv1_3;
}
else
{
state_to_transport[E_STATE_SSLv23] = ENCAPS_SSLv23 | ENCAPS_DISABLE_TLSv1_1 | ENCAPS_DISABLE_TLSv1_2;
}
state_to_transport[E_STATE_SSLv2] = ENCAPS_SSLv2;
state_to_transport[E_STATE_TLSv1] = ENCAPS_TLSv1;
state_to_transport[E_STATE_SSLv3] = ENCAPS_SSLv3;
state_to_transport[E_STATE_TLSv11] = ENCAPS_TLSv1_1;
state_to_transport[E_STATE_TLSv12] = ENCAPS_TLSv1_2;
state_to_transport[E_STATE_TLSv13] = ENCAPS_TLSv1_3;
state_to_transport[E_STATE_TLS_HELLO] = ENCAPS_IP;
state_to_transport[E_STATE_SSL3_HELLO] = ENCAPS_IP;
state_to_transport[E_STATE_SSL2_HELLO] = ENCAPS_IP;
state_to_transport[E_STATE_IP] = ENCAPS_IP;
g_ssl_ports = [
261, # Nsiiops
443, # HTTPS
446, # Openfiler's management interface
448, # ddm-ssl
465, # SMTPS
563, # NNTPS
585, # imap4-ssl
614, # SSLshell
636, # LDAPS
684, # Corba IIOP SSL
695, # IEEE-MMS-SSL
853, # DNS over TLS
902, # VMWare Auth Daemon
989, # FTPS data
990, # FTPS control
992, # telnets
993, # IMAPS
994, # IRCS
995, # POP3S
1032, # HP Server Automation (twisted web interface)
1241, # Nessus
1243, # PVS Proxy
1311, # Dell OpenManage
1950, # Tivoli Security Configuration Manager agent
2010, # IBM HTTP Server administration SSL port
2050, # Domino
2161, # APC UPS Power Monitoring Agent
2224, # Pacemaker PCSD Service
2381, # Compaq Web Management
2456, # SGMI (Remote firewall management)
2478, # SecureSight Authentication Server
2479, # SecureSight Event Logging Server
2482, # Oracle GIOP SSL
2484, # Oracle TTS SSL
2679, # Sync Server SSL
2738, # HP DDMI
3037, # Novell File Reporter Agent
3077, # Orbix 2000 Locator SSL
3078, # Oribx 2000 Locator SSL
3220, # Juniper Junos XML protocol server (over SSL)
3269, # Microsoft Global Catalog w/ LDAP/SSL
3389, # Microsoft Remote Desktop
3424, # Xware xTrm Communication Protocol over SSL (xtrms)
3471, # jt400 SSL
3661, # IBM Tivoli Directory Service using SSL
3780, # Nexpose
3790, # Metasploit HTTPS Server
3994, # IIS deployment manager
4031, # UUCP over SSL
4343, # Trend Micro Worry-Free Business Security Web Console
4445, # PCI
5007, # WSM Server SSL
5061, # SIP over TLS
5443, # IBM WebSphere Commerce Payments secure server
5480, # VMware vRealize Automation and SolarWinds Virtualization Manager
5556, # Oracle WebLogic Node Manager
5666, # Nagios Remote Plugin Executor (NRPE)
5671, # Advanced Message Queueing Protocol -- SSL
5783, # 3PAR Management Service
5988, # SBLIM Small Footprint CIM Broker
5989, # SBLIM Small Footprint CIM Broker
6697, # IRC/SSL
6783, # Splashtop Streamer SSL port
6784, # Splashtop Streamer SSL port
6785, # Splashtop Streamer SSL port
6789, # Sun Java Web Console
7002, # WebLogic
7004, # RSA Secure Logon
7071, # Zimbra Collaboration Server
7135, # IBM Tivoli Access Manager runtime env -- SSL
# IANA lists a different service assigned to TCP 7101
# 7101, # Oracle Enterprise Manager Admin Server (HTTPS)
7183, # Cloudera Manager
7301, # Oracle Enterprise Manager Cloud Control Managed Server (HTTPS)
7403, # Oracle Enterprise Manager Grid Control Node Manager (HTTPS)
7700, # Bosch Security System Ethernet Connection Module
7799, # Oracle Enterprise Manager Console
8000, # Tenable Appliance / IBM WebSphere Commerce Accelerator
8002, # IBM WebSphere Commerce Server Admin Console
8004, # IBM WebSphere Commerce Server Organization Administration Console
8006, # IBM WebSphere Commerce preview
8009, # Sony Bravia TV
8012, # Citrix XenServer Workload Balancer
8082, # BlueCoat ProxySG Console
8089, # Splunk management port
8139, # Puppet agent
8140, # Puppet master
8333, # VMware
8443, # Tomcat
8444, # McAfee ePolicy Orchestrator
8445, # Symantec SEPM
8834, # Nessus 4.2
8835, # PVS 4.0
8880, # IBM WebSphere Application Server SOAP connector
9000, # Sony Bravia
9002, # Oracle WebLogic Administration Port
9043, # IBM WebSphere Application Server administrative console secure port
9390, # OpenVAS Manager
9391, # OpenVAS Scanner
9392, # Greenbone Security Assistant
9393, # OpenVAS Administrator
9443, # WebSphere internal secure server
9090, # HP iNode Management Center
10000, # Webmin+SSL
10443, # McAfee Email Gateway
11090, # IBM Spectrum Protect Operations Center
13841, # HP VSA hydra 10.0
18443, # MySQL Enterprise Monitoring
18630, # StreamSets DataCollector
18636, # StreamSets DataCollector
19201, # SilPerformer agent
40007, # AlienVault OSSIM SOAP
40011, # AlienVault OSSIM REST
42966, # HP Remote Graphics
50000, # HP Insight Software
54345, # HP Load Runner
54984, # WebYaST Web Client
63002, # HP Smart Update Manager
65443 # McAfee LinuxShield nailsd
];
#
# Initialize the variables
#
function globals_reset()
{
g_sock_state = {};
g_sock = {};
g_transport_state = {};
g_banners = {};
g_timestamps = {};
g_methods = {};
g_sock_conn_tries = {};
g_port_start_time = {};
g_port_state_time = {};
g_port_pool = [];
g_port_pool_max = 0;
g_port_pool_idx = 0;
}
function globals_init()
{
globals_reset();
g_ssl_ports_to_try_idx = 0;
g_ssl_ports_to_try = {};
}
#-------------------#
# Helper functions #
#-------------------#
##
# Apply pattern to an FTP banner to see if this is a printer
#
# @param [banner:string] FTP banner
# @param [banner:string] FTP port
# @return [report:string] If matches to printer - return a report, otherwise return empty string
#
##
function check_printer_over_ftp(banner, port)
{
local_var report = '';
if("JD FTP Server Ready" >< banner)
{
report = strcat(report, '\nJD FTP server on port ', port, '\n');
}
else if (pgrep(pattern:"^220 [A-Za-z0-9]+ Network Management Card AOS v",string:banner))
{
report = strcat(report, '\nAPC UPS Management Card FTP server on port ', port, '\n');
}
else if (pgrep(pattern:"^220 AXIS .* FTP Network Print Server .+ ready", string:banner))
{
report = strcat(report, '\nAXIS printer FTP server on port ', port, '\n');
}
else if ("220 Dell Laser Printer " >< banner)
{
report = strcat(report, '\nDell FTP server on port ', port, '\n');
}
else if ( banner =~ "^220 Dell .* Laser" )
{
report = strcat(report, '\nDell FTP server on port ', port, '\n');
}
else if ( pgrep(pattern:"^220 DPO-[0-9]+ FTP Server", string:banner) )
{
report = strcat(report, '\nToshiba Printer FTP server on port ', port, '\n');
}
else if ( pgrep(pattern:"^220 .* Lexmark.* FTP Server", string:banner))
{
report = strcat(report, '\nLexmark Printer FTP server on port ', port, '\n');
}
else if ( pgrep(pattern:"^220 LANIER .* FTP server", string:banner))
{
report = strcat(report, '\nLANIER Printer FTP server on port ', port, '\n');
}
else if ("220 Print Server Ready." >< banner)
{
report = strcat(report, '\nGeneric printer FTP server on port ', port, '.\n');
}
else if (pgrep(pattern:"^220 FS-[0-9]+(DN|MFP) FTP server", string:banner))
{
report = strcat(report, '\nKyocera FTP server on port ', port, '.\n');
}
else if (
"220 KONICA MINOLTA FTP server ready" >< banner ||
"220 KONICAMINOLTA FTP server ready" >< banner
)
{
report = strcat(report, '\nKonica Minolta FTP server on port ', port, '.\n');
}
else if ( pgrep(pattern:"^220 RICOH .* FTP server", string:banner))
{
report = strcat(report, '\nRICOH Printer FTP server on port ', port, '\n');
}
else if (pgrep(pattern:"^220 SHARP (MX|AR)- .* FTP server", string:banner))
{
report = strcat(report, '\nSharp printer FTP server on port ', port, '\n');
}
else if (pgrep(pattern:"^220 ZBR-[0-9]+ Version V", string:banner))
{
report = strcat(report, '\nZebraNet printer FTP server on port ', port, '\n');
}
else if (pgrep(pattern:"^220 +IB-[0-9]+ Ver [0-9.]+ FTP server", string:banner))
{
report = strcat(report, '\nKyocera printer FTP server on port ', port, '\n');
}
else if (pgrep(pattern:"^220 +EFI.*FTP Print server ready", string:banner))
{
report = strcat(report, '\nEFI Printer FTP server on port ', port, '\n');
}
else if (pgrep(pattern:"^220 ECOSYS \S+ FTP server", string:banner))
{
report = strcat(report, '\nKyocera Printer FTP server on port ', port, '\n');
}
return report;
}
##
# Determine total elapsed time from provided start
#
# @anonparam start staring time (gettimeofday() epoch)
#
# @return difference between start and current gettimeofday() if start,
# else NULL
#
##
function timediff()
{
var start = _FCT_ANON_ARGS[0];
if (empty_or_null(start)) return NULL;
return datetime::timeofday_diff(begin:start, end:gettimeofday());
}
##
# Transition to next state for the provided port.
#
# @param port Port to transition states on
#
# @return NULL
##
function transition_state(port)
{
# If >= 8.9 skip SSLv2 state
if (nasl_level() >= 80900 && ((g_transport_state[port] + 1) == E_STATE_SSLv2))
{
g_transport_state[port] += 2;
}
else
{
g_transport_state[port]++;
}
}
#----------------------#
# Service recognition #
#----------------------#
function SSL_hello(port)
{
var ver, cipherspec, cspeclen, chello, hello_done, data, rec, cipher, n;
var soc, state, exts, exts_len, rec_ver, port_start_time, recv_start_time;
port_start_time = gettimeofday();
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'Port ' + port + ' test starting...');
soc = g_sock[port];
state = g_transport_state[port];
cipherspec = NULL;
ver = NULL;
# Detect SSLv3+, TLS servers should support backward compatibility
if(state != E_STATE_SSL2_HELLO)
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' - detected SSLv3 or later. Attempting negotiation...');
if (state == E_STATE_TLSv13)
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Trying TLS 1.3...');
chello = tls13_client_hello();
send(socket:soc, data:chello);
data = recv_ssl(socket:soc, hard_timeout:TRUE);
# Server hello
rec = ssl_find(
blob:data,
'content_type', SSL3_CONTENT_TYPE_HANDSHAKE,
'handshake_type', SSL3_HANDSHAKE_TYPE_SERVER_HELLO
);
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'Port ' + port + ' test completed in ' + timediff(port_start_time) + ' seconds');
# check our server version is 3,3 and our extension supported version is TLS 1.3
if ( !isnull(rec) && rec['handshake_version'] == 0x0303 && rec['extension_supported_versions'][0] == 0x0304)
return TLS_13;
else
return -3;
}
else
{
# not TLS 1.3
cipherspec = get_valid_cipherspec_for_encaps(encaps:COMPAT_ENCAPS_TLSv12, ciphers:ciphers);
cipherspec += raw_string(0x00, 0xff);
cspeclen = mkword(strlen(cipherspec));
rec_ver = raw_string(3,1);
exts = tls_ext_ec() + tls_ext_ec_pt_fmt();
exts_len = mkword(strlen(exts));
if(state == E_STATE_SSL3_HELLO)
{
rec_ver = raw_string(3,0);
exts = exts_len = NULL;
}
chello = client_hello(
v2hello :FALSE,
version : rec_ver,
cipherspec : cipherspec,
cspeclen : cspeclen,
extensions : exts,
extensionslen: exts_len,
maxver : raw_string(3,3)
);
send(socket:soc, data:chello);
hello_done = FALSE;
n = 0;
while ( ! hello_done )
{
if ( n++ > 64 ) return -1;
recv_start_time = gettimeofday();
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' recv_ssl() iteration: ' + n + ' starting...');
data = recv_ssl(socket:soc, hard_timeout:TRUE);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' recv_ssl() iteration: ' + n + ' completed in ' + timediff(recv_start_time) + ' seconds');
if ( isnull(data) ) return -2;
# Server Hello
rec = ssl_find(
blob:data,
'content_type', SSL3_CONTENT_TYPE_HANDSHAKE,
'handshake_type', SSL3_HANDSHAKE_TYPE_SERVER_HELLO
);
if ( !isnull(rec) )
{
if( !isnull(rec['handshake_version']))
ver = rec['handshake_version'];
else
return -3;
}
# Server Hello Done.
rec = ssl_find(
blob:data,
'content_type', SSL3_CONTENT_TYPE_HANDSHAKE,
'handshake_type', SSL3_HANDSHAKE_TYPE_SERVER_HELLO_DONE
);
if ( !isnull(rec) ) hello_done = TRUE;
}
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'Port ' + port + ' test completed in ' + timediff(port_start_time) + ' seconds');
return ver;
}
}
# Detect SSLv2 server
else
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' - detected SSLv2. Attempting negotiation...');
foreach cipher (sort(keys(ciphers)))
{
if('SSL2_' >< cipher)
{
cipherspec += ciphers[cipher];
}
}
cspeclen = mkword(strlen(cipherspec));
chello = client_hello(
version : raw_string(0,2),
cipherspec : cipherspec,
cspeclen : cspeclen,
v2hello : TRUE
);
send(socket:soc, data:chello);
recv_start_time = gettimeofday();
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' recv_ssl() for SSLv2 starting...');
data = recv_ssl(socket:soc, hard_timeout:TRUE);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' recv_ssl() for SSLv2 completed in ' + timediff(recv_start_time) + ' seconds');
if ( isnull(data) ) return -2;
rec = ssl_find(
blob:data,
"content_type", SSL2_CONTENT_TYPE_SERVER_HELLO
);
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'Port ' + port + ' test completed in ' + timediff(port_start_time) + ' seconds');
if(! isnull(rec))
{
if(! isnull(rec['version']))
return rec['version'];
else
return -3;
}
else
return -4;
}
}
function is_ssl_banner()
{
var banner;
banner = _FCT_ANON_ARGS[0];
if ( strlen(banner) < 5 ) return FALSE;
if ( (substr(banner, 0, 2 ) == raw_string(0x15, 0x03, 0x01)) ||
(substr(banner, 0, 4 ) == raw_string(0x15, 0x03, 0x00, 0x00, 0x02)) ||
(substr(banner, 0, 4 ) == raw_string(0x80, 0x03, 0x00, 0x00, 0x01)) ||
"error:1407609C:SSL routines:" >< banner )
return TRUE;
else
return FALSE;
}
function three_digits(port, banner)
{
if ( banner && banner =~ "^[0-9][0-9][0-9]($|-| )" )
{
set_kb_item(name:"Services/three_digits", value:port);
return 1;
}
}
function report_finding(port, proto, name, transport)
{
var data;
if ( isnull(name) ) name = 'A ' + proto + ' server';
register_service(port:port, proto:proto);
# Don't save www banners from an HTTP 1.0 request as they may
# cause problems for scans of name-based virtual hosts.
if ( '\0' >!< g_banners[port] && proto != "www" && !empty_or_null(g_banners[port]))
replace_kb_item(name:proto + "/banner/" + port, value:g_banners[port]);
# weblogic speaks 5 different protocols off the same port. flag this
# http service as potentially wls early so that the downstream protcols
# can examine this list
if (proto == "www")
{
set_kb_item(name:'www/possible_wls', value:port);
}
data = name + ' is running on this port';
if ( transport == ENCAPS_SSLv2 ) data +=' through SSLv2.';
else if ( transport == ENCAPS_SSLv3 ) data +=' through SSLv3.';
else if ( transport == ENCAPS_SSLv23 ) data +=' through SSLv23.';
else if ( transport == ENCAPS_TLSv1 ) data +=' through TLSv1.';
else if ( transport == COMPAT_ENCAPS_TLSv11 ) data +=' through TLSv1.1.';
else if ( transport == COMPAT_ENCAPS_TLSv12 ) data +=' through TLSv1.2.';
else if ( transport == COMPAT_ENCAPS_TLSv13 ) data +=' through TLSv1.3.';
if (data[strlen(data)-1] != '.') data += '.';
security_note(port:port, extra:data);
return NULL;
}
function may_be_time()
{
var now, rt70, diff_1970_1900, max_shift;
diff_1970_1900 = 2208988800;
max_shift = 3*365*86400;
set_byte_order(BYTE_ORDER_BIG_ENDIAN);
rt70 = getdword(blob:_FCT_ANON_ARGS[0], pos:0) - diff_1970_1900;
now = unixtime() - rt70;
if ( now < 0 ) now = 0 - now;
if ( now < max_shift ) return TRUE;
else return FALSE;
}
function register_unknown(port, banner)
{
if (strlen(banner) && banner =~ "^[0-9][0-9][0-9]($|-| )" ) return 0; # 3 digits
set_kb_item(name:"Services/unknown", value:port);
if ( strlen(banner) ) replace_kb_item(name:"unknown/banner/" + port, value:banner);
return 0;
}
function register_silent()
{
var port;
port = _FCT_ANON_ARGS[0];
set_kb_item(name:"Services/Silent/" + port , value:TRUE);
set_kb_item(name:"Services/Silent", value:port);
return 0;
}
#
# Signature based recognition
#
function recognize_banner(banner, port, transport)
{
var low, is_http, info, ver;
is_http = 0;
if ( strlen(banner) == 0 )
return register_unknown(port:port, banner:banner);
low = tolower(banner);
if ( is_ssl_banner(banner) &&
should_try_ssl(port) == FALSE &&
transport == ENCAPS_IP )
{
g_ssl_ports_to_try[g_ssl_ports_to_try_idx++] = port;
return NULL;
}
if (low =~ "^<html>" && "<TITLE>Directory /</TITLE>" >< banner)
{
report_finding(port:port, proto:"wild_shell", name:"A bind shell", transport:transport);
}
else if ( low =~ "^http/[0-9]\." || "<title>Not supported</title>" >< low || low =~ "^<html>" )
{
# HTTP server
# MA 2008-07-16: we used to skip port 5000 because of vtun
if ( ! ( low =~ "^http/1\.0 403 forbidden" && "server: adsubtract" >< low ) &&
! ( "server: flashcom/" >< low ) &&
! ( "server: heimdal/" >< low ) &&
! ( low =~ "^cimerror: ") )
{
is_http = 1;
if ( "mongodb over http on the native driver port" >< low )
{
report_finding(port:port, proto:"mongodb-http", name:"MongoDB HTTP", transport:transport);
}
else if (
low =~ "^http/1\.[01] (101 switching protocols|426 upgrade required)" &&
'upgrade: websocket' >< low)
{
report_finding(port:port, proto:"websocket", name:"A WebSocket", transport:transport);
}
else
{
report_finding(port:port, proto:"www", name:"A web server", transport:transport);
}
}
}
# Telnet-related services
if (strlen(banner) > 2 &&
ord(banner[0]) == 255 && ord(banner[1]) >= 251 && ord(banner[1]) <= 254)
{
# Regular Telnet is always the last one (inside else)
# we need a new socket for retrieving the telnet banner
var telnet_soc = open_sock_tcp(port), telnet_banner;
if (telnet_soc)
{
telnet_banner = telnet_negotiate(socket:telnet_soc);
close(telnet_soc);
}
g_banners[port] = telnet_banner;
if ("Welcome To jdkchat" >< telnet_banner && "Commands available:" >< telnet_banner)
{
return report_finding(port:port, proto:"jdkchat", name:"A Telnet Chat Server from J.D. Koftinoff Software", transport:transport);
}
else if ( "Eggdrop" >< telnet_banner || "Eggheads" >< telnet_banner )
{
return report_finding(port:port, proto:"eggdrop", name:"An eggdrop IRC bot control server", transport:transport);
}
else if ("communicating without encryption but connections from clients that do not support encryption are not allowed" >< telnet_banner && "CLEARTEXT option" >< telnet_banner)
{
return report_finding(port:port, proto:"SAS-CONNECT", name:"A SAS/CONNECT Server", transport:transport);
}
else if (hexstr(banner) == 'fffb010a' && (port == 13846 || port == 13847 || port == 13850 || port == 13946))
{
return report_finding(port:port, proto:"lefthand-os-support", name:"An HP StoreVirtual (LeftHand) Storage server", transport:transport);
}
else
{
# regular telnet
return report_finding(port:port, proto:"telnet", transport:transport);
}
}
else if ( "ccproxy telnet service ready" >< low)
return report_finding(port:port, proto:"ccproxy-telnet", name:"A CCProxy Telnet proxy", transport:transport);
else if ( strlen(banner) >= 4 &&
substr(banner, 0, 3) == '\00\01\01\00')
return report_finding(port:port, proto:"gnome14",name:"Gnome 1.4", transport:transport);
else if ( "http/1.0 403 forbidden" >< low && "server: adsubtract" >< low )
{
return report_finding(port:port, proto:"AdSubtract",name:"A locked AdSubtract server", transport:transport);
}
else if ( "server: flashcom/" >< low )
{
return report_finding(port:port, proto:"rtmp",name:"Flash Media Server", transport:transport);
}
else if ( low =~ "^\$lock" )
return report_finding(port:port, proto:"DirectConnectHub", name:"A Direct Connect Hub", transport:transport);
else if ( strlen(low) > 34 && "iss ecnra built-in provider" >< substr(low, 34, strlen(low) - 1 ) )
return report_finding(port:port, proto:"issrealsecure", name:"ISS RealSecure", transport:transport);
else if ( strlen(banner) == 4 && banner == 'Q\00\00\00\00' )
return report_finding(port:port, proto:"cpfw1", name:"Check Point FW1 SecuRemote or FW1 FWModule", transport:transport);
else if ( low =~ "^ssl-tunnel/[0-9.]+ prot/[0-9.]+" )
return report_finding(port:port, proto:"ssltunnel", name:"SSLTunnel (a VPN solution)", transport:transport);
else if ( "adsgone blocked html ad" >< low )
return report_finding(port:port, proto:"adsgone", name:"An AdsGone server", transport:transport);
else if ( low =~ "icy 200 ok" )
return report_finding(port:port, proto:"shoutcast", transport:transport);
else if (
low =~ "^200.*running eudora internet mail server" ||
"+ok applepasswordserver" >< low ||
low =~ "^220.*poppassd" ||
low =~ "^200.*poppassd" ||
low =~ "^poppassd hello" )
{
return report_finding(port:port, proto:"pop3pw", transport:transport);
}
else if ( banner =~ "^220" && " SNPP" >< banner )
{
return report_finding(port:port, proto:"snpp", name:"An SNPP server", transport:transport);
}
else if ( getdword(blob:banner, pos:0) == (strlen(banner) - 4) &&
"krbtgt" >< banner )
{
return report_finding(port:port, proto:"krbtgt", name:"A Kerberos ticket server", transport:transport);
}
else if ( "ccproxy" >< low && "smtp service ready" >< low)
return report_finding(port:port, proto:"ccproxy-smtp", name:"A CCProxy SMTP proxy", transport:transport);
else if ( (
"smtp" >< low ||
"simple mail transfer" >< low ||
"mail server" >< low ||
"messaging" >< low ||
"connection rate limit exceeded" >< low ||
"weasel" >< low) && low =~ "^(220|421)" )
return report_finding(port:port, proto:"smtp", name:"An SMTP server", transport:transport);
# FTV-40905-469: False detection of an FTP server
# "220 ***************" >< banner
else if (low =~ "^220 esafe(@|alert)" ||
low =~ "^220.*groupwise internet agent" )
return report_finding(port:port, proto:"smtp", name:"An SMTP server", transport:transport);
else if ( ord(low[0]) != 0 && "host '" >< low && "mysql" >< low )
return report_finding(port:port, proto:"mysql", name:"A MySQL server", transport:transport);
else if ( ord(low[0]) != 0 && "host '" >< low && "mariadb" >< low )
return report_finding(port:port, proto:"mysql", name:"A MariaDB server", transport:transport);
else if ( ord(low[0]) != 0 && "can't create a new thread (errno" >< low && "if you are not out of available memory, you can consult" >< low )
return report_finding(port:port, proto:"mysql-broken", name:"A MySQL server which is out of resources", transport:transport);
else if ( low =~ "^efatal" ||
low =~ "^einvalid packet length" )
return report_finding(port:port, proto:"postgresql", name:"A PostgreSQL server", transport:transport);
else if ( "cvsup server ready" >< low )
return report_finding(port:port, proto:"cvsup", name:"A CVSup server", transport:transport);
else if ( low =~ "cvs \[p?server aborted\]:" )
return report_finding(port:port, proto:"cvspserver", name:"A CVS pserver", transport:transport);
else if ( low =~ "^cvslock" )
return report_finding(port:port, proto:"cvslock", name:"A CVSLock server", transport:transport);
else if ( low =~ "@rsyncd" )
return report_finding(port:port, proto:"rsyncd", name:"An rsync server", transport:transport);
else if ( strlen(banner) == 4 && may_be_time(banner) )
return report_finding(port:port, proto:"time", name:"A time server", transport:transport);
else if ( ("rmserver" >< low || "realserver" >< low) && "server: apache" >!< low )
return report_finding(port:port, proto:"realserver", name:"A RealMedia server", transport:transport);
else if ( "ccproxy ftp service" >< low )
return report_finding(port:port, proto:"ccproxy-ftp", name:"A CCProxy FTP proxy", transport:transport);
else if ( ("ftp" >< low ||
"winsock" >< low ||
"axis network camera" >< low ||
"netpresenz" >< low ||
"serv-u" >< low ||
"service ready for new user" >< low ) && low =~ "^2[23]0" )
return report_finding(port:port, proto:"ftp", name:"An FTP server", transport:transport);
else if ( low =~ "^220-" && port != 25 && port != 63 && port != 2628 )
return report_finding(port:port, proto:"ftp", name:"An FTP server", transport:transport);
else if ( low =~ "^220" && "whois+" >< low )
return report_finding(port:port, proto:"whois++", name:"A whois++ server", transport:transport);
else if ( "520 command could not be executed" >< low )
return report_finding(port:port, proto:"mon", name:"A mon server", transport:transport);
else if ( pgrep(pattern:"^SSH-[0-9.]+-", string:banner) )
return report_finding(port:port, proto:"ssh", name:"An SSH server", transport:transport);
else if ( pgrep(pattern:"^relaylock: ", string:banner) )
return report_finding(port:port, proto:"plesk-relay-lock", name:"An broken relay-lock server", transport:transport);
else if ( "ok welcome to the nails statistics service" >< low)
return report_finding(port:port, proto:"nailsd", name:"NAILS Statistics Service from McAfee LinuxShield", transport:transport);
else if ( "ccproxy" >< low && "pop3 service ready" >< low)
return report_finding(port:port, proto:"ccproxy-pop3", name:"A CCProxy POP3 proxy", transport:transport);
else if ( low =~ "^\+ok" ||
( low[0] == '+' && "pop" >< low ) )
{
if ( port == 109 )
return report_finding(port:port, proto:"pop2", name:"A POP2 server", transport:transport);
else
return report_finding(port:port, proto:"pop3", name:"A POP3 server", transport:transport);
}
else if ( low =~ "^\+ok *hello there" )
return report_finding(port:port, proto:"pop3", name:"A POP3 server", transport:transport);
else if ( low =~ "^\-err this server is currently" )
return report_finding(port:port, proto:"broken-pop3", name:"A POP3 server under maintenance", transport:transport);
else if ( ("imap4" >< low && low =~ "^\* ?ok") ||
low =~ "^\*ok iplanet messaging multiplexor" ||
low =~ "^\*ok communigate pro imap server" ||
low =~ "^\* ok courier-imap" ||
low =~ "^\* ok dbmail imap" ||
(low =~ "^\* ok server ready" && "unauthorized access prohibited." >< low) ||
low =~ "^\* ok imaprev1" )
return report_finding(port:port, proto:"imap", name:"An IMAP server", transport:transport);
else if ( low =~ "^giop" )
return report_finding(port:port, proto:"giop", name:"A GIOP-enabled service", transport:transport);
else if ( "microsoft routing server" >< low )
return report_finding(port:port, proto:"exchg-routing", name:"A Microsoft Exchange routing server", transport:transport);
else if ( "gap service ready" >< low )
return report_finding(port:port, proto:"iPlanetENS", name:"iPlanet ENS (Event Notification Server)", transport:transport);
else if ("-service not available" >< low )
return report_finding(port:port, proto:"tcpmux", transport:transport);
else if ( strlen(banner) > 2 &&
substr(banner,0,4) == '\x7f\x7fICA' )
return report_finding(port:port, proto:"citrix", name:"A Citrix server", transport:transport);
else if ( "496365500100010003000e000000" >< hexstr(banner) )
return report_finding(port:port, proto:"hp-remote-graphics", name:"An HP Remote Graphics server", transport:transport);
else if ( banner =~ "^[0-9][0-9][0-9][ -]" &&
(" INN " >< banner ||
" Leafnode " >< banner ||
" nntp daemon" >< low ||
" nnrp service ready" >< low ||
" nntp server ready" >< low ||
"posting ok" >< low ||
"posting allowed" >< low ||
"502 no permission" >< low ||
low =~ "^502.*diablo" ) )
return report_finding(port:port, proto:"nntp", name:"An NNTP server", transport:transport);
else if ( "networking/linuxconf" >< low ||
"networking/misc/linuxconf" >< low ||
"server: linuxconf" >< low )
return report_finding(port:port, proto:"linuxconf", name:"LinuxConf", transport:transport);
else if ( banner =~ "^gnudoit:" )
return report_finding(port:port, proto:"gnuserv", name:"A GNUserv server", transport:transport);
else if ( strlen(banner) > 5 &&
( banner[0] == '0' && 'error.host\t1' >< low ) ||
( banner[0] == '3' && 'That item is not current available' >< banner ) ||
( banner[0] == '3' && "--6 Bad Request" >< banner ) )
return report_finding(port:port, proto:"gopher", name:"A Gopher server", transport:transport);
else if ('www-authenticate: basic realm="swat"' >< low )
return report_finding(port:port, proto:"swat", name:"A SWAT server", transport:transport);
else if ("vqserver" >< low && "www-authenticate: basic realm=/" >< low )
return report_finding(port:port, proto:"vqServer-admin", transport:transport);
else if ( "1invalidrequest" >< low )
return report_finding(port:port, proto:"mldonkey", name:"MLDonkey, a peer-to-peer client,", transport:transport);
else if ( "get: command not found" >< low )
return report_finding(port:port, proto:"wild_shell", name:"A shell server (possible backdoor)", transport:transport);
else if ( "Microsoft Windows" >< banner &&
"C:\" >< banner &&
"(C) Copyright 1985-" >< banner &&
"Microsoft Corp." >< banner )
return report_finding(port:port, proto:"wild_shell", name:"A shell server (possible backdoor)", transport:transport);
else if ( low == "root@metasploitable:/# ")
return report_finding(port:port, proto:"wild_shell", name:"A shell server (Metasploitable)", transport:transport);
else if ( "Tiny command server. This is a remote command server, not a telnet server." >< banner )
return report_finding(port:port, proto:"wild_shell", name:"A shell server (rcmd.bat) from IpTools", transport:transport);
else if ( "netbus" >< banner )
return report_finding(port:port, proto:"netbus", name:"NetBus", transport:transport);
else if ( "0 , 0 : error : unknown-error" >< low ||
"0, 0: error: unknown-error" >< low ||
"get : error : unknown-error" >< low ||
"0 , 0 : error : invalid-port" >< low ||
pgrep(string: low, pattern:"^[0-9]+ *, *[0-9]+ *: * userid *: *[^: ]* *:") )
return report_finding(port:port, proto:"auth", name:"An identd server", transport:transport);
else if ( low =~ "^http/1\." && pgrep(pattern:"^dav:.*calendar-(access|schedule|proxy)", string:low ) )
{
return report_finding(port:port, proto:"caldav", name:"A CalDAV server", transport:transport);
}
else if ( low =~ "^http/1\." && pgrep(pattern:"^dav:.*calendarserver-principal-property-search", string:low ) )
{
return report_finding(port:port, proto:"caldav-property", name:"A CalDAV property server", transport:transport);
}
else if (
(pgrep(pattern:"^http/1\..*proxy", string:low) && !pgrep(pattern:"^cache-control:.*proxy-revalidate", string:low)) ||
(low =~ "^http/1\." && pgrep(pattern:"^via:", string:low) ) ||
(low =~ "^http/1\." && pgrep(pattern:"^proxy-connection: ", string:low) ) ||
(low =~ "^http/1\." && pgrep(pattern:"^anon-proxy: ", string:low) ) ||
#(low =~ "^http/1\." && "cache" >< low && "bad request" >< low ) ||
# TudouVA (see BID 47508)
("HTTP/1.0 404 Not Found" >< banner && "Server: mmsserver" >< banner && "Allow: GET, HEAD, DELETE" >< banner && "error" >< banner)
)
{
return report_finding(port:port, proto:"http_proxy", name:"An HTTP proxy", transport:transport);
}
else if ( low =~ "^http/1\." && "gnutella " >< low )
return report_finding(port:port, proto:"gnutella", name:"A Gnutella servent", transport:transport);
else if ( banner =~ "^RFB 00" )
return report_finding(port:port, proto:"vnc", transport:transport);
else if ( low =~ "^ncacn_http/1\." )
{
if ( port == 593 ) return report_finding(port:port, proto:"http-rpc-epmap", name:"An http-rpc-epmap", transport:transport);
else return report_finding(port:port, proto:"ncacn_http", name:"An ncacn_http server", transport:transport);
}
else if ( 'GET / HTTP/1.0\r\n\r\n' == banner )
return report_finding(port:port, proto:"echo", name:"An echo server", transport:transport);
else if ( '!"#$%&\'()*+,-./' >< banner &&
'ABCDEFGHIJ' >< banner &&
'abcdefg' >< banner &&
'0123456789' >< banner ) return report_finding(port:port, proto:"chargen", transport:transport);
else if ( "vtun server" >< low )
return report_finding(port:port, proto:"vtun", name:"A VTUN (Virtual Tunnel) server", transport:transport);
else if ( low == "login: password: " ||
( banner =~ "^login: " && port == 540 ))
return report_finding(port:port, proto:"uucp", transport:transport);
else if ( low =~ "^bad request" ||
"invalid protocol request (71): gget / http/1.0" >< low ||
low =~ "^lpd:" ||
"^lpsched" >< low ||
"malformed from address" >< low ||
"no connect permissions" >< low )
return report_finding(port:port, proto:"lpd", name:"An LPD (Line Printer Daemon) server", transport:transport);
else if ( "%%lyskom unsupported protocol" >< low )
return report_finding(port:port, proto:"lyskom", transport:transport);
else if ( "598:get:command not recognized" >< low )
return report_finding(port:port, proto:"ph", transport:transport);
else if ("BitTorrent prot" >< banner )
return report_finding(port:port, proto:"BitTorrent", name:"BitTorrent", transport:transport);
else if ( strlen(banner) >= 3 && substr(banner, 0, 2) == 'A\x01\x02' )
return report_finding(port:port, proto:"smux", name:"An SNMP Multiplexer (smux)", transport:transport);
else if ( low =~ "^0 succeeded" )
return report_finding(port:port, proto:"LISa", name:"A LISa daemon", transport:transport);
else if ( "welcome!psybnc@" >< low ||
"notice * :psybnc" >< low )
return report_finding(port:port, proto:"psybnc", name:"PsyBNC (IRC proxy)", transport:transport);
else if ( banner =~ "^\* ACAP " )
return report_finding(port:port, proto:"acap", name:"An ACAP server", transport:transport);
else if ( low =~ "Sorry, you ([0-9.]*) are not among the allowed hosts" )
return report_finding(port:port, proto:"nagiosd", name:"Nagios", transport:transport);
else if ( banner == '[TS]\nerror\n' || banner == '[TS]\r\nerror\r\n' )
return report_finding(port:port, proto:"teamspeak-tcpquery", transport:transport);
else if ( 'TS3 Client' >< banner && 'TeamSpeak 3 ClientQuery interface' >< banner )
return report_finding(port:port, proto:"teamspeak3-tcpquery", transport:transport);
else if ( banner =~ "^Language received from client: GET / HTTP/1\.0" )
return report_finding(port:port, proto:"websm", name:"A WEBSM server", transport:transport);
else if ( banner == "CNFGAPI" )
return report_finding(port:port, proto:"ofa_express", name:"An OFA/Express server", transport:transport);
else if ( banner =~ "^SuSE Meta pppd" )
return report_finding(port:port, proto:"smppd", name:"A SuSE Meta pppd server", transport:transport);
else if ( banner =~ "^ERR UNKNOWN-COMMAND" )
return report_finding(port:port, proto:"upsmon", name:"A upsd/upsmon server", transport:transport);
else if ( banner =~ "^connected\..*, ver: Legends" )
return report_finding(port:port, proto:"sub7", name:"A Sub7 trojan", transport:transport);
else if ( banner =~ "^WinShell:" )
return report_finding(port:port, proto:"winshell", name:"A WinShell trojan", transport:transport);
else if ( banner =~ "^SPAMD/[0-9.]*" )
return report_finding(port:port, proto:"spamd", name:"SpamAssassin (spamd)", transport:transport);
else if ( banner =~ "^220" && " dictd " >< low )
return report_finding(port:port, proto:"dictd", name:"dictd, a dictionary database server,", transport:transport);
else if ( banner =~ "^220 " && "VMware Authentication Daemon" >< banner )
return report_finding(port:port, proto:"vmware_auth", name:"A VMware authentication daemon", transport:transport);
else if ( low =~ "^220.* interscan version" )
return report_finding(port:port, proto:"interscan_viruswall", name:"An InterScan VirusWall", transport:transport);
else if ( strlen(banner) > 1 && banner[0] == '~' && banner[strlen(banner) - 1] == '~' && !isnull(strstr(banner, '}')) )
return report_finding(port:port, proto:"pppd", name:"A PPP daemon", transport:transport);
else if ( banner =~ "Hello, this is ([Zz]ebra|[Qq]uagga)" )
return report_finding(port:port, proto:"zebra", name:"A zebra daemon", transport:transport);
else if ( "NOTICE AUTH :" >< banner || "NOTICE Auth :" >< banner )
{
return report_finding(port:port, proto:"irc", name:"An IRC server");
}
else if ( "ircxpro " >< low )
return report_finding(port:port, proto:"ircxpro_admin", name:"An IRCXPro administrative server", transport:transport);
else if ( low =~ "^.*version report" )
return report_finding(port:port, proto:"gnocatan", name:"A Gnocatan game server", transport:transport);
else if ( banner =~ "^RTSP/1\.0.*QTSS/" )
return report_finding(port:port, proto:"quicktime-streaming-server", name:"A Quicktime streaming server", transport:transport);
else if ( banner =~ "^RTSP/1.0 400 " )
return report_finding(port:port, proto:"rtsp", name:"A streaming server is running on this port", transport:transport);
else if ( strlen(banner) > 2 && ord(banner[0]) == 0x30 && ord(banner[1]) == 0x11 && ord(banner[2]) == 0 )
return report_finding(port:port, proto:"dameware", transport:transport);
else if ( "stonegate firewall" >< low )
return report_finding(port:port, proto:"SG_ClientAuth", name:"A StoneGate authentication server", transport:transport);
else if ( low =~ "^pbmasterd" )
{
info = "A PowerBroker master server";
ver = pregmatch(string:low, pattern:'^pbmasterd([0-9.-]+)@');
if (ver)
{
info += ' (version ' + ver[1] + ')';
set_kb_item(name:'pbmasterd/' + port + '/version', value:ver[1]);
}
return report_finding(port:port, proto:"power-broker-master", name:info, transport:transport);
}
else if ( low =~ "^pblocald" )
{
info = "A PowerBroker locald server";
ver = pregmatch(string:low, pattern:'^pblocald([0-9.-]+)@');
if (ver)
{
info += ' (version ' + ver[1] + ')';
set_kb_item(name:'pblocald/' + port + '/version', value:ver[1]);
}
return report_finding(port:port, proto:"power-broker-locald", name:info, transport:transport);
}
else if ( low =~ "^pblogd" )
{
info = "A PowerBroker logd server";
ver = pregmatch(string:low, pattern:'^pblogd([0-9.-]+)@');
if (ver)
{
info += ' (version ' + ver[1] + ')';
set_kb_item(name:'pblogd/' + port + '/version', value:ver[1]);
}
return report_finding(port:port, proto:"power-broker-logd", name:info, transport:transport);
}
else if ( low =~ "^<stream:error>invalid xml</stream:error>" )
return report_finding(port:port, proto:"jabber", name:"jabber", transport:transport);
else if ( low =~ "^/c -2 get ctgetoptions" )
return report_finding(port:port, proto:"avotus_mm", name:"An avotus 'mm' server", transport:transport);
else if ( low =~ "^error:wrong password" )
return report_finding(port:port, proto:"pNSClient", name:"pNSClient.exe, a Nagios plugin,", transport:transport);
else if ( banner =~ "^1000 2" )
return report_finding(port:port, proto:"VeritasNetBackup", name:"Veritas NetBackup", transport:transport);
else if ("the file name you specified is invalid" >< low &&
"listserv" >< low )
return report_finding(port:port, proto:"listserv", name:"A LISTSERV daemon", transport:transport);
else if ( low =~ "^control password:" )
return report_finding(port:port, proto:"FsSniffer", name:"FsSniffer, a password-stealing backdoor,", transport:transport);
else if ( banner == "Gh0st" )
return report_finding(port:port, proto:"ghost-rat", name:"Gh0st, a Remote Admin Tool often used as a backdoor,", transport:transport);
else if ( low =~ "^remotenc control password:")
return report_finding(port:port, proto:"RemoteNC", name:"RemoteNC, a backdoor trojan,", transport:transport);
else if ( "error while loading shared libraries :" >< low )
return report_finding(port:port, proto:"broken-inetd", name:"A broken inetd service (which can't load the shared libraries it depends on)", transport:transport);
else if ( "A E O N I A N D R E A M S" >< banner &&
"R E A W A K E N E D" >< banner )
return report_finding(port:port, proto:"aeonian-dreams", name:"A 'Aeonian Dreams' game server", transport:transport);
else if ( "finger: GET: no such user" >< banner ||
"finger: /: no such user" >< banner ||
"finger: HTTP/1.0: no such user" >< banner ||
"Login Name TTY Idle When Where" >< banner ||
"Line User" >< banner ||
"Login name: GET" >< banner )
return report_finding(port:port, proto:"finger", name:"A finger daemon", transport:transport);
else if ( strlen(banner) >= 4 && ord(banner[0]) == 5 && ord(banner[1]) <= 8 && ord(banner[2]) == 0 && ord(banner[3]) <= 4 && ord(banner[1]) == strlen(banner) - 2)
return report_finding(port:port, proto:"socks5",name:"A SOCKS5 proxy", transport:transport);
else if ( strlen(banner) >= 4 && ord(banner[0]) == 0 && ord(banner[1]) >= 90 && ord(banner[1]) <= 93 )
return report_finding(port:port, proto:"socks4",name:"A SOCKS4 proxy", transport:transport);
else if ( pgrep(pattern:"^server: heimdal/[0-9.]+", string:low) )
{
low = ereg_replace(pattern:"^server: heimdal/([0-9.]+).*", string:pgrep(pattern:"^server: heimdal/[0-9.]+", string:low), replace:"\1");
return report_finding(port:port, proto:"krbtgt", name:"A kerberos ticketing server (Heimdal v" + chomp(low) + ")", transport:transport);
}
# This looks like a broken web server; eg, it responds to GET requests with:
# HTTP/1.1 501 Not Implemented
# CIMError: Only POST and M-POST are implemented
else if ( pgrep(pattern:"^cimerror: ", string:low) )
{
return report_finding(port:port, proto:"cim_listener", name:"A CIM Listener", transport:transport);
}
else if ( preg(string:low, pattern:'^http/[0-9.]+ 501 not implemented', multiline:TRUE) &&
preg(string:low, pattern:'^server: sfchttpd', multiline:TRUE) )
{
return report_finding(port:port, proto:"cim_listener", name:"SBLIM Small Footprint CIM Broker", transport:transport);
}
else if ( banner =~ "^<<<check_mk>>>" )
{
return report_finding(port:port, proto:"check_mk", name:"A Check_MK agent", transport:transport);
}
else if ( banner =~ "Groovy Shell" &&
'Type \'go\' to execute statements' >< banner)
{
return report_finding(port:port, proto:"groovy_shell", name:"Groovy Shell", transport:transport);
}
else if (banner =~ "^Android Console: type 'help' for a list of commands\r\nOK\r\n")
{
return report_finding(port:port, proto:"android_emulator_telnet", name:"An Android Emulator Telnet service", transport:transport);
}
else if (banner =~ '^\\(error "-3: \\([^)]+\\): Command not supported"\\)')
{
return report_finding(port:port, proto:"cogent_datahub_mirror", name:"Cogent DataHub Tunnel/Mirror service", transport:transport);
}
else if (
"ViPER Monitor Transport Protocol" >< banner &&
"ViPERManager" >< banner
)
{
# May be associated with Mitel ViPER virtual cards for giving IP addresses to legacy devices.
return report_finding(port:port, proto:"vmtp", name:"A ViPER Monitor Transport Protocol (VMTP) service", transport:transport);
}
else if (
banner == '0 {}\r\n' ||
banner == '0 {}\n'
)
{
return report_finding(port:port, proto:"3par_mgmt", name:"HP 3PAR Management Service", transport:transport);
}
else if (
'FSAE server' >< banner &&
'FSAE_SERVER_' >< banner &&
getdword(blob:banner, pos:0) == strlen(banner))
{
report_finding(port:port, proto:"fsae_server", name:"Fortinet Server Authentication Agent", transport:transport);
}
else if (banner =~ '^SRS:Ready')
{
return report_finding(port:port, proto:"splashtop_streamer", name:"Splashtop Streamer service", transport:transport);
}
else if (preg(string:banner, pattern:'^220 *\\*+\r\n'))
{
set_kb_item(name:"Services/filtered", value:port);
return report_finding(port:port, proto:"cisco_pix_filtered_smtp", name:"An SMTP service filtered by Cisco PIX", transport:transport);
}
else if ( is_http != 1 )
return register_unknown(port:port, banner:banner);
return NULL;
}
#------------------#
# Banner Grabbing #
#------------------#
function ssl_ports_init()
{
var item;
g_ssl_ports_H = make_array();
foreach item ( g_ssl_ports ) g_ssl_ports_H[item] = TRUE;
}
#
# Functions definitions
#
function should_try_ssl()
{
var port, s, e;
if ( SSL_PORT_TO_CONNECT == SSL_CONNECT_ALL ) return TRUE;
else if ( SSL_PORT_TO_CONNECT == SSL_CONNECT_NONE ) return FALSE;
port = _FCT_ANON_ARGS[0];
if ( g_ssl_ports_H[port] == TRUE ) return TRUE;
return FALSE;
}
function port_push()
{
if ( _FCT_ANON_ARGS[0] == 139 || _FCT_ANON_ARGS[0] == 445 || _FCT_ANON_ARGS[0] == 3389 ) return NULL; # Do not scan port 139, 445 or 3389
# display("Push ", _FCT_ANON_ARGS[0], "\n");
g_port_pool[g_port_pool_max++] = _FCT_ANON_ARGS[0];
}
function port_pop()
{
if ( g_port_pool_idx >= g_port_pool_max ) return NULL;
else return g_port_pool[g_port_pool_idx++];
}
function port_new()
{
var port, banner, port_start_time;
port = port_pop();
if ( port == NULL ) return FALSE;
g_port_start_time[port] = gettimeofday();
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'Port ' + port + ' tests starting...');
#
# Check whether nessus_tcp_scanner found the banner already
#
banner = get_kb_item("BannerHex/" + port);
if ( isnull(banner) ) banner = get_kb_item( "Banner/" + port );
else banner = hex2raw(s:banner);
if ( should_try_ssl(port) == FALSE )
g_transport_state[port] = E_STATE_IP;
else
g_transport_state[port] = E_STATE_SSL_START;
set_sock_state(port:port, state:S_STATE_CONNECTING);
g_methods[port] = "spontaneous";
if ( ! isnull(banner) )
{
if ( is_ssl_banner(banner) && SSL_PORT_TO_CONNECT != SSL_CONNECT_NONE )
{
# This looks like SSL - let's force a negotiation here
g_transport_state[port] = E_STATE_SSL_START;
}
else
{
g_transport_state[port] = E_STATE_IP;
set_sock_state(port:port, state:S_STATE_DONE);
g_banners[port] = banner;
replace_kb_item(name:"Transports/TCP/" + port, value:ENCAPS_IP);
return port_new();
}
}
g_timestamps[port] = unixtime();
if ( g_sock[port] > 0 )
{
close(g_sock[port]);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Closed socket to port ' + port);
}
g_sock[port] = open_sock_tcp(port, transport:state_to_transport[g_transport_state[port]], nonblocking:TRUE);
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'Opened socket to port ' + port);
return TRUE;
}
function port_done()
{
var port;
port = _FCT_ANON_ARGS[0];
set_sock_state(port:port, state:S_STATE_DONE);
close(g_sock[port]);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Closed socket to port ' + port);
g_sock[port] = NULL;
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'Port ' + port + ' tests completed in ' + timediff(g_port_start_time[port]) + ' seconds');
if (g_sock_conn_tries[port] > 0)
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' took ' + g_sock_conn_tries[port] + ' connection tries before completing.');
port_new();
}
function mark_wrapped_svc()
{
var port;
port = _FCT_ANON_ARGS[0];
if ( port == 514 ) return NULL;
security_note(port:port, extra:'The service closed the connection without sending any data.\nIt might be protected by some sort of TCP wrapper.');
set_kb_item(name:"Services/wrapped", value:port);
}
function port_connect_error()
{
var port, port_start_time;
port = _FCT_ANON_ARGS[0];
port_start_time = gettimeofday();
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' test starting...');
if ( g_transport_state[port] < E_STATE_IP )
{
transition_state(port:port);
set_sock_state(port:port, state:S_STATE_CONNECTING);
g_timestamps[port] = unixtime();
if ( g_sock[port] > 0 )
{
close(g_sock[port]);
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'Closed socket to port ' + port);
}
g_sock[port] = open_sock_tcp(port, transport:state_to_transport[g_transport_state[port]], nonblocking:TRUE);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Opened socket to port ' + port);
}
else
port_done(port);
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'Port ' + port + ' test completed in ' + timediff(port_start_time) + ' seconds');
}
#
# e = error from socket_get_error()
#
function port_process(port, e)
{
var note, ver, port_start_time;
port_start_time = gettimeofday();
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' test starting...');
if ( e < 0 )
{
if ( g_transport_state[port] < E_STATE_IP )
{
transition_state(port:port);
set_sock_state(port:port, state:S_STATE_CONNECTING);
g_timestamps[port] = unixtime();
if ( g_sock[port] > 0 )
{
close(g_sock[port]);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Closed socket to port ' + port);
}
g_sock[port] = open_sock_tcp(port, transport:state_to_transport[g_transport_state[port]], nonblocking:TRUE);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Opened socket to port ' + port);
}
else port_done(port);
}
else
{
if ( (g_transport_state[port] == E_STATE_TLSv11 && !TLSv1_1_AVAILABLE) ||
(g_transport_state[port] == E_STATE_TLSv12 && !TLSv1_2_AVAILABLE) ||
(g_transport_state[port] == E_STATE_TLSv13 && !TLSv1_3_AVAILABLE) ||
g_transport_state[port] == E_STATE_TLS_HELLO ||
g_transport_state[port] == E_STATE_SSL3_HELLO ||
g_transport_state[port] == E_STATE_SSL2_HELLO)
{
if (get_kb_item("global_settings/disable_ssl_cipher_neg"))
{
# don't fail it since it didn't attempt a connection. just let the
# state transitions work it out.
transition_state(port:port);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' test completed in ' + timediff(port_start_time) + ' seconds');
return 1;
}
ver = SSL_hello(port:port);
if ( ver > 0 )
{
note = '';
set_sock_state(port:port, state:S_STATE_DONE);
set_kb_item(name:"Transport/SSL", value:port);
# Do *NOT* set Transport/TCP/<port> here as the engine does not support TLSv1.1+
# These KBs are set by ssl_supported_versions.nasl, why set here?
#if ( g_transport_state[port] == E_STATE_TLSv11 )
# set_kb_item(name:"SSL/Transport/" + port, value:COMPAT_ENCAPS_TLSv11);
#else
# set_kb_item(name:"SSL/Transport/" + port, value:COMPAT_ENCAPS_TLSv12);
if ( ver == TLS_11 ) note = 'A TLSv1.1';
else if (ver == TLS_12 ) note = 'A TLSv1.2';
else if (ver == TLS_13 ) note = 'A TLSv1.3';
else if (ver == TLS_10 ) note = 'A TLSv1';
else if (ver == SSL_V3 ) note = 'A SSLv3';
else if (ver == SSL_V2 ) note = 'A SSLv2';
if ( strlen(note) > 0 )
{
note = note + ' server answered on this port.\n';
security_note(port:port, extra:note);
}
port_done(port);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' test completed in ' + timediff(port_start_time) + ' seconds');
return NULL;
}
else
{
transition_state(port:port);
set_sock_state(port:port, state:S_STATE_CONNECTING);
g_timestamps[port] = unixtime();
if ( g_sock[port] > 0 )
{
close(g_sock[port]);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Closed socket to port ' + port);
}
g_sock[port] = open_sock_tcp(port, transport:state_to_transport[g_transport_state[port]], nonblocking:TRUE);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Opened socket to port ' + port);
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' test completed in ' + timediff(port_start_time) + ' seconds');
return NULL;
}
}
# We are connected
replace_kb_item(name:"Transports/TCP/" + port, value:state_to_transport[g_transport_state[port]]);
if( state_to_transport[g_transport_state[port]] != ENCAPS_IP )
{
set_kb_item(name:"Transport/SSL", value:port);
if ( state_to_transport[g_transport_state[port]] == ENCAPS_SSLv2 ) note ='An SSLv2';
else if ( state_to_transport[g_transport_state[port]] == ENCAPS_SSLv3 ) note ='An SSLv3';
else if ( state_to_transport[g_transport_state[port]] == ENCAPS_TLSv1 ) note ='A TLSv1';
else if ( state_to_transport[g_transport_state[port]] == COMPAT_ENCAPS_TLSv11 ) note ='A TLSv1.1';
else if ( state_to_transport[g_transport_state[port]] == COMPAT_ENCAPS_TLSv12 ) note ='A TLSv1.2';
else if ( state_to_transport[g_transport_state[port]] == COMPAT_ENCAPS_TLSv13 ) note ='A TLSv1.3';
else note = NULL;
if ( note )
{
note = note + ' server answered on this port.\n';
security_note(port:port, extra:note);
}
}
set_sock_state(port:port, state:S_STATE_READING);
}
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' test completed in ' + timediff(port_start_time) + ' seconds');
return 1;
}
function port_send_get()
{
var port, port_start_time;
port = _FCT_ANON_ARGS[0];
port_start_time = gettimeofday();
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' test starting...');
send(socket:g_sock[port], data:'GET / HTTP/1.0\r\n\r\n');
set_sock_state(port:port, state:S_STATE_READING_W_GET);
g_methods[port] = "get_http";
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' test completed in ' + timediff(port_start_time) + ' seconds');
}
##
# Set the state and log if debugging is enabled
#
# @param [port:integer] port number
# @param [state:integer] state as a constant variable (e.g. S_STATE_CONNECTING, S_STATE_READING_W_GET)
#
# @remark modifies global variable g_sock_state
#
# @return NULL always
##
function set_sock_state(port, state)
{
if (get_kb_item("global_settings/enable_plugin_debugging"))
{
var current_state = g_sock_state[port];
if (empty_or_null(current_state))
{
g_port_state_time[port] = gettimeofday();
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' state ' + S_STATE_DESCRIPTIONS[state] + ' starting...');
}
# State change
else if (state != current_state)
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' state ' + S_STATE_DESCRIPTIONS[state] + ' completed in ' + timediff(g_port_state_time[port]) + ' seconds');
if (state == S_STATE_DONE)
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' state set to S_STATE_DONE.');
else
{
g_port_state_time[port] = gettimeofday();
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Port ' + port + ' state ' + S_STATE_DESCRIPTIONS[state] + ' starting...');
}
}
}
g_sock_state[port] = state;
}
function select()
{
var port, now, e, e2, num, state;
num = 0;
now = unixtime();
foreach port ( keys(g_sock) )
{
if ( g_sock_state[port] == S_STATE_CONNECTING )
{
num ++;
e = socket_get_error(g_sock[port]);
if ( e != 0 && e != EINPROGRESS )
{
if ( e == ECONNREFUSED )
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Connection refused on port ' + port);
port_done(port);
}
else port_connect_error(port); # Some error occurred
}
e2 = socket_ready(g_sock[port]);
if ( e2 > 0 )
{
if(isnull(port_process(port:port, e:e)))
g_sock_conn_tries[port] ++;
if(g_sock_conn_tries[port] > CONNECT_RETRIES)
num --;
}
else if ( e2 == 0 && (socket_get_error(g_sock[port]) != 0 &&
socket_get_error(g_sock[port]) != EINPROGRESS) ) port_connect_error(port);
else if ( e2 < 0 || (now - g_timestamps[port] >= CONNECT_TIMEOUT) ) port_connect_error(port);
}
else if ( g_sock_state[port] == S_STATE_READING )
{
num ++;
g_sock_conn_tries[port] = 0;
if ( socket_pending(g_sock[port]) )
{
g_banners[port] = recv(socket:g_sock[port], length:65535);
#display(hexstr(g_banners[port]), "\n");
if ( isnull(g_banners[port]) && socket_get_error(g_sock[port]) == ECONNRESET )
mark_wrapped_svc(port);
else if ( isnull(g_banners[port]) && socket_get_error(g_sock[port]) == ETIMEDOUT)
{
port_send_get(port);
continue;
}
else if ( isnull(g_banners[port]) )
register_unknown(port:port, banner:NULL);
port_done(port);
}
else if ( now - g_timestamps[port] >= SPONTANEOUS_TIMEOUT )
port_send_get(port);
}
else if ( g_sock_state[port] == S_STATE_READING_W_GET )
{
num ++;
g_sock_conn_tries[port] = 0;
if ( socket_pending(g_sock[port]) )
{
g_banners[port] = recv(socket:g_sock[port], length:65535);
#display(hexstr(g_banners[port]), "\n");
if ( g_banners[port] == NULL ) register_unknown(port:port, banner:NULL);
port_done(port);
}
else if ( now - g_timestamps[port] >= TIMEOUT)
{
register_unknown(port:port, banner:NULL);
register_silent(port);
port_done(port);
}
}
}
return num;
}
#-----------#
# Main #
#-----------#
function main()
{
var list, item, i, port, pref, rt, to2, k;
var execution_start_time, select_start_time;
execution_start_time = gettimeofday();
dbg::detailed_log(lvl:1, src:FUNCTION_NAME, msg:
'execution starting...');
rt = get_read_timeout();
pref = int(get_preference("max_checks"));
if (pref > 0)
{
MAX_SIMULT_CONNECTIONS = pref;
if (islocalnet())
MAX_SIMULT_CONNECTIONS *= 2;
else
{
# Congestion information in KB is not reliable in 4.0.1 or earlier
pref = int(get_preference("TCPScanner/NbPasses"));
if (pref <= 0) pref = int(get_preference("SYNScanner/NbPasses"));
if (pref > 0 && pref <= 2) pref *= 2;
}
}
# Just in case..
foreach k (["max_simult_tcp_sessions", "global.max_simult_tcp_sessions", "host.max_simult_tcp_sessions"])
{
pref = int(get_preference(k));
if (pref > 0 && MAX_SIMULT_CONNECTIONS > pref)
MAX_SIMULT_CONNECTIONS = pref;
}
if ( MAX_SIMULT_CONNECTIONS > 32 ) MAX_SIMULT_CONNECTIONS = 32;
set_kb_item(name: "FindService/MaxSimultCnx", value: MAX_SIMULT_CONNECTIONS);
if (rt > 30)
to2 = rt;
else
{
to2 = 2 * rt;
if (to2 > 30) to2 = 30;
}
CONNECT_TIMEOUT = to2;
TIMEOUT = to2;
pref = get_preference("Test SSL based services");
# Changed preference name to support .nessus policy import, but policies using the old
# name are still out there.
if(isnull(pref))
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'New preference returned NULL. Trying legacy preference.');
pref = script_get_preference("Test SSL based services");
}
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'TLS discovery preference is: ' + pref);
if ( "All" >< pref )
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Detecting TLS on all discovered ports.');
SSL_PORT_TO_CONNECT = SSL_CONNECT_ALL;
}
else if ( "None" >< pref )
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Not performing TLS service discovery.');
SSL_PORT_TO_CONNECT = SSL_CONNECT_NONE;
set_kb_item(name:"global_settings/disable_test_ssl_based_services", value:TRUE);
}
else if ( "Known" >< pref )
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Checking for TLS services only on ports known to host them.');
SSL_PORT_TO_CONNECT = SSL_CONNECT_KNOWN;
}
else
{
dbg::detailed_log(lvl:3, src:FUNCTION_NAME, msg:
'Unrecognized TLS service discovery setting. Defaulting to \'All ports\'.');
SSL_PORT_TO_CONNECT = SSL_CONNECT_ALL;
}
list = get_kb_list("Ports/tcp/*");
if ( isnull(list) )
{
dbg::detailed_log(lvl:1, src:FUNCTION_NAME, msg:
'Plugin exited, no Ports/tcp/*');
dbg::detailed_log(lvl:1, src:FUNCTION_NAME, msg:
'execution completed in ' + timediff(execution_start_time) + ' seconds');
exit(0, "No open ports were detected."); # No open port
}
list = keys(list);
if ( max_index(list) > 1500 )
{
dbg::detailed_log(lvl:1, src:FUNCTION_NAME, msg:
'Plugin exited, Too many open ports.');
dbg::detailed_log(lvl:1, src:FUNCTION_NAME, msg:
'execution completed in ' + timediff(execution_start_time) + ' seconds');
exit(1, "Too many open ports.");
}
dbg::detailed_log(
lvl:3,
src:FUNCTION_NAME,
msg:'Ports list',
msg_details:{
"Value":{"lvl":3, "value":obj_rep(list)}
});
foreach item (list)
{
if (service_is_unknown(port:int(item - "Ports/tcp/")) )
port_push(int(item - "Ports/tcp/"));
}
for ( i = 0 ; i < MAX_SIMULT_CONNECTIONS ; i ++ )
if ( port_new() == FALSE ) break;
select_start_time = gettimeofday();
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'select() loop starting...');
while ( select() != 0 ) usleep(5000);
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'select() loop completed in ' + timediff(select_start_time) + ' seconds');
foreach port ( keys(g_banners) )
{
if ( isnull(g_banners[port]) )
{
register_unknown(port:port, banner:NULL);
continue;
}
#display(hexstr(g_banners[port]), "\n");
set_kb_banner(port: port, type: g_methods[port], banner: g_banners[port]);
three_digits(port:port, banner:g_banners[port]);
recognize_banner(banner:g_banners[port], port:port, transport:state_to_transport[g_transport_state[port]]);
if (port == 21 && !get_kb_item("Scan/Do_Scan_Printers") && !get_kb_item("Host/dead"))
{
var report = check_printer_over_ftp(banner:g_banners[port], port:port);
if(!empty_or_null(report))
{
set_kb_item(name: "Host/dead", value: TRUE);
report_xml_tag(tag:'dead_host', value:TRUE);
dbg::detailed_log(lvl:1, src:FUNCTION_NAME, msg:
'Detected : ' + report + 'Setting Host/dead kb item.\n');
}
}
}
dbg::detailed_log(lvl:1, src:FUNCTION_NAME, msg:
'execution completed in ' + timediff(execution_start_time) + ' seconds');
}
#
# This function goes through every service which showed an SSL error when
# being connected to, and forces a SSL negotiation on these.
#
function try_non_std_ssl_ports()
{
var i, port, select_start_time;
dbg::detailed_log(
lvl:3,
src:FUNCTION_NAME,
msg:'g_ssl_ports_to_try',
msg_details:{
"value":{"lvl":3, "value":obj_rep(g_ssl_ports_to_try)}
});
if ( g_ssl_ports_to_try_idx == 0 ) return NULL;
if (get_kb_item("global_settings/disable_ssl_cipher_neg")) return NULL;
#
# Reset globals
#
globals_reset();
#
# Mark all ports to be SSL compatible
#
SSL_PORT_TO_CONNECT = SSL_CONNECT_ALL;
for ( i = 0 ; i < g_ssl_ports_to_try_idx ; i ++ )
port_push(g_ssl_ports_to_try[i]);
for ( i = 0 ; i < MAX_SIMULT_CONNECTIONS ; i ++ )
if ( port_new() == FALSE ) break;
select_start_time = gettimeofday();
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'select() loop starting...');
while ( select() != 0 ) usleep(5000);
dbg::detailed_log(lvl:2, src:FUNCTION_NAME, msg:
'select() loop completed in ' + timediff(select_start_time) + ' seconds');
foreach port ( keys(g_banners) )
{
if ( isnull(g_banners[port]) ) continue;
set_kb_banner(port: port, type: g_methods[port], banner: g_banners[port]);
three_digits(port:port, banner:g_banners[port]);
recognize_banner(banner:g_banners[port], port:port, transport:state_to_transport[g_transport_state[port]]);
}
}
if (nessusd_is_agent())
{
exit(0, 'This plugin does not run on Nessus Agents');
}
var script_start_time = gettimeofday();
dbg::detailed_log(lvl:1, src:SCRIPT_NAME, msg:
'starting...');
globals_init();
ssl_ports_init();
main();
try_non_std_ssl_ports();
dbg::detailed_log(lvl:1, src:SCRIPT_NAME, msg:
'completed in ' + timediff(script_start_time) + ' seconds');