Cover V09, I13
Table 1
Figure 1
Figure 2


Implementing C2 Auditing in the Solaris Environment

Kevin Wenchel and Stephen Michaels

The C2 auditing facility provided in Solaris 2.x is often overlooked, despite the added system security that it can provide. In its absence, administrators often rely on application-level audit trails, such as syslog, for their primary source of security audit data. Unfortunately, these audit trails lack much of the security-relevant data that is normally found in a C2 audit trail. In this article, I will discuss C2 auditing and provide instructions and tips for implementing it in the Solaris 2.x environment. I will also present the BSM event Viewer application, which was written by the same authors to simplify Solaris C2 audit trail analysis.

What is C2 Auditing?

The C2 security rating was originally defined in the Trusted Computer System Evaluation Criteria (TCSEC), published by NCSC (National Computer Security Center) in the early eighties. Commonly referred to as the Orange Book because of the report's orange cover, TCSEC set forth to provide criteria for judging the effectiveness of the security controls built into operating systems. It defined four general divisions of security: D (Minimal Protection), C (Discretionary Protection), B (Mandatory Protection), and A (Verified Protection). The complete set of ratings from least to most effective are: D, C1, C2, B1, B2, B3, A1.

Most commercial operating system today are certified at the C2 level, and this is generally regarded as the lowest acceptable level of security. Among other criteria, a C2-compliant system must be able to provide a system-level audit trail. Specifically, C2 systems must be able to audit the use of identification and authentication mechanisms, the introduction of objects into a users address space (such as file opens and program initiation), the deletion of objects, and administrative actions (such as user account administration, mounts, reboots, etc.).

Why Bother with C2 Auditing?

Compared with traditional application-level logging facilities such as syslog, C2 auditing provides much more relevant audit data from the security auditing standpoint. C2 auditing operates at the kernel level, intercepting and logging system calls on the basis of an audit policy. This allows for virtually any action on the system to be audited. In an extreme case, it would be possible to track every action that a user takes on the system. Also, no user process can escape C2 auditing. In contrast, syslog operates in user mode. Applications voluntarily log events through syslog and so the applications themselves decide what events will be logged, if any.

The C2 audit trail can be enormously useful for intrusion detection, reconstruction of events, and problem determination. At our site, we audit all login attempts as well as any attempts by unprivileged users to perform administrative actions, such as mount commands and user administration. Additionally, we audit every action taken under the root account. This is primarily so that in the event of a serious mishap under the root account, we will be able to backtrack and reconstruct what happened. Also, keep in mind that C2 auditing provides the only mechanism for auditing file access in the Solaris environment. This has come in handy more than once for general system debugging.

C2 Auditing under Solaris

Although SunOs has been C2 certified since version 4.1, the implementation of C2 auditing has changed slightly over time. Originally C2 auditing implemented in the base kernel. Beginning in Solaris 2.x, the auditing functionality was moved out of the base kernel and into a loadable kernel module, known as the Solaris Basic Security Module (BSM). BSM has been included as a standard part of Solaris since 2.3.

As you might expect, enabling C2 auditing will incur some performance penalty. When C2 auditing is enabled, additional auditing code will be executed for every system call that is made, even for those system calls that are not being audited. Sun suggests that this processing overhead should be no more than 10% and generally less than 5%. In addition to processing overhead, extra storage space may be required to maintain the audit trail, which can grow quite large depending on the audit policy. In both cases, the overhead costs are generally proportional to the amount of data being collected and can be mitigated by adjusting the audit policy.

Configuration of C2 Auditing

Before attempting to install and configure auditing on your Solaris system, I highly recommend reading the Answer book. Under the heading “SunSHIELD Basic Security Module Guide”, you will find more detailed and descriptive documentation than described in this article.

Installing the Solaris Basic Security Module

To use C2 auditing, you must install and enable the Solaris Basic Security Module (BSM). Verify that the following packages are installed on your system: SUNWcar, SUNWcsr, SUNWcsu, SUNWhea, SUNWman using the pkginfo utility. BSM is not enabled by default, but SUN provides two shell scripts that allow you to easily enable or disable it by running the following commands as root in single-user mode.

/etc/security/bsmconv  - sets up the system \
   to run the BSM after the next reboot
/etc/security/bsmunconv - unconfigures the \
   system for auditing
Note that enabling BSM adds a line to /etc/system that disables the ability to abort the system using the Stop-a keyboard sequence. Just remove the line:

set abort_enable = 0
and reboot the system if you wish to retain the use of the Stop-a keyboard sequence.

Next, verify that the BSM kernel module is loaded and that the auditd is process running:

# modinfo | grep c2audit
 34 600de000   c5ac 186   1  \
   c2audit (C2 system call)

# ps -ef | grep auditd
    root   459     1  0   Jun 27 ?  \
          0:13 /usr/sbin/auditd
Configuring System-Wide and Per-User Audit Policies

Now that BSM has been enabled, you are ready to configure C2 auditing. To do this, you will need to know what can be audited and then decide what you will audit. Solaris keeps an ASCII list of audit events in the file etc/security/audit_event. Each event is defined in the file by a symbolic name, an event number, a set of pre-selection classes, and a short description. Events often directly correspond to underlying system calls.

Common sets of events, such as system calls associated with file read access, are grouped into a single class. Solaris has 18 pre-defined event classes (see Table 1). The short name for the audit class is what is referred to as the audit_flag. You use the audit flag in the auditing configuration files to specify which classes of events to audit. The system-wide audit policy is specified in the etc/security/audit_control file using the audit flags to denote the classes of events that you wish to audit. For example, the line:

enables auditing of login, logout, and administrative actions for all users on the system. The audit flags may be prefixed with a “+” to indicate auditing of successes only or a “-” to indicate recording of failures only. If no prefix is given, then both successes and failures are recorded for that class of events. In the above example, all failures of any type will be recorded.

There are three other lines in the audit_control file that you should be aware of:

dir: /var/audit
The first line (dir:) specifies the root audit directory. This is the directory where the audit trail will be created. Depending on what you are auditing, these files can grow rather large. You may decide that you need to set up a separate disk partition just for the audit trail so that other applications aren't affected if the file system fills up.

The second line (minfree:) specifies the minimum amount of free space that must be present in the file system where the root audit directory resides. If the amount of free space falls below this line, then the auditd daemon invokes the /etc/security/audit_warn script. If you wish to be notified by mail whenever audit_warn is invoked, you should set up an alias called audit_warn in /etc/aliases.

The third line (naflags:) specifies the audit flags that define what classes of events are audited when an action cannot be attributed to a specific user. Non-attributable events would include, for example, logon failures from user ids that do not exist on the system.

Per-User Auditing

For per-user auditing, you must modify /etc/security/audit_user. This file is very similar to the audit_control file, and it allows you to fine tune auditing on a per-user basis. Entries in that file use the format:

username:always-audit-flags:never-audit-flags For example:

enables auditing of the Oracle user account for failed file creates, failed file writes, failed file reads, successful file deletions, and successful file attribute modification attempts.

Also, the ^ prefix can be used in both the audit_user and audit_control file to turn off previously set audit flags. Use ^+ to turn off auditing of successful attempts, ^- to turn off for failed events, and ^ to turn off for both successful and failed attempts. For example, the following line from the audit_control file:

flags:  -all,^-fr
turns on auditing of all failed events except for failed file read attempts.

Be careful when using the all flag because it can generate tons of data and fill up the audit file system pretty fast. If using the all flag, be sure to remember to choose the proper flag prefixes to turn off auditing for events that you really don't care about.

Verifying Configuration with auditconfig

As a final step in getting your system set up for auditing, you should verify your configuration with the auditconfig command. The auditconfig command is a command-line interface to let you get and set kernel audit parameters. You should run it with the -chkconf parameter to check the kernel audit event to class mappings that you have set up. This will report runtime class vs. configured class mask mismatches if there are any. The auditconfig command has many other useful parameters; see the auditconfig man pages for more details.

Managing the Audit Trail Files

Now that you've got auditing up and running, you should understand how audit trails are created. Audit trails are created by the auditd daemon, which is started at boot time by /etc/init.d/audit. auditd collects audit data from the kernel and writes the audit records to log files in the root audit directory. The naming convention used for audit files is as follows:
where the first two timestamps represent the log start and end time.

Without proper management, audit logs will accumulate over time, cluttering the audit root directory and wasting storage space. Every time the audit daemon is stopped and restarted (due to a reboot, for example), a new audit log will be created in the root audit directory. If the machine is not rebooted regularly, then the audit logs will be switched infrequently, resulting in one huge audit log that spans a large period of time and that is difficult to search through. To keep the audit trail manageable, checkpoint the audit log on a daily, or possibly weekly, basis using the audit -n command. This will cause the audit daemon to close its current audit file and create a new one. After performing a checkpoint, you will probably want to copy the old audit file to an archive disk or to a tape. This task can be automated using cron and a simple script like the one listed below:


# checkpoint audit log
/usr/sbin/audit -n

# move any terminated log files to an \
# archive dir

for file in $audit_dir/*[0-9].*[0-9].*
  mv $file $audit_arch_dir
Dumping the Audit Trail

Once BSM auditing is up and running, you will no doubt be anxious to look at the contents of the audit log. Audit records are stored in a special binary format, so it is not possible to dump and search the audit log using standard UNIX utilities. Solaris provides two command-line tools for this purpose: auditreduce and praudit. These two tools are typically used together in a pipeline. The auditreduce command provides a grep-like capability, and it is used for selecting records from the audit log on the basis of criteria such as event class, effective UID, real UID, process ID, etc. Auditreduce outputs the matching audit records in their raw binary form. Piping this output through the praudit utility will produce readable ASCII text. Common filtering parameters used with the auditreduce tool include:

-c Event class
-u Real UID
-a Events occurring after the
specified time
-b Events occurring before the specified time
-e Effective UID
-g Real GID
-f Effective GID

The complete list of auditreduce parameters is lengthy and can be found on the man page. The pipeline below dumps audit records for file read and write failures that occurred under the real UID of wenchkb1 between 10:00 AM and 10:10 AM on June 29:

# auditreduce -c -fr,-fw -u wenchkb1 -a \
   20000629100000 -b 20000629101000 | praudit -s

subject,wenchkb1,wenchkb1,bis,wenchkb1,bis,   \
   22378,22366,24 0
return,failure: No such file or directory,-1
header,103,2,AUE_OPEN_R,,Thu Jun 29 \
   10:02:54 2000, + 417631148 msec

subject,wenchkb1,root,other,root,other,   \
   22456,4158,24 8
return,failure: No such file or directory,-1
header,75,2,AUE_OPEN_WC,,Thu Jun 29 10:10:14 \
   2000, + 912522538 msec
The first audit record shows a failed read on /etc/shadow, and the second event shows a failed write to /.rhosts.

By default, when auditreduce runs it will dump audit records from all of the audit logs present in the root audit directory. To dump the contents of a specific audit log located outside of the root audit directory, you can simply specify the file name on the command line as shown below:

# auditreduce -c -lo  \
  /archive/bsm/200006270600.200006280559.mbsund0| \
   praudit -s
Audit Trail Analysis with BSM Event Viewer

As demonstrated by the previous example, the auditreduce and praudit tools offer a rather primitive solution for C2 audit trail analysis. The numerous auditreduce filter parameters are challenging for the newcomer, and the static text output produced by praudit is cryptic and disappointing at best. Unfortunately, Sun does not provide a GUI-based tool for browsing the BSM audit trail. Anyone who has spent even a small amount of time in the Windows NT environment has probably seen the NT Event Viewer, a GUI tool used for viewing and searching the NT C2 audit trail. Although not perfect, this tool greatly simplifies audit trail analysis in NT. Shortly after we implemented BSM auditing on our Solaris systems, we realized that we needed a similar tool for the Solaris environment. We developed the BSM Event Viewer to satisfy this need.

The BSM Event Viewer is a GUI application written in Perl/Tk and relies on the functionality of the auditreduce and praudit utilities. To use BSM Event Viewer, you need Perl 5.0004 in addition to the Perl Tk800.022 and Tk-MListbox-1.09 modules. These two modules can be obtained from CPAN ( \

To install the BSM Event Viewer:

1. Download the latest BSM Event Viewer source code from the Sys Admin Web site:

2. Create a directory in which to install BSM Event Viewer. cd to that directory and type tar -xf bsmvwr.tar.

3. Run the Perl script.

To start BSM Event Viewer, run bsmvwr.

The first step in using BSM event Viewer is to select which audit logs you want to view. Choose the “Select Log” item from the File menu to do this. By default, BSM Event Viewer will behave like auditreduce, dumping records from all of the audit logs in the root audit directory. If you want to dump specific audit logs residing outside of the root audit directory, click the “Select Individual Files” from the Select Log dialog, and you will then be presented with a file selection dialog box.

After choosing which audit logs you wish to view, you will want to configure event filtering by selecting the “Enable/Edit Filter” item from the View menu. The “Event Filter” dialog box is shown in Figure 1. Through this dialog box you select the criteria for the audit records you want to view. Currently, the event filter supports the most common auditreduce filtering options including the event category, event time, the effective and real UID and GID, and process id. Specific event types can be selected by highlighting items from the Event Classes listbox and clicking the select button. To enable filtering on EUID, RUID, EGID, or RGID, click the button labeled “All Users” or “All Groups” next to the appropriate label and choose from the pop-up list of user or group ids. In Figure 1, for example, we have chosen to dump file read events that occurred under the wenchkb1 account between June 20, 2000 11:30 and June 20, 2000 13:30.

Finally, select the “Dump Log” option from the File menu. Depending on the audit trail size, the dump process may take several minutes. When complete, the audit data will appear in a listbox as shown in Figure 2. Seven columns of data are present: Type, Source, Date/Time, Ruid, Euid, Host, and Details. The audit data can be sorted on any of these columns by clicking on the column header. Also, double-clicking on an individual event will bring up a dialog box showing the event details in a more readable form.

Although system auditing is a commonly neglected practice, its importance in maintaining a secure system cannot be overemphasized. The Solaris C2 auditing can provide administrators with a far more detailed audit trail than any other logging mechanism available under Solaris. Unfortunately, the lack of easy to use tools available for Solaris C2 audit trail analysis can limit its effectiveness. I hope that the BSM Event Viewer can help fill in this gap. If you use Solaris C2 auditing and find the BSM Event Viewer useful, please drop me a line and let me know about it.


Sun Microsystems. 1996. C2 Security Frequently Asked Questions. Sunsolve Online (, infodoc id 14313.

National Computer Security Center. 1985. Trusted Computer Systems Evaluation Criteria. \

About the Author

Kevin Wenchel holds a Masters degree in Computer Science from Johns Hopkins University. He is a systems programmer at the Johns Hopkins University Applied Physics Laboratory. His interests include computer security and operating system internals. Kevin can be reached at:
Stephen Michaels holds a Masters degree in Computer Systems Management from the University of Maryland. He has over 15 years experience with networked computing systems. He is currently a Sr. Systems Programmer, specializing in UNIX, at the Johns Hopkins University Applied Physics Laboratory. Steve can be reached at: