Auditing Mac OS X Compliance with the

advertisement
Good evening. This presentation is based on my GIAC GSNA Gold technical paper
entitled “Auditing Mac OS X Compliance with the Center for Internet Security Benchmark
Using Nessus.”
I wrote the paper as the beginning of the compliance checks for a customer that wanted an
automated method to check the compliance of their Mac OS X machines against a baseline.
Their baseline was derived from the Mac OS X v10.5 Benchmark from Center for Internet
Security (CIS, www.ciseurity.org ).
The CIS Benchmark for Mac OS X was released May 2008. It contained Level 1 and
Level 2 items. Implementing Level 1 is the minimum recommendation and should not break
any applications. Level 2 increases the security posture of the machine but could break
applications. In both Level 1 and 2, there are 118 Benchmark items: 66 Level 1 items and 52
Level 2 items. Of those 118 items, there are 51 listed as “Scorable,” indicating that they can be
verified with an automated check. Many of the remain items are listed as manual; in other
words there is no easy way to automate the checking for that item. The Benchmark includes
items which are operational policy issues that can’t be checked on the machines.
Unlike Windows, Mac OS X does not have a “security template” or Group Policy Object
capability. That means checking the compliance of a Mac against the benchmark requires
manually examining the contents of files or other manual checks. The customer could have
used a shell script to check the compliance of their Macs but they were already using Nessus to
do compliance checks on Windows machines and wanted to use the same tool.
When I began writing the compliance checks I wanted to be able to use them on any Mac
so I imposed the constraint that only built-in tools would be used and not require installing any
scripts or tools in the target machines.
1
In this presentation, you will learn how you can check for secure configurations of Mac
OS X (10.5) using Nessus 3 and later. We will learn how the compliance check features of
Nessus are used to check security settings on Mac OS X in addition to using the local security
checks to scan for vulnerabilities. We will will also learn how to customize the compliance
checks for use in your Mac OS X environment. You'll also receive pointers to a detailed list of
compliance checks that everyone using a Mac should know and use.
References:
Center for Internet Security. (2008, May). CIS Level 1 & 2 Benchmark for Mac OS X.
Retrieved November 4, 2008 from Center for Internet Security web site: http://
www.cisecurity.org/bench_macosx.html (registration required)
Tenable Network Security. (2008, August 1). Nessus Compliance Checks – Auditing UNIX and
Windows Device Configurations. Retrieved October 30, 2008, from Tenable Network Security
web site: https://plugins-customers.nessus.org/support-center/nessus_compliance_checks.pdf
Smith, R.D. (2008, November 7). Auditing Mac OS X Compliance with the Center for Internet
Security Benchmark Using Nessus. Retrieved December 31, 2008 from GIAC web site: http://
www.giac.org/certified_professionals/practicals/GSNA/00487.php
2
Nessus started out as an open-source network-based vulnerability scanner. It works solely
by checking for open ports and then analyzing the ports and the service behind each port to
determine if the machine has a vulnerability. Nessus uses a client-server architecture in which
the Nessus daemon conducted the scan against specified targets. The client tells the server
which vulnerabilities to check for by specifying a set of plugins to run along with any
information necessary for the plugins to run. The Nessus plugins told the server how to
conduct the vulnerability checks and the expected results. Once the scan was completed, the
server sent the results to the client.
When Tenable Security introduced Nessus 3, it went from open source to closed source.
Tenable also made several improvements to the capabilities of the Nessus server. The biggest
change was the addition of the capability to do local checks. Now a plugin can tell Nessus to
log in to the remote target machine and conduct various types of checks. In other words,
Nessus can find local client-side vulnerabilities on the machine instead of just network
vulnerabilities. For example, it can find that the machine has a vulnerable version of Adobe
Reader installed.
Tenable Security also made several changes in the licensing of Nessus 3. Currently there
are two type of licenses: HomeFeed and ProfessionalFeed. The HomeFeed license is free and
allows installation and use in a noncommercial environment. The ProfessionalFeed is required
if you use Nessus in a commercial environment or for scanning third parties. You need a
ProfessionalFeed license installed to enable the compliance checks capability.
Compliance checks use .audit files to specify the checks that will be performed on the
target machine and the expected results. Tenable has created Windows and UNIX versions
of .audit files to give the ability to specify unique checks on the different OSs. For example,
you can check registry values and permissions on a Windows machine with Windows .audit
files. We are going to talk exclusively about Unix .audit files for the rest of this talk, although
many of the concepts can be applied to the Windows .audit files as well.
3
The .audit files are XML-like in structure. A simple one line tag, <check_type:"Unix">
specifies that this is a UNIX .audit file and a </check_type> tag closes the file. The rest of
the .audit file specifies the compliance check items.
You can do built-in checks that examine some standard security related parameters on
UNIX machines. For example, looking for accounts with an invalid default shell based on the
list of shells listed in /etc/shells. Some of these built-in check items don’t work on all
versions of UNIX or Linux, for example the min_password_age built-in check is not
supported on Mac OS X targets.
Custom items are usually check parameters that are not standard across the various flavors
of UNIX or Linux or are customized for a particular installation. For the Mac OS X dot-audit
files, the majority of the check items used were command execution and file content checks.
File content checks can look for existence of text in the file or the lack of text depending on
how check is specified. Grammar custom check allows you to use regular expressions to
define the correct grammar or construction of a particular file and then check that file
There are several other types of custom items that are specific for a particular UNIX or
Linux distribution. For example, on RedHat derived systems, you can look at the status of
services using chkconfig command or check the version of a particular installed rpm
package.
Let’s look at some examples of specifying built-in check items.
4
Here are two examples of built in checks. You can tell they are built-in checks since they
start with an <item> tag and end with an </item> tag. The checks are built from keywordvalue pairs. The name keyword is required and specifies the built-in check. The next
keyword, description is also required. One of the requirements for the description
keyword is each check must have a unique description value, but that requirement is handled
by Tenable for the built-in checks.
Each built-in check may require other keyword-value pairs. For example, the
min_password_length requires the value keyword-value pair that specifies the range of
acceptable password lengths. For the account_bad_home_permissions check needs the
mode keyword-value pair set to the acceptable permissions for a user’s home directory.
The severity keyword is one of the optional keyword-value pairs that can be used with any
check. The value set using this keyword modifies the severity of the Nessus finding when the
check fails. The default severity is HIGH. In the account_bad_home_permissions check
example, I have changed the severity to MEDIUM.
One thing to remember when writing the checks, the keyword-value pair must be on a
single line in the .audit file. In the min_password_length example, the description line
has been wrapped onto a second line for display purposes.
These checks are well documented in Tenable’s guide to .audit files so I won’t cover them
in depth. Now let’s look at the custom compliance checks.
5
The first difference between the built-in checks and the custom checks is the tags are
“custom_item” not “item.” Also in most cases, the custom checks need more key-value
pairs to the specify the check.
The system keyword specifies the operating system that the check applies to. To
determine the correct value, run uname on the system. For example on a Mac OS X system, in
a Terminal.app window you would get:
RDS-MacBook-Pro:~ rick$ uname
Darwin
The type keyword tells Nessus which one of the 10 kinds of custom checks to perform.
This example is a FILE_CHECK so the Nessus compliance check plugin will check the file
exists and it matches the specified properties of the file. The properties that can be checked are
owner, group owner, permissions, and the MD5 checksum of the file.
The description keyword is required and the value must be unique just like for built-in
checks. The info keyword-value pairs are optional and are used to add information to the
Nessus finding output. In this example, I’ve included information about the applicable section
of the CIS benchmark. In the rest of the examples only the Benchmarks Section info keywordvalue pairs will be shown.
The file keyword is required and specifies the file to check. You can specify the full path to
the file or you can use the search_locations keyword to tell Nessus the directories to
search for a file with the name specified by the file keyword.
The checks can be specified by using the owner, group, mode, or md5 keyword-value
pairs. In this example the mode keyword is used with a value of 0700. For the mode keyword,
you can specify the mode as either an absolute mode, “0644”, or as a symbolic mode,
“-rw-r--r—”.
Now let’s look at checking the contents of a file.
6
For most UNIX systems, checking the configuration settings usually involves looking for
the correct value in a text-based configuration file. That is exactly what a
FILE_CONTENT_CHECK checks does. It searches the contents of a text file for a match to the
regular expression given in the regex keyword. The check will fail if the file does not exist or
the contents of the file doesn’t match the expected results.
The description keyword is required and the value must be unique just like the built-in
checks. The file keyword specifies the file to examine. You can specify the full path to the
file or you can specify the search_locations keyword to tell Nessus the directories to
search for a file with the name specified by the file keyword.
The regex and the expect keywords tell Nessus what content to look for in the text file
and the correct results. For this example, the regex keyword is set so we are looking for the
line containing “TIMESYNC=” along with the possibility of some other text on either side of it.
To break the regular expression down, we see that the regular expression starts and ends with
the two characters, “.*”. In regular expressions, a “.” means any character and a “*” means the
preceding character can be repeated zero or more times. This gives the possibility of text at
either end of the line. The “$” represents the end of the line. So putting it back together, the
regular expression will match a line with any number of characters before “TIMESYNC=” and
any number of characters after until the end of the line.
The expect keyword is set to the same regular express as the regex keyword except the
desired value is inserted at the correct position. In this example, we want to see if the
TIMESYNC variable in the /etc/hostconfig file is assigned “-YES-” as its value. So the
regular expression for the expect keyword has “-YES-” in place of the “.*$”. For the check to
pass, the line which matched the regex keyword pattern can contain any number of characters
before “TIMESYNC=-YES-” and nothing after.
This type of check doesn’t work for configuration files where the text to check is on
multiple lines or the configuration files aren’t text files. We will need to use command
execution checks for many of the configuration file checks.
7
The command execution compliance checks gives us the capability to use the output of a
command run on the target system to verify the compliance of the target system. The Nessus
compliance check plugin runs the command then verifies the output is correct. On Unix
systems, the Nessus compliance plugin will run the command with sudo using the supplied
sudo credentials unless the nosudo keyword is set to “YES.”
There are limitations on command execution compliance checks that we need to
understand before we look at some examples. The first limitation that you need to understand
is the commands must be as a single line. You can pipe commands together but you have to
end up with one line of output. That is the second limitation of the CMD_EXEC checks. When
the compliance check plugin does the comparison of the command output to the expect
keyword value, it only looks at the first line of the command output.
I used two workarounds.
• The first workaround is the obvious one. You can pipe multiple commands to get the
desired results. This works well if the final command gives one line of output.
• The second workaround is to use Perl one-liners. Perl one-liners allows you to
“compress” multiple lines of text into a single line of output.
You can use a Perl one-liners when the output of the command has multiple lines of
output. Or when you need to examine an XML-base Apple binary property list file (plist)
where the configuration setting information is on multiple lines. You can also use the Perl oneliners to examine the command output when it is too complex to examine with a simple regular
expression.
You can use any scripting language for these checks, like Ruby or python, if you can
create the same functionality on one line in those languages.
Now let’s look at some examples.
8
The first example is a relatively simple command execution check. This example
compliance check verifies that a password is required to be entered to boot the machine. This is
an example of a command that produces multiple lines of output but the data that needs to be
examined is on one line.
For this check the type keyword is set to CMD_EXEC. Again, this type of check requires
that you specify a unique value for the description keyword. The other two required keywords
are cmd and expect. The cmd keyword value is the exact command that needs to be run to get
the expected results.
For this example, the nvram command is used to get or set firmware NVRAM variables.
The “–p” option lists all of the NVRAM variables. The output is piped through grep to search
for the line containing the “security-mode” NVRAM variable. The expected output is the
NVRAM variable name followed by any number of any characters (indicated by the “.*”
combination) and then the desired value of “command.”
For the cmd keyword, you have to put the exact command line inside double-quotes. Any
double quotes or back slashes you need to use in the command line itself you must escape by
with a backslash. We will see this in the complex command execution examples.
9
This example is another simple command execution compliance check. Apple stores some
configuration information in Apple binary property list (plist) files. You have to use the
defaults command line tool to get or set the variables stored in the files. This compliance
check verifies the Mac OS X automatic logon feature has been disabled.
In this example, the defaults command is used to read in the /Library/
Preferences/.GlobalPreferences plist file and print out the value of the
com.apple.userpref.DisableAutoLogin variable.
The expected results is a value of 1, which is the value if the automatic logins are disabled.
If automatic logins are not disabled, the value returned would be 0.
Now let’s look at some complex examples of command execution compliance checks.
10
In this example compliance check, we are checking whether the Apache httpd daemon is
configured to start on boot. The Apache configuration stored in an XML-based Apple property
list (plist) file. These files are text files but the setting name and the corresponding value are
stored on different lines in the text so you can’t use simple FILE_CONTENT checks. The
contents of the plist file for the check on the above are listed below. You can see the
Disabled key and its value, “true” are different lines.
rick$ cat /System/Library/LaunchDaemons/org.apache.httpd.plist <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://
www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<true/>
<key>Label</key>
<string>org.apache.httpd</string>
<key>OnDemand</key>
<false/>
…
</dict>
</plist>
11
To handle these files, you can use Perl one-liners to find the value of the setting and create
the single line of output that can be checked by the Nessus compliance check engine. The Perl
command line options you need to use and understand are:
-0777
Puts Perl in to “file slurp” mode. Perl will read in the entire file as one line
into the input record.
-e
Allows you to define Perl code to be executed by the compiler, that is, create
a one-liner.
-n
Creates an implicit loop. It loops around your -e code so it will read all of
the files given on the command line a line at a time.
-l
Causes Perl to automatically chomp the input record (remove the line feed
and carriage return characters)
This example check is an if-else conditional that looks for the desired key with the correct
value using a regular expression. If it is found, “Disabled” or “Service Enabled” is
printed as output. The compliance check looks for “Disabled” as the output.
This is a good example of escaping double quotes and back slashes in the command line.
(Yes, the Perl code can be written in other ways to do the same check in less space but this way
it is readable by people who aren’t familiar with Perl.)
12
This example is one of the more complex compliance checks I implemented. The CIS
benchmark requires that a banner with organization defined content is set for the OpenSSH
daemon, sshd. This check does two things: checks the /etc/sshd_config file for a banner
being configured and checks the banner file content. To create the configuration check
command, I used two command line tools and two Perl one-liners.
The first step is using grep to find the Banner configuration line in the sshd_config
file.
rick$ grep -E '^Banner' /etc/sshd_config
Banner /etc/motd
Then cut is used to get the banner file name out of the Banner line from the sshd_config
file.
rick$ grep -E '^Banner' /etc/sshd_config | cut -d " " -f2 /etc/motd
The third step, and the first Perl one-liner, uses a system call to list the contents of the banner
file, in this example /etc/motd.
rick$ grep -E '^Banner' /etc/sshd_config | cut -d " " -f2 | \
perl -nle 'system("cat", $_);'
!!Authorized Uses ONLY!!
All activity may be monitored and reported.
13
The last step is to concatenate the contents of the banner file into one line as the output for
the compliance check engine.
rick$ grep -E '^Banner' /etc/sshd_config | cut -d " " -f2 | \
perl -nle 'system("cat", $_);’ | \ perl -0777 -ne 's/\n//g;s/\r//g;print;'
!!Authorized Uses ONLY!!All activity may be monitored
and reported.
The expect keyword is written to match on this value.
NOTE: This is the banner text that I used as an example for my GIAC GSNA technical
paper. This check needs to be customized for your organization’s approved banner text.
14
The first step in configuring the scan policy in Nessus is ensuring the correct plugins are
enabled. On the Plugin Selections tab, enabling the “MacOS X Local Checks” family ensures
Nessus logs in to the target machines to login via OpenSSH to check the configuration of the
machine from the inside. The local security checks are a prerequisite for the compliance
checks. Under the Policy Compliance family, enabling the Unix Compliance Checks enables
the compliance check plugin. Both of these should be enabled by default in a new scan policy.
15
On the Credentials tab, you need to supply ssh credentials for an admin account in order
for the Nessus server to remotely login to the Mac OS X target machines and conduct the local
security checks. You can specify either a username and password or a set of SSH publicprivate keys to login to the remote machines. Nessus prefers root logins to do the checks but
since the root user is disabled by default on Mac OS X, you also need to supply sudo
credentials.
On the Advanced tab, select Unix Compliance from the pull-down menu. Then enter the .audit
files.
NOTE: The instructions above assume you are using NessusClient to connect to a Nessus
server that was registered with a ProfessionalFeed License and has updated plugins.
NOTE: If Nessus fails to conduct the local security checks, verify you have entered the correct
credentials and that Remote Login is enabled and allowed through any firewall. Test by
establishing an ssh connection into the target from the Nessus server using the same
credentials.
NOTE: If you don’t see the Policy Compliance category of plugins, then you probably don’t
have a ProfessionalFeed license. You can also look for the unix_compliance_check.nbin,
compliance_check.nbin, and compliance_check_windows_file_content.nbin files
in the directory where your plugins are stored. These “nbin” files are compiled Nessus plugins
as opposed to the standard Nessus Attack Script Language (NASL) plugins. The complied
plugins contain Tenable Security’s proprietary code.
16
I designed my test setup with the goals of testing each check completely as possible and
also as fast as possible. To do that, I used two targets, one configured to pass the check and one
to fail the check. If possible, I used the default configuration as one of the configurations for
testing. To minimize the number of findings while I was testing, both targets were patched up
to Mac OS X v10.5.5, which was the latest version when I was testing. I created a Nessus
Audit Admin account on both machines.
For hardware, I also needed to check configurations on the PowerPC-based and Intelbased Macs. My two test targets were a MacBook Pro 15 (Intel-based) and a PowerMac G4
867MHz (PowerPC-based). Using the old PowerMac gave me a machine that did not have an
iSight camera and Bluetooth installed. For some configuration checks, the configuration of the
machines was switched to verify that each machine could pass
For Nessus, I used NessusClient 3.2.1 on a MacBook Pro 17, also running Mac OS X
v10.5.5. The Nessus server version 3.2.1 was running on a Dell Latitude D600 running
openSuSE 11.0 Linux. The Nessus server was registered with a ProfessionalFeed license.
For testing new compliance checks, I used a test .audit file containing only one
compliance check. Each compliance check was tested by itself to ensure that the check failed
or passed on the appropriate machine. After running a Nessus scan against the two machines,
the results were filtered for the Plugin ID of the UNIX compliance checks plugin, 21157.
The complex command execution compliance checks required multiple iterations.
Starting out in a Terminal window on one of the targets, the command line with the Perl oneliner is written and tested iteratively until the check worked. The command line testing also
helped determine the value for the expect keyword. Once the one-liner worked on one target,
the compliance check was added to the test .audit file. Then both targets were scanned, the
results checked. Then the Perl one-liner or the expect keyword value would be modified.
The cycle repeated until the check worked correctly on both machines.
17
In this presentation, we covered how to write a number of different types of Nessus compliance
checks. Built-in checks can be used for some benchmark items, but most of the items require a
custom compliance check. We also covered some techniques to check the configuration
settings in a number of different file types with custom compliance checks. And, how to set up
a test environment for testing your own compliance checks.
Overall, Nessus compliance checks work well for checking the security configuration of Mac
OS X machine against the CIS benchmark. Using the techniques in this presentation I was able
to write compliance checks to cover 62 benchmarks items, over half of the total items and
more than the 51 Scorable items. The majority of the checks I implemented, 50 of 62, were
system context items, that is, they check a system wide configuration. The rest were user
context items and the check must be run against the configuration of all user accounts. I
implemented 12 user context items but they only check the configuration of the user account
that Nessus uses to log in. Most of the benchmark items that I couldn’t check completely were
in user context. To access the account configuration files, you need to su to each account. I
couldn’t find a way to check those items without enabling the superuser, or root, account and
providing the root credentials to Nessus.
The complete set of .audit files for checking a Mac OS X system against the CIS Benchmark
are available from my GIAC GSNA technical paper. Email me at rdsmith@mac.com if you
have questions.
18
Download