Lucene search
K

Microsoft SQL Server TCP/IP Listener Detection

🗓️ 12 Oct 1999 00:00:00Reported by TenableType 
nessus
 nessus
🔗 www.tenable.com👁 721 Views

Remote Microsoft SQL Server detected; version retrieval possible from pre-login response.

Code
#
# (C) Tenable Network Security, Inc.
#

include("compat.inc");

if (description)
{
  script_id(10144);
  script_version("1.62");
  script_set_attribute(attribute:"plugin_modification_date", value:"2024/07/29");
  script_xref(name:"IAVT", value:"0001-T-0800");

  script_name(english:"Microsoft SQL Server TCP/IP Listener Detection");

  script_set_attribute(attribute:"synopsis", value:
"A database server is listening on the remote port.");
  script_set_attribute(attribute:"description", value:
"The remote host is running MSSQL, a database server from Microsoft. It
is possible to extract the version number of the remote installation
from the server pre-login response.");
  script_set_attribute(attribute:"solution", value:
"Restrict access to the database to allowed IPs only.");
  script_set_attribute(attribute:"risk_factor", value:"None");

  script_set_attribute(attribute:"plugin_publication_date", value:"1999/10/12");

  script_set_attribute(attribute:"plugin_type", value:"remote");
  script_set_attribute(attribute:"asset_inventory", value:"True");
  script_set_attribute(attribute:"asset_inventory_category", value:"software_enumeration");
  script_set_attribute(attribute:"cpe", value:"cpe:/a:microsoft:sql_server");
  script_set_attribute(attribute:"thorough_tests", value:"true");
  script_end_attributes();

  script_category(ACT_GATHER_INFO);
  script_family(english:"Service detection");

  script_copyright(english:"This script is Copyright (C) 1999-2024 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("find_service1.nasl", "find_service2.nasl", "mssql_ping.nasl");
  script_require_ports("Services/unknown", "mssql/possible_port", 1433, "Database/nonstandard_db_port");

  exit(0);
}

include("audit.inc");
include("byte_func.inc");
include("global_settings.inc");
include("install_func.inc");
include("misc_func.inc");
include("spad_log_func.inc");

var report = '';
var app = "Microsoft SQL Server";
var service = "mssql";
var cpe = "cpe:/a:microsoft:sql_server";

if (thorough_tests && !get_kb_item("global_settings/disable_service_discovery"))
{
  unk_ports = get_kb_list("Services/unknown");
  if(! isnull(unk_ports)) unk_ports = make_list(unk_ports);

  ports = add_port_in_list(list:unk_ports, port:1433);
}
else ports = make_list(1433);


# Also test any ports we identified via a "Ping" request in mssql_ping.nasl.
var port;
possible_ports = get_kb_list("mssql/possible_port");
if (!isnull(possible_ports))
{
  foreach port (make_list(possible_ports))
    ports = add_port_in_list(list:ports, port:port);
}

# Add any ports specified in a mssql credential
var idx = 0;
var key = "Database";
var dbtype = get_kb_item(key + "/type");
port = get_kb_item(key + "/Port");
while(!isnull(dbtype))
{
  if(dbtype == 1)
    ports = add_port_in_list(list:ports, port:port);

  idx += 1;
  key = "Database/" + idx;
  dbtype = get_kb_item(key + "/type");
  port = get_kb_item(key + "/Port");
}

port = branch(ports);
# No idea why, but in testing branch returned some ports as 'data' type instead of 'int', causing errors later
# This is just to make sure it's always an integer
port = int(port);
if (!get_tcp_port_state(port)) audit(AUDIT_PORT_CLOSED, port);

soc = open_sock_tcp(port);
if (!soc) audit(AUDIT_SOCK_FAIL, port);

set_byte_order(BYTE_ORDER_BIG_ENDIAN);

data =
  mkbyte(0)    + # Type: VERSION
  mkword(0x1A) + # Offset
  mkword(0x06) + # Length

  mkbyte(1)    + # Type: ENCRYPTION
  mkword(0x20) + # Offset
  mkword(0x01) + # Length

  mkbyte(2)    + # Type: INSOPT
  mkword(0x21) + # Offset
  mkword(0x01) + # Length

  mkbyte(3)    + # Type: THREADID
  mkword(0x22) + # Offset
  mkword(0x04) + # Length

  mkbyte(4)    + # Type: MARS
  mkword(0x26) + # Offset
  mkword(0x01) + # Length

  mkbyte(0xFF) + # Type: TERMINATOR

  # UL_VERSION
  mkbyte(12)   +
  mkbyte(0)    +
  mkword(0)    +

  # UL_SUBBUILD
  mkword(0)    +

  # B_FENCRYPTION
  mkbyte(0)    +

  # B_INSTVALIDITY
  mkbyte(0)    +

  # UL_THREADID
  mkdword(0)   +

  # B_MARS
  mkbyte(0);
len = strlen(data);

req =
  mkbyte(18)      + # Type: Pre-Login Msg
  mkbyte(1)       + # Status: EOM
  mkword(len + 8) + # Length: data+header length
  mkword(0)       + # SPID
  mkbyte(0)       + # PacketID
  mkbyte(0)       + # Window (not used)
  data;

spad_log(message:'sending ' + obj_rep(req));
send(socket:soc, data:req);
buf = recv(socket:soc, length:4096);
len = strlen(buf);

if (len) spad_log(message:'target returned ' + obj_rep(buf));

if (len < 20)
  exit(0, "The service listening on port " + port + " responded with a message too short to be parsed.");

code = getbyte(blob:buf, pos:0);
if (code != 4)
  exit(0, "The service listening on port " + port + " responded with a message of the wrong type.");

plen = getword(blob:buf, pos:2);
if (plen != len)
  exit(0, "The service listening on port " + port + " responded with a message containing an incorrect packet length field.");

encryption = version = NULL;

# Parse first option header.
pos = 8;
while(pos < strlen(buf))
{
  type = getbyte(blob:buf, pos:pos);
  off  = getword(blob:buf, pos:pos + 1);
  dlen = getword(blob:buf, pos:pos + 3);
  pos += 5;

  if(type == 0xFF) break; # TERMINATOR
  if(off == 0) break;

  if(type == 0x00) # VERSION
  {
    if(dlen < 6 || (off + dlen + 8) > len)
      exit(0, "Error parsing version field for service on port " + port + ".");
    off += 8;
    v = make_list(
      getbyte(blob:buf, pos:off),
      getbyte(blob:buf, pos:off+1),
      getword(blob:buf, pos:off+2),
      getword(blob:buf, pos:off+4));
    version = join(v, sep:".");
  }
  else if(type == 0x01) # ENCRYPTION
  {
    if(dlen < 1 || (off + dlen + 8) > len)
      exit(0, "Error parsing encryption field for service on port " + port + ".");
    off += 8;
    encryption = getbyte(blob:buf, pos:off);
  }
}

if(encryption != 0x03) # ENCRYPT_REQ
{
  report += 'The remote MSSQL server accepts cleartext logins.';
  set_kb_item(name:"PCI/ClearTextCreds/" + port, value:report);
}

if(isnull(version))
  exit(1, "Unable to parse version field for service on port " + port + ".");

spad_log(message:'Detected MSSQL version ' + version + ' on port ' + port);
set_kb_item(name:"MSSQL/" + port + "/Version", value:version);

register_service(port:port, proto:"mssql");

var instances = get_kb_list("MSSQL/" + port + "/InstanceName");
if(isnull(instances))
{
  # remote detection may have detected MSSQL version, but failed to detect instance name
  spad_log(message:'No SQL Server instances determined for port ' + port + ' on target.');
  instances = "Instance name not determined";  
}

instances = make_list(instances);

foreach(var instance in instances)
{
  if(empty_or_null(instance))
    continue;

  var extra;
  if (instance != "Instance name not determined")
    extra["InstanceName"] = instance;

  if(!empty_or_null(report))
    extra["Note"] = report;

  register_install(
    vendor   : "Microsoft",
    product  : "SQL Server",
    app_name : app,
    version  : version,
    port     : port,
    service  : strcat(service, "-", instance),
    cpe      : cpe,
    extra    : extra
  );
}

report_installs(app_name:app, port:port);

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

29 Jul 2024 00:00Current
5.5Medium risk
Vulners AI Score5.5
721