# This script was written by Michel Arboi <mikhail@nessus.org>
# It is released under the GNU Public Licence.

if(description)
{
 script_id(17975);
 script_version ("$Revision: 1.6 $");
 
 name["english"] = "Identifies unknown services with GET";
 script_name(english:name["english"]);
 
 desc["english"] = "
This plugin is a complement of find_service.nes
It recognizes more banners and use an HTTP request if necessary.
 
Risk factor : Low";


 script_description(english:desc["english"]);
 
 summary["english"] = "Sends 'GET' to unknown services and look at the answer";
 script_summary(english:summary["english"]);
 
 script_category(ACT_GATHER_INFO); 
 script_timeout(0);
 script_copyright(english:"This script is Copyright (C) 2005 Michel Arboi");
 script_family(english: "Service detection");
 script_dependencie("find_service.nes");
# Do *not* add a port dependency  on "Services/unknown"
# Some scripts must run after this script even if there are no
# unknown services
 exit(0);
}

#
include("misc_func.inc");
include("global_settings.inc");

port = get_kb_item("Services/unknown");
if (! port) exit(0);
if (! get_port_state(port)) exit(0);
if (known_service(port: port)) exit(0);

# If the service displays a banner on connection, find_service.c does not
# send a GET request. However, if a GET request was sent and the service
# remains silent, the get_http KB entry is void

r0 = get_kb_item('FindService/tcp/'+port+'/spontaneous');	# Banner?
get_sent = ! r0;	# banner => no GET request

k = 'FindService/tcp/'+port+'/get_http';
r = get_kb_item(k);
if (! r)
{
 if (get_sent			# Service did not anwer to GET
     && ! thorough_tests)	# We try again in "thorough tests"
  exit(0);

 soc = open_sock_tcp(port);
 if (! soc) exit(0);
 send(socket: soc, data: 'GET / HTTP/1.0\r\n\r\n');
 r = recv(socket:soc, length:4096);
 close(soc);
 if (! r) exit(0);
 set_kb_item(name: k, value: r);
}

# aka HTTP/0.9
if (r =~ '^[ \t\r\n]*<HTML>.*</HTML>')
{
 report_service(port: port, svc: 'www', banner: r);
 exit(0);
}

if (r == '[TS]\r\n')
{
 report_service(port: port, svc: 'teamspeak-tcpquery', banner: r);
 exit(0);
}

if (r == 'gethostbyaddr: Error 0\n')
{
 register_service(port:port, proto:"veritas-netbackup-client");
 security_note(port:port, data:"Veritas NetBackup Client Service is running on this port");
 exit(0);
}

if ("GET / HTTP/1.0 : ERROR : INVALID-PORT" >< r)
{
 report_service(port: port, svc: 'auth', banner: r);
 exit(0);
}

#### Double check: all this should be handled by find_service.nes ####

if (r == 'GET / HTTP/1.0\r\n\r\n')
{
 report_service(port: port, svc: 'echo', banner: r);
 exit(0);
}

# Should we excluded port=5000...? (see find_service.c)
if (r =~ '^HTTP/1\\.[01] +[1-5][0-9][0-9] ')
{
 report_service(port: port, svc: 'www', banner: r);
 exit(0); 
}

# Suspicious: "3 digits" should appear in the banner, not in response to GET
if (r =~ '^[0-9][0-9][0-9]-?[ \t]')
{
 debug_print('"3 digits" found on port ', port, ' in response to GET\n');
 register_service(port: port, svc: 'three_digits');
 exit(0); 
}
