Lucene search

K
openvasCopyright (C) 2009 LSSOPENVAS:1361412562310102014
HistoryOct 06, 2009 - 12:00 a.m.

NFS export

2009-10-0600:00:00
Copyright (C) 2009 LSS
plugins.openvas.org
210

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.015 Low

EPSS

Percentile

86.7%

This plugin lists NFS exported shares, and warns if some of them
are readable (

# SPDX-FileCopyrightText: 2009 LSS
# 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-or-later

# Tested on Ubuntu/Debian mountd

if(description)
{
  script_oid("1.3.6.1.4.1.25623.1.0.102014");
  script_version("2023-09-08T05:06:21+0000");
  script_cve_id("CVE-1999-0554", "CVE-1999-0548");
  script_name("NFS export");
  script_tag(name:"last_modification", value:"2023-09-08 05:06:21 +0000 (Fri, 08 Sep 2023)");
  script_tag(name:"creation_date", value:"2009-10-06 18:45:43 +0200 (Tue, 06 Oct 2009)");
  script_tag(name:"cvss_base", value:"10.0");
  script_tag(name:"cvss_base_vector", value:"AV:N/AC:L/Au:N/C:C/I:C/A:C");
  script_category(ACT_GATHER_INFO);
  script_copyright("Copyright (C) 2009 LSS");
  script_family("Remote file access");
  script_dependencies("gb_rpc_portmap_udp_detect.nasl", "gb_rpc_portmap_tcp_detect.nasl");
  script_mandatory_keys("rpc/portmap/tcp_or_udp/detected");

  script_tag(name:"summary", value:"This plugin lists NFS exported shares, and warns if some of them
  are readable ('*' in the plugin output means the share is world readable).

  It also warns if the remote NFS server is superfluous (means no exported shares).");

  script_tag(name:"solution", value:"Verify that the exported shares are not exposing sensitive data
  and check the permissions of these exports.");

  script_tag(name:"solution_type", value:"Mitigation");
  script_tag(name:"qod_type", value:"remote_analysis");

  exit(0);
}

include("rpc.inc");
include("nfs_func.inc");
include("byte_func.inc");

#mountd program number and version
RPC_MOUNTD = 100005;
RPC_MOUNTD_VERSION = 1;
RPC_NFSD = 100003;

####RPC MOUNT EXPORT function####
#  PURPOSE: obtains the targets export list by sending an RPC CALL message to EXPORT procedure of mountd
#  ARGUMENT: -port- on which the mountd daemon is listening
#       -protocol- IPPROTO_UDP(default) or IPPROTO_TCP
#  RETURN: returns the NFSd daemons export list as defined in rfc 1094 (Appendix A)
#    null on error

function rpc_mountd_export(port,protocol){

  XID = raw_string(0x01, 0x23, 0x45, 0x67);                    # rpc message ID, should be the same as reply xid
  RPC_CALL = raw_string(0x00, 0x00, 0x00, 0x00);               # call message = 0
  RPC_VERSION = raw_string(0x00, 0x00, 0x00, 0x02);            # current RPC version = 2
  RPC_PROG = raw_string(0x00, 0x01, 0x86, 0xa5);               # mountd program number = 100005
  RPC_PROG_VERSION = raw_string(0x00, 0x00, 0x00, 0x01);       # mountd program version = 1
  RPC_PROCEDURE = raw_string(0x00, 0x00, 0x00, 0x05);          # mountd export procedure number = 5
  RPC_CREDENTIALS_FLAVOR = raw_string(0x00, 0x00, 0x00, 0x00); # credentials flavor = AUTH_NULL = 0
  RPC_CREDENTIALS_LENGTH = raw_string(0x00, 0x00, 0x00, 0x00); # credentials length = 0
  RPC_VERIFIER_FLAVOR = raw_string(0x00, 0x00, 0x00, 0x00);    # verifier flavor = AUTH_NULL = 0
  RPC_VERIFIER_LENGTH = raw_string(0x00, 0x00, 0x00, 0x00);    # verifier length = 0

  rpc_mountd_export_call = XID +
        RPC_CALL +
        RPC_VERSION +
        RPC_PROG +
        RPC_PROG_VERSION +
        RPC_PROCEDURE +
        RPC_CREDENTIALS_FLAVOR +
        RPC_CREDENTIALS_LENGTH +
        RPC_VERIFIER_FLAVOR +
        RPC_VERIFIER_LENGTH;
  if(isnull(protocol)) {
    protocol = IPPROTO_UDP;
  }
  MSS = 1460; #data len to read at most (maximum segment size for ethernet)
  rpc_mountd_export_reply = NULL;
  if(protocol == IPPROTO_UDP) {
    udp_sock = open_sock_udp(port);
    if(isnull(udp_sock)) {
      return NULL;
    }
    send(socket:udp_sock, data:rpc_mountd_export_call);
    rpc_mountd_export_reply = recv(socket:udp_sock, length:MSS);
    close(udp_sock);
  } else if(protocol == IPPROTO_TCP) {
    tcp_sock = open_sock_tcp(port);
    if(isnull(tcp_sock)) {
      return NULL;
    }
    send(socket:tcp_sock, data:rpc_mountd_export_call);
    rpc_mountd_export_reply = recv(socket:tcp_sock, length:MSS);
    close(tcp_sock);
  } else {
    return NULL;
  }

  if(isnull(rpc_mountd_export_reply)) {
    return NULL;
  }

  #RPC reply
  reply_xid = substr(rpc_mountd_export_reply, 0, 3);
  if(reply_xid != XID) {
    return NULL;
  }
  reply_msg_type = substr(rpc_mountd_export_reply, 4, 7);
  if(reply_msg_type != raw_string(0x00, 0x00, 0x00, 0x01)) {
    return NULL;
  }
  reply_reply_state = substr(rpc_mountd_export_reply, 8, 11);
  if(reply_reply_state != raw_string(0x00, 0x00, 0x00, 0x00)) {
    return NULL;
  }
  reply_verifier_flavor = substr(rpc_mountd_export_reply, 12, 15);
  reply_verifier_length = substr(rpc_mountd_export_reply, 16, 19);
  reply_accept_state = substr(rpc_mountd_export_reply, 20, 23);
  if(reply_accept_state != raw_string(0x00, 0x00, 0x00, 0x00)) {
    return NULL;
  }
  #MOUNTD exportlist
  reply_mountd_exportlist = substr(rpc_mountd_export_reply, 24);
  return reply_mountd_exportlist;
}

####MAIN####

RPC_MOUNTD_port = rpc_get_port(program:RPC_MOUNTD, protocol:IPPROTO_UDP);
RPC_NFSD_port = rpc_get_port(program:RPC_NFSD, protocol:IPPROTO_UDP);

#display("NFSD: " + RPC_NFSD_port + '\n');
#display("MOUNTD port: " + RPC_MOUNTD_port + '\n');

export_list = rpc_mountd_export(port:RPC_MOUNTD_port, protocol:IPPROTO_UDP); #using UDP because rpc_get_port is written only for udp ports
if(isnull(export_list)) {
  exit(0);
} else {
  VALUE_FOLLOWS = raw_string(0x00, 0x00, 0x00, 0x01);
  LEFT = 0;
  RIGHT = 3;
  export_value_follows = substr(export_list, LEFT, RIGHT);
  while(export_value_follows == VALUE_FOLLOWS) {
    LEFT = RIGHT + 1;
    RIGHT = LEFT + 3;
    export_dirpath_length = str2long(val:substr(export_list, LEFT,RIGHT), idx:0);
    LEFT = RIGHT + 1;
    RIGHT = LEFT + export_dirpath_length - 1;
    export_dirpath = substr(export_list, LEFT, RIGHT);
    LEFT = RIGHT + padsz(len:export_dirpath_length) + 1;
    RIGHT = LEFT + 3;
    groups_value_follows = substr(export_list, LEFT, RIGHT);
    groups = "";
    while(groups_value_follows == VALUE_FOLLOWS) {
      LEFT = RIGHT + 1;
      RIGHT = LEFT + 3;
      groups_length = str2long(val:substr(export_list, LEFT, RIGHT), idx:0);
      LEFT = RIGHT + 1;
      RIGHT = LEFT + groups_length - 1;
      groups = groups + substr(export_list, LEFT, RIGHT);
      LEFT = RIGHT + padsz(len:groups_length) + 1;
      RIGHT = LEFT + 3;
      groups_value_follows = substr(export_list, LEFT, RIGHT);
    }
    LEFT = RIGHT + 1;
    RIGHT = LEFT + 3;
    export_value_follows = substr(export_list, LEFT,RIGHT);
    if(strlen(groups) > 0) {
      insstr(groups, '\0', strlen(groups) - 1);
    } else {
      groups = "empty/none";
    }
    list += export_dirpath + ' ' + groups + '\n';
    set_kb_item(name:"nfs/exportlist", value:export_dirpath);
  }
}

proto = "udp";
if(isnull(list)) {
  report = "The remote host is running a superfluous NFS daemon without any exported shares.";
  security_message(port:RPC_NFSD_port, data:report, proto:proto);
} else {
  report = 'Here is the export list of the host "' + get_host_name() + '":\n\n' + list + '\n' + 'Please check the permissions of these exports ("*" means the share is world readable).';
  security_message(port:RPC_NFSD_port, data:report, proto:proto);
}

exit(0);

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.015 Low

EPSS

Percentile

86.7%

Related for OPENVAS:1361412562310102014