Facebook Google Plus Twitter LinkedIn YouTube RSS Menu Search Resource - BlogResource - WebinarResource - ReportResource - Eventicons_066 icons_067icons_068icons_069icons_070

New Keywords and APIs for UNIX Compliance Checks

Tenable has recently added several new APIs to the UNIX compliance checks. This blog entry discusses the new checks with several examples. These APIs are available to Direct Feed and Security Center users who have recently updated their plugins. Many of these checks will work for any UNIX operating system, however several of them are specific to RedHat Linux and its derivatives such as Fedora. 

New File Based Keywords and APIs

Checking File Attributes

This 'attr' keyword can now be used in conjunction with the FILE_CHECK and FILE_CHECK_NOT APIs to audit the file attributes associated with a file. Here is a short example:

<custom_item>
type : FILE_CHECK
file : "/bin/sh"
md5 : "d4228cff8f00b204e9812998ecf8427e"
description : "make sure the md5 of /bin/sh is correct"
# make sure the file is immutable (linux-only)
attr : 'i'
</item>

For more information about Linux file attributes, please refer to the man page for chattr.

Checking File Masks

The 'mask' keyword is opposite of the 'mode' keyword where one can specify a permission that should NOT be available for a particular user, group or other member.

Example:

mask : 022

This would specify any permission is acceptable for the file owner but no write permissions for group and other.

A mask value of 7 would mean that no permissions for that particular owner, group or other member are acceptable.

Globbing of File Names

File names can now also be globs. For example, file: "/var/log/*" can be used to specify any and all files in the the /var/log directory.

This feature is particularly useful when all the files with in a given directory need to audited for permissions or contents using FILE_CHECK, FILE_CONTENT_CHECK, FILE_CHECK_NOT or FILE_CONTENT_CHECK_NOT audit checks. 

Required Checks

This keyword is used to specify if the audited item is required to be present or not on the remote system. It gives auditors the flexibility to say "if this file is here, then it should be configured like this". It also lets auditors require that a certain file exist.

For example if 'required' is set to ‘NO’ and the check ‘type’ is ‘FILE_CHECK', then the check will pass if the file exists and permissions are as specified in the .audit file or if the file does not exist. On the other hand if 'required' was set to ‘YES’ the above check would fail.

CHKCONFIG

This audit check allows interaction with the 'chkconfig' utility on the remote RedHat system being audited.

This check consists of 5 keywords which are 'type', 'description', 'service', 'levels' and 'status'. All of these keywords must be specified to define a CHKCONFIG check.

This only works on Red Hat systems or a derivative of Red Hat system such as Fedora.

The following example verifies that the xinetd service is disabled in run levels 1 through 6.

<custom_item>
   type:CHKCONFIG
   description:"Make sure that xinetd is disabled"
   service:"xinetd"
   levels:"123456"
   status:OFF
</custom_item>

If xinetd were to be running in levels 1,2,3 and 6, then the example would look like:

<custom_item>
   type:CHKCONFIG
   description:"Make sure that xinetd is disabled"
   service:"xinetd"
   levels:"1236"
   status:OFF
</custom_item>

It should be pointed out that this audit does not check if the actual process is running or not, just if the process is configured to start at boot time or not.

GRAMMAR_CHECK

This audit check examines the contents of a file and matches a loosely defined grammar made up of one or more regular expression statements. If one line in the target file does not match any of the regular expressions, then the test will fail.

For example, in the bottom example .audit segment, if the file /etc/securetty contained the word "tenable" (a string that should not exist in this file) or was missing the word "vc/3", the audit would fail.

<custom_item>
type : GRAMMAR_CHECK
description : " Check /etc/securetty contents are OK."
file : "/etc/securetty"
regex : "console"
regex : "vc/1"
regex : "vc/2"
regex : "vc/3"
regex : "vc/4"
regex : "vc/5"
regex : "vc/6"
regex : "vc/7"
</custom_item>

This format would also be acceptable:

<custom_item>
type : GRAMMAR_CHECK
description : " Check /etc/securetty contents are OK."
file : "/etc/securetty"
regex : "console"
regex : "vc/[0-9]"
</custom_item>

In the latter case, if we knew the exact contents of a file, it would also be possible to perform an MD5 checksum. However, if we wanted to accept ranges of values, using multiple regular expressions offers greater flexibility.

RPM_CHECK

This audit check is used to check the version numbers of installed rpm packages on the remote system.

This check consists of 4 mandatory keywords which are 'type', 'description', 'rpm', 'operator' and the optional keyword 'required'.

The ‘rpm’ keyword is used to specify the package to look for and the ‘operator’ keyword is to specify the condition to pass or fail the check based on the version of the installed rpm package.

The 'operator' keyword accepts one of these four values:

  • lt less than
  • gte greater than or equal to
  • gt grater than
  • eq equal

This keyword only works on RedHat distributions.

Here are some examples, assuming iproute-2.4.7-10 is installed.

<custom_item>
   type : RPM_CHECK
   description : "RPM check for iproute-2.4.7-10 - should pass"
   rpm : "iproute-2.4.7-10"
   operator : "gte"
</custom_item>

<custom_item>
   type : RPM_CHECK
   description : "RPM check for iproute-2.4.7-10 should fail"
   rpm : "iproute-2.4.7-10"
   operator : "lt"
   required : YES
</custom_item>

<custom_item>
   type : RPM_CHECK
   description : "RPM check for iproute-2.4.7-10 should fail"
   rpm : "iproute-2.4.7-10"
   operator : "gt"
   required : NO
</custom_item>

<custom_item>
   type : RPM_CHECK
   description : "RPM check for iproute-2.4.7-10 should pass"
   rpm : "iproute-2.4.7-10"
   operator : "eq"
   required : NO
</custom_item>

<custom_item>
   type : RPM_CHECK
   description : "RPM check for iproute1"
   rpm : "webmin"
   operator : "eq"
   required : YES
</custom_item> 

Please note that although this API could be used to perform vulnerability audits for missing patches, there are already many different Nessus plugin families which perform security patch audits of many different UNIX systems.

XINETD_SVC

The “XINETD_SVC” audit check is used to audit the startup status of xinetd services. The check consists of 4 mandatory keywords which are 'type', 'description', 'service' and 'status'. The 'status' keyword

This check only works on RedHat Linux OSes and their derivatives.

Example Usage:

<custom_item>
type : XINETD_SVC
description : "Make sure that telnet is disabled"
service : "telnet"
status : OFF
</custom_item>

New "Builtin" UNIX Checks

These new APIs have been "built in" to the UNIX compliance checks grammar.

admin_accounts_in_ftpusers

This check audits if all administrator accounts (i.e users with a UID less than 500) are present in /etc/ftpusers.

Example usage:

<item>
name : "admin_accounts_in_ftpusers"
description : "This check makes sure every account whose UID is below 500 is present in /etc/ftpusers"
</item>

dot_in_root_path_variable

This check ensures that the current working directory (‘.’) is not included in the executable path of root user. Ensuring this prevents a malicious user from escalating privileges to superuser by forcing an administrator logged in as root from running a Trojan horse that may be installed in the current working directory.

Example usage:

<item>
name : "dot_in_root_path_variable"
description: "This check makes sure that root's $PATH variable does not contain any relative paths"
</item>

find_orphan_files

This check reports all files that are un-owned on the system.

By default the search is done recursively under the “/” directory which can make this check extremely slow to execute depending on the number of files present on the remote system. However, if needed the default base directory to search for can be changed by using the optional keyword "basedir".

It is also possible to skip certain files within a "basedir" from being searched using the optional keyword "ignore".

The timeout value (i.e the time after which Nessus will stop processing results for this check) is five hours and this value cannot be changed.

Two Examples:

<item>
name : "find_orphan_files"
description : "This check finds all the files which are 'orphaned'"
</item>

<item>
name : "find_orphan_files"
description : "This check finds all the files which are 'orphaned'"
basedir : "/tmp"
ignore : "/tmp/foo"
ignore : "/tmp/bar"
</item>

find_suid_sgid_files

This check reports all files with the set-user-ID (SUID) or set-group-ID (SGID) bit set. These files can be run by less privileged users but are executed with user's of higher privilege.

All files reported by this check should be carefully audited for any security issues especially shell scripts and executables that were not shipped with the system.

SUID and SGID files present the risk of escalating privileges of a normal user to the ones possessed by the owner or the group of the file.

If such files or scripts do need to exist then they should be specially examined to check if they allow creating file with elevated privileges.

Example Usage:

<item>
name : "find_suid_sgid_files"
description : "This check finds all the files which have their SUID or SGID bit set"
</item>

find_world_writeable_directories

This check reports all the directories that are world writeable and also have the sticky bit not set on the remote system.

Ensuring that the sticky bit is set for all world writeable directories ensures that only the owner of file with in a directory can delete the file which prevents any other user from accidentally or intentionally deleting the file.

Two Examples:

<item>
name : "find_world_writeable_directories"
description : "This check finds all the directories which are world writeable and whose sticky bit is not set"
</item>

<item>
name : "find_world_writeable_directories"
description : "This check finds all the directories which are world writeable and whose sticky bit is not set"
basedir : "/tmp"
ignore : "/tmp/foo"
ignore : "/tmp/bar"
</item>

find_world_writeable_files

This check reports all the files that are world writeable on the remote system.

Ideally there should be no world writeable files on the remote system (i.e. the result from this check should nothing). However in some cases depending on organizational needs, there may be a requirement for having world writeable files.

All items returned from this check must be carefully audited and files that don’t necessarily need world writeable attributes should be removed as follows:

chmod o-w world_writeable_file

Two Examples:

<item>
name : "find_world_writeable_files"
description : "This check finds all the files which are world writeable and whose sticky bit is not set"
</item>

<item>
name : "find_world_writeable_files"
description : "This check finds all the files which are world writeable and whose sticky bit is not set"
basedir : "/tmp"
ignore : "/tmp/foo"
ignore : "/tmp/bar"
</item>

writeable_dirs_in_root_path_variable

This check reports all the world and group writeable directories in the root users $PATH variable.

All directories returned by this check should be carefully examined and unnecessary world/group writeable permissions on directories should be removed as follows:

chmod go-w path/to/directory

Example usage:

<item>
name : "writeable_dirs_in_root_path_variable"
description : "This check makes sure that root's $PATH variable does not contain any writeable directory" </item>