Unix / Linux - Local Users Information : Passwords Never Expire

2015-05-10T00:00:00
ID LOCALUSERS_PWEXPIRY.NASL
Type nessus
Reporter Tenable
Modified 2018-05-16T00:00:00

Description

Using the supplied credentials, Nessus was able to list local users that are enabled and whose passwords never expire.

                                        
                                            #TRUSTED 924e2e51a624cd5d7a6834caca77a9a4ded358d5449d222f3de070599a7bc58b09ab7a111516dd376f7a1a2171799629f1a888506d2dbfbc0056f7b10804a375d7686ec43e87eaf7d7efb095b94b7ef9f3d428654213edfa6881c458670dcbabf5d8f280eb226200ee7be3a93b513e1e20b5c450750b3af13e82bd366991f321d93de1b079658f93bf551f99bf722730e4f7e671f0dac676a915009f4eaaf5b0cfb492af989102e0d75744f6eecc09876309ab4a11220a9e6dfddf1f4896d42d33fd11109c5da9570efa4873ff9ca8badd4554199b9c58e22eca0f33c3b4909bc7664aadeb5167ab563cb918630f85fca9a80f1241757cb3fc602985d24d22ec6c461ef731352702aadc3cc18cb47395faeb64e274bd0bf24b97a7b0d0280c66ca1e6e088583c703dab670dd1c521cb59daaf3ecfebd96bcf3c835b6d21b813bb53929f85da005636ec66956b73ffd0fac17fe7effcbc5bdfd7e5d384f6c0ab5e8d884dc625e7f34662715d925d12ef4e294be890eca37e655d1d260b4c9f3248bb88f2a7ab4fd495a7048af173d6b76e9a039d6049c4fffc2245d0e7a10ea1cea47a75d2827594a268beeceb3b74188e0de00ca3d186b599490f2d061bbc15ed5a53815ea65c9d509287c741459f0d98875840cf1dc37c3316d2b3f550d0b4d4ea76981352812c3b3191befdd6891446c3ce405c5b0b9e3650510b97d3247cf
#
# (C) Tenable Network Security, Inc.
#

include("compat.inc");

if (description)
{
  script_id(83303);
  script_version("1.7");
  script_set_attribute(attribute:"plugin_modification_date", value:"2018/05/16");

  script_osvdb_id(755);

  script_name(english:"Unix / Linux - Local Users Information : Passwords Never Expire");
  script_summary(english:"Lists local users whose passwords never expire.");

  script_set_attribute(attribute:"synopsis", value:
"At least one local user has a password that never expires.");
  script_set_attribute(attribute:"description", value:
"Using the supplied credentials, Nessus was able to list local users
that are enabled and whose passwords never expire.");
  script_set_attribute(attribute:"solution", value:
"Allow or require users to change their passwords regularly.");
  script_set_attribute(attribute:"risk_factor", value:"None");

  script_set_attribute(attribute:"plugin_publication_date", value:"2015/05/10");

  script_set_attribute(attribute:"plugin_type", value:"local");
  script_end_attributes();

  script_category(ACT_GATHER_INFO);
  script_family(english:"Misc.");

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

  script_dependencies("ssh_get_info.nasl");
  script_require_keys("Host/local_checks_enabled");

  exit(0);
}

include("audit.inc");
include("ssh_func.inc");
include("telnet_func.inc");
include("hostlevel_funcs.inc");
include("global_settings.inc");
include("misc_func.inc");
include("data_protection.inc");

if(sshlib::get_support_level() >= sshlib::SSH_LIB_SUPPORTS_COMMANDS)
  enable_ssh_wrappers();
else disable_ssh_wrappers();

if (!get_kb_item("Host/local_checks_enabled")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);

# Do not run against Windows and some Unix-like systems
supported = FALSE;
dist = "";
if (
  get_kb_item("Host/CentOS/release") ||
  get_kb_item("Host/Debian/release") ||
  get_kb_item("Host/Gentoo/release") ||
  get_kb_item("Host/Mandrake/release") ||
  get_kb_item("Host/RedHat/release") ||
  get_kb_item("Host/Slackware/release") ||
  get_kb_item("Host/SuSE/release") ||
  get_kb_item("Host/Ubuntu/release")
)
{
  supported = TRUE;
  dist = "linux";
  field = 5;
}
else if (
  get_kb_item("Host/FreeBSD/release") 
)
{
  supported = TRUE;
  dist = "bsd";
  field = 6;
}

if (!supported) exit(0, "Account expiration checks are not supported on the remote OS at this time.");

# We may support other protocols here
if ( islocalhost() )
{
  if (!defined_func("pread")) exit(1, "'pread()' is not defined.");
  info_t = INFO_LOCAL;
}
else
{
  sock_g = ssh_open_connection();
  if (!sock_g) audit(AUDIT_FN_FAIL, 'ssh_open_connection');
  info_t = INFO_SSH;
}

if (dist == "linux")
  cmd = "cat /etc/shadow";
else
  cmd = "cat /etc/master.passwd";

validfile = FALSE;
noexpiry = make_list();
buf = info_send_cmd(cmd:cmd);
if (info_t == INFO_SSH) ssh_close_connection();
if (buf)
{
  lines = split(buf);
  if (!empty_or_null(lines))
  {
    foreach line (lines)
    {
      acct_fields = split(line, sep:':', keep:FALSE);
      if (max_index(acct_fields) >= 7)
      {
        validfile = TRUE;
        # Skip locked / expired accounts
        if (acct_fields[1] == '*' || acct_fields[1] == '!' || acct_fields[1] == "!!")
          continue;
        if (dist == "bsd" && acct_fields[1] =~ '\\*LOCKED\\*')
          continue;

        if (dist == "linux" && !empty_or_null(acct_fields[7]))
        {
          if (!empty_or_null(acct_fields[6]))
            timetoexpire = int(acct_fields[6]) * 86400;
          else timetoexpire = 0;

          expire_timestamp = int(acct_fields[7]) * 86400 + timetoexpire;
          current_timestamp = unixtime();
          if (expire_timestamp < current_timestamp)
            continue;
        }

        if (empty_or_null(acct_fields[field - 1]) || int(acct_fields[field - 1]) == 99999 || (dist == "bsd" && acct_fields[field - 1] == 0))
          noexpiry = make_list(noexpiry, acct_fields[0]);
      }
    }
  }
}
else
{
  errmsg = ssh_cmd_error();
  if ('Permission denied' >< errmsg)
    exit(1, "The supplied user account does not have sufficient privileges to read the password file.");
  else
    exit(1, errmsg);
}
if (!validfile)
  exit(1, "The password file did not use the expected format.");

if (!empty_or_null(noexpiry))
{
  count = 0;
  foreach user (noexpiry)
  {
    count += 1;
    set_kb_item(name:"SSH/LocalUsers/PwNeverExpires/"+count, value:user);
  }

  if (report_verbosity > 0)
  {
    users = join(noexpiry, sep:'\n  - ');
    users = data_protection::sanitize_user_enum(users:users);
    report =
      '\nNessus found the following unlocked users with passwords that do not expire :' +
      '\n  - ' + users + '\n';
    security_note(port:0, extra:report);
  }
  else security_note(0);
  exit(0);
}
audit(AUDIT_HOST_NOT, 'affected');