Lucene search
+L

Service Detection (3 ASCII digit codes like FTP, SMTP, NNTP...)

🗓️ 03 Nov 2005 00:00:00Reported by Copyright (C) 2005 Michel ArboiType 
openvas
 openvas
🔗 plugins.openvas.org👁 78 Views

Service Detection plugin for identifying services with 3 ASCII digit codes like FTP, SMTP, NNTP

Refs
Code
# SPDX-FileCopyrightText: 2005 Michel Arboi
# Some text descriptions might be excerpted from (a) referenced
# source(s), and are Copyright (C) by the respective right holder(s).
#
# SPDX-License-Identifier: GPL-2.0-only

if(description)
{
  script_oid("1.3.6.1.4.1.25623.1.0.14773");
  script_version("2023-06-14T05:05:19+0000");
  script_tag(name:"last_modification", value:"2023-06-14 05:05:19 +0000 (Wed, 14 Jun 2023)");
  script_tag(name:"creation_date", value:"2005-11-03 14:08:04 +0100 (Thu, 03 Nov 2005)");
  script_tag(name:"cvss_base_vector", value:"AV:N/AC:L/Au:N/C:N/I:N/A:N");
  script_tag(name:"cvss_base", value:"0.0");
  script_name("Service Detection (3 ASCII digit codes like FTP, SMTP, NNTP...)");
  script_category(ACT_GATHER_INFO);
  script_copyright("Copyright (C) 2005 Michel Arboi");
  script_family("Service detection");
  script_dependencies("find_service.nasl"); # cifs445.nasl
  script_require_ports("Services/three_digits");
  # "rpcinfo.nasl", "dcetest.nasl"

  script_xref(name:"URL", value:"https://forum.greenbone.net/c/vulnerability-tests/7");

  script_tag(name:"summary", value:"This plugin performs service detection.");

  script_tag(name:"insight", value:"This plugin is a complement of the plugin 'Services' (OID:
  1.3.6.1.4.1.25623.1.0.10330). It attempts to identify services that return 3 ASCII digit codes
  (ie: FTP, SMTP, NNTP, ...).");

  script_tag(name:"qod_type", value:"remote_banner");

  exit(0);
}

include("host_details.inc");
include("global_settings.inc");
include("port_service_func.inc");
include("misc_func.inc");

function read_answer( socket ) {

  local_var socket;
  local_var retry, i, r, answer;

  retry = 2;

  repeat {
    for( i = 0; i <= retry; i++ ) {
      r = recv_line( socket:socket, length:4096 );
      if( strlen( r ) > 0 )
        break;
    }
    answer += r;
  }
  until( ! r || r =~ '^[0-9]{3}[^-]' || strlen( answer ) > 1000000 );
  return answer;
}

if( ! port = get_kb_item( "Services/three_digits" ) )
  exit( 0 );

if( ! get_port_state( port ) )
  exit( 0 );

if( ! service_is_unknown( port:port ) )
  exit( 0 );

if( ! soc = open_sock_tcp( port ) )
  exit( 0 );

banner = read_answer( socket:soc );

if( banner )
  replace_kb_item( name:"FindService/tcp/" + port + "/spontaneous", value:banner );
else
  debug_print( "Banner is void on port ", port, "\n" );

# 500 = Unknown command
# 502 = Command not implemented

# If HELP works, it is simpler than anything else
send( socket:soc, data:'HELP\r\n' );
help = read_answer( socket:soc );
if( help ) {
  replace_kb_item( name:"FindService/tcp/" + port + "/help", value:help );
  if( ! banner )
    banner = help; # Not normal, but better than nothing
}

if( help && help !~ "^50[0-9]" ) {

  # See e.g. the following for a list of NNTP commands:
  # http://www.complang.tuwien.ac.at/tom/Projects/NewsCache/ThesisHTML/node54.html
  if( "ARTICLE" >< help || "NEWGROUPS" >< help || "NEWNEWS" >< help || "XHDR" >< help || "XOVER" >< help || banner =~ "^[0-9]{3} .*(NNTP|NNRP)" ) {
    service_report( port:port, svc:"nntp", banner:banner );
    close( soc );
    exit( 0 );
  }

  # nb: this must come before FTP recognition.
  if( egrep( string:banner, pattern:"^220.*HylaFAX .*Version.*" ) || egrep( string:help, pattern:"^220.*HylaFAX .*Version.*" ) ) {
    service_report( port:port, svc:"hylafax", banner:banner );
    close( soc );
    exit( 0 );
  }

  if( eregmatch( string:help, pattern:".*[a-z]{32}.*Authentication required\." ) ) {
    service_register( port:port, proto:"varnish-cli", message:"A Varnish control terminal seems to be running on this port." );
    log_message( port:port, data:"A Varnish control terminal seems to be running on this port." );
    close( soc );
    exit( 0 );
  }

  # iMQ Broker Rendezvous(imqbrokerd)
  # nb: this must come before FTP recognition.
  if( egrep( pattern:"^101", string:banner ) && ( egrep( pattern:"[a-zA-Z]+broker", string:banner, icase:TRUE ) ||
      egrep( pattern:"portmapper tcp PORTMAPPER", string:banner ) ) ) {
    service_register( port:port, proto:"imqbrokerd" );
    log_message( port:port, data:"A Message Queue broker is running at this port." );
    close( soc );
    exit( 0 );
  }

  # Code from find_service2.nasl
  if( help =~ "^220 .* SNPP " || egrep( string:help, pattern:"^214 .*PAGE" ) ) {
    service_report( port:port, svc:"snpp", banner:banner );
    close( soc );
    exit( 0 );
  }

  if( egrep( string:help, pattern:"^214-? " ) && "MDMFMT" >< help ) {
    service_report( port:port, svc:"hylafax-ftp", banner:banner );
    close( soc );
    exit( 0 );
  }

  # Code from find_service2.nasl:
  # SNPP, HylaFAX FTP, HylaFAX SPP, agobot.fo, IRC bots, WinSock server,
  # Note: this code must remain in find_service2.nasl until we think that
  # all find_service.nasl are up to date
  if( egrep( pattern:"^220 Bot Server", string:help ) ||
      raw_string( 0xb0, 0x3e, 0xc3, 0x77, 0x4d, 0x5a, 0x90 ) >< help ) {
    service_report( port:port, svc:"agobot.fo", banner:banner );
    close( soc );
    exit( 0 );
  }

  if( "220 WinSock" >< help ) { # or banner?
    service_report( port:port, svc:"winsock", banner:banner );
    close( soc );
    exit( 0 );
  }

  if( "PORT" >< help || "PASV" >< help ) {
    service_report( port:port, svc:"ftp", banner:banner );
    close( soc );
    exit( 0 );
  }
}

# e.g.:
# 220 HP GGW server (version 1.0) ready
# 220 JetDirect GGW server (version 1.0) ready
#
# nb: The same pattern is also used in all other find_service2.nasl to find_service6.nasl because
# there is always the slight chance that an overloaded target didn't responded to the initial
# service detection probes.
if( egrep( string:banner, pattern:"^220 (HP|JetDirect) GGW server \(version ([0-9.]+)\) ready" ) ) {
  service_register( port:port, proto:"hp-gsg", message:"A Generic Scan Gateway (GGW) server service is running at this port." );
  log_message( port:port, data:"A Generic Scan Gateway (GGW) server service is running at this port." );
  close( soc );
  exit( 0 );
}

# e.g.
# 554 No SMTPd here
# 554 No SMTP service here
# 554 No smtpd here
# 554-NO SMTP service
#
# nb: This is still a SMTP service which is blocking access according to:
# https://bobcares.com/blog/554-no-smtpd-here/
if( banner =~ "^554[ -]no smtpd? (service|here)" ) {
  service_register( port:port, proto:"smtp" );
  close( soc );
  exit( 0 );
}

# Unknown SMTP service
if( banner =~ "550[ -]Access denied \(not in relay or upstream list\)" ) {
  service_register( port:port, proto:"smtp" );
  close( soc );
  exit( 0 );
}

# nb: Should be outside of the "if" for the help status code above due to the "500" checked here.
if( "500 P-Error" >< help && "220 Hello" >< help ) { # or banner?
  service_report( port:port, svc:"unknown_irc_bot", banner:banner );
  close( soc );
  exit( 0 );
}

if( egrep( pattern:"^200 .* (PWD Server|poppassd)", string:banner ) ) {
  service_register( port:port, proto:"pop3pw" );
  close( soc );
  exit( 0 );
}

# e.g.:
# 220 8a3d01d704b5 LMTP Server (JAMES Protocols Server) ready
# 220 $hostname Zimbra LMTP server ready
# 220 2.1.5 LMTP server is ready
if( egrep( string:banner, pattern:"^220 [^ ]+( [^ ]+)? LMTP [Ss]erver.+ready", icase:FALSE ) ) {
  service_report( port:port, svc:"lmtp", banner:banner );
  close( soc );
  exit( 0 );
}

send( socket:soc, data:'HELO mail.example.org\r\n' );
helo = read_answer( socket:soc );

if( egrep( string:helo, pattern:"^250" ) ) {
  service_report( port:port, svc:"smtp", banner:banner );
  close( soc );
  exit( 0 );
}

# nb: Some systems might not include the "LMTP Server" banner above so we're sending a separate LHLO
# one as specified in https://datatracker.ietf.org/doc/html/rfc2033#section-4.1 to catch them.
send( socket:soc, data:'LHLO mail.example.org\r\n' );
lhlo = read_answer( socket:soc );

if( egrep( string:lhlo, pattern:"^250" ) ) {
  service_report( port:port, svc:"lmtp", banner:banner );
  close( soc );
  exit( 0 );
}

send( socket:soc, data:'DATE\r\n' );
date = read_answer( socket:soc );

if( date =~ '^111[ \t]+2[0-9]{3}[01][0-9][0-3][0-9][0-2][0-9][0-5][0-9][0-5][0-9]' ) {
  service_report( port:port, svc:"nntp", banner:banner );
  close( soc );
  exit( 0 );
}

# nb: This should be kept at the bottom to first detect all services above before doing the more
# generic approach via the commands here which could cause some false detections.
ftp_commands = make_list( "CWD", "SYST", "PORT", "PASV" );
ko = 0;

foreach cmd( ftp_commands ) {

  send( socket:soc, data:cmd + '\r\n' );
  r = read_answer( socket:soc );

  if( ! r || egrep( string:r, pattern:"^50[0-9]" ) )
    ko++;
  debug_print( "Answer to ", cmd, ": ", r );

  if( cmd == "SYST" ) {
    # We store the result of SYST just in case. Most (>99%) FTP servers answer
    # "Unix Type: L8" so this is not very informative
    v = eregmatch( string:r, pattern:'^2[0-9][0-9] +(.*)[ \t\r\n]*$' );
    if( ! isnull( v ) )
      set_kb_item( name:"ftp/" + port + "/syst", value:v[1] );
  }
}

close( soc );

if( ! ko ) {
  service_report( port:port, svc:"ftp", banner:banner );
  exit( 0 );
}

if( substr( banner, 0, 3 ) == "200 " ) {
  soc = open_sock_tcp( port );
  if( soc ) {
    vt_strings = get_vt_strings();
    banner = read_answer( socket:soc );
    send( socket:soc, data:string( "USER ", vt_strings["lowercase"], "\r\n" ) );
    r = read_answer( socket: soc );
    if( strlen( r ) > 3 && substr( r, 0, 3 ) == "200 " ) {
      send( socket:soc, data:string( "PASS ", vt_strings["lowercase_rand"], "\r\n" ) );
      r = read_answer( socket:soc );
      if( strlen( r ) > 3 && substr( r, 0, 3 ) == "500 " ) {
        service_register( port:port, proto:"pop3pw" );
        close( soc );
        exit( 0 );
      }
    }
    close( soc );
  }
}

# Give it to find_service2 & others
service_register( port:port, proto:"unknown" );
unknown_banner_set( port:port, banner:banner );

report  = 'Although this service answers with 3 digit ASCII codes like FTP, SMTP or NNTP servers, the Scanner was unable to identify it.\n\n';
report += 'This is highly suspicious and might be a backdoor; in this case, your system is compromised and an attacker can control it remotely.\n\n';
report += '** If you know what it is, consider this message as a false alert and please report it to the referenced community forum.\n\n';
report += 'Solution : disinfect or reinstall your operating system.';

log_message( port:port, data:report );
exit( 0 );

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation