Friday Jun 09, 2006

FREE Sun Beta Certification Exam for Security Admins


Do you like free stuff? Do you enjoy helping others and sharing your wisdom and experience? Would you like to participate in an effort to help create a Sun certification exam? Do you assess, configure or manage security functions on Solaris 10 systems? If so, read on because we have a great opportunity for you!

If you are an expert security administrator, this is your opportunity to get involved
in the creation of the new Solaris 10 Sun Certified Security Administrator exam!  As 
a beta tester, you officially test the test and will be able to provide Sun with 
valuable comments and technical feedback about the questions. Sun beta exams count
towards official Security Certification!

Recommended prerequisites: 

Twelve months job-role experience administering security in a Solaris Operating System
and previous Solaris OS system and network administration.

If this sounds like fun to you and you would like to participate, then please check out the Solaris 10 Sun Certified Security Administrator beta program page and read all about it. Registration does not officially begin until July 3, 2006, so check out the program, the testing objectives and start getting ready today!

Technorati Tag:

Tuesday Apr 25, 2006

I see you! snoop(1M)'ing in non-global zones!

Dear diary... It has been quite a while since my last posting...

While I have not posted very much to my blog lately, I have been quite busy writing. In fact, since February, the following Sun BluePrints articles have been published:

Today's article talks about how to enable snoop(1M) in a non-global (or local) zone. In Solaris 10 today, the ability to use the snoop(1M) command or any other packet sniffer for that matter is restricted to the global zone. There is no way to snoop traffic from within a zone. Enter the Configurable Privileges for Zones project which integrated into Nevada build 37 and of course is available in OpenSolaris today.

Using this project and a little device manipulation, you can today get snoop working in a non-global zone, and here is how to do it... But first, a few warnings:

WARNING #1: This approach will allow the local zone to see all of the network traffic associated with the device that is added. Unless you use separate network interfaces for the global zone and other non-global zones, this means that following these instructions will allow a zone to see traffic intended for or exchanged with another zone.

WARNING #2: This approach is likely not generally recommended. This is meant only as an illustration of what can be done and may serve as a useful workaround in some environments until a more recommended, secure and supportable solution is available.

With that out of the way, let's give it a try!

First, you must configure your zone to include the net_rawaccess privilege. This is done using a new zonecfg(1M) parameter, limitpriv. In the following example, we will assume that we have previously created and installed a non-global zone, called test. To add the new net_rawaccess privilege, simply use the following command:

# zonecfg -z test
zonecfg:test> set limitpriv=default,net_rawaccess
zonecfg:test> exit
Next, let's boot up the zone and check that the privilege has been successfully added:

# zoneadm -z test boot
# zlogin test
[Connected to zone 'test' pts/5]
Last login: Mon Apr 24 23:49:15 on pts/5
Sun Microsystems Inc.   SunOS 5.11      snv_38  October 2007
# ppriv $$
4547:   -sh
flags = 
        E: basic,contract_event,contract_observer,file_chown,file_chown_self,file_dac_execute,
        I: basic
        P: basic,contract_event,contract_observer,file_chown,file_chown_self,file_dac_execute,
        L: basic,contract_event,contract_observer,file_chown,file_chown_self,file_dac_execute,
Technically speaking what comes next is likely not recommended, but it does work and can help you out in a pinch if you need to get this functionality working in a non-global zone until a more recommended method becomes available.

In order to get snoop working in a non-global zone, you must also introduce the network devices into the zone. The following commands must be executed from the global zone and are representative only (based on my system's configuration). The actual command you should use will vary (based on the actual interface name and the major/minor numbers of the device.

On my system, the network interface name is nge0. My first goal is to determine the major and minor device number associated with the network interface:

# ls -l /dev/nge0
lrwxrwxrwx   1 root     root          38 Apr 21 10:02 /dev/nge0 -> ../devices/pci@0,0/pci108e,5347@a:nge0
# ls -l /devices/pci@0,0/pci108e,5347@a:nge0
crw-rw-rw-   1 root     root      96,  1 Apr 22 10:46 /devices/pci@0,0/pci108e,5347@a:nge0
With this information, we can now create the network device in the non-global zone:
# zonecfg -z test info zonepath
zonepath: /my/zones/test
# cd /my/zones/test/dev
# mknod nge0 c 96 1
# ls -l nge0
crw-r--r--   1 root     root      96,  1 Apr 25 13:00 nge0
All the hard work is now done. With the privilege and device added to the zone, you can now use snoop!

# snoop -d nge0
Using device /dev/nge0 (promiscuous mode) -> test         TCP D=22 S=62991 Syn Seq=2109859625 Len=0 Win=49640 Options=
      test   -> TCP D=62991 S=22 Syn Ack=2109859626 Seq=377273646 Len=0 Win=49640 Options= -> test         TCP D=22 S=62991 Ack=377273647 Seq=2109859626 Len=0 Win=49640
      test   -> TCP D=62991 S=22 Push Ack=2109859626 Seq=377273647 Len=20 Win=49640
Voila! Piece of cake! Just use this tip with caution as you do not inadvertantly want to expose yourself. Peek-a-boo! I'll see you (later!)

Take care,


Technorati Tag:

Wednesday Feb 15, 2006

CIS Solaris 10 Security Benchmark Support

On Tuesday, Sun issued a press release titled, "Sun Announces Plan for Trusted Extensions for Solaris 10, the Most Secure Operating System on the Planet". Hidden somewhat discretely within this release (for reasons not entirely clear to me) was the following:

Support for CIS Benchmark

Sun has also extended support services for Solaris 10 OS deployments that adhere
to the Center for Internet Security (CIS) Benchmark. Named "best benchmarking 
effort" by Information Security Magazine, CIS Benchmarks are developed through 
a global consensus process involving hundreds of security professionals to 
determine best-practice security configurations. The CIS Level-I Benchmark for
the Solaris 10 OS is a compilation of security configuration actions and settings
introduced in March 2005. As a result of a close partnership between Sun and the
members of CIS, Solaris 10 Service Plan customers who now implement the CIS
security recommendations will have Sun support for their resulting configurations.
Complementing Sun's freely available Solaris Security Toolkit, CIS will also
introduce a Scoring Tool for the Solaris 10 OS later this month, giving users a
quick and easy way to evaluate systems and compare their security configuration
against the CIS Benchmark criteria. 

This is actually quite an important announcement!

A number of us have been working with the Center for Internet Security, or CIS, for years in an effort to promote more consistent and complete Solaris security recommendations and to better align their Solaris Security Benchmarks with our recommendations. In fact, the CIS Solaris 10 Security Benchark represents the highest level of collaboration and sharing to date. Together, we were able to develop and publish the updated Benchmark document before the GA of Solaris 10 (last year).

This announcement takes our relationship one step further by ensuring customers who implement the Solaris 10 Security Benchmark from CIS can receive support from Sun (under the Solaris 10 Service Plan). This is the first time that Sun has publically announced support for Solaris security recommendations (other than those documented in the Sun BluePrints program). Certainly this is a natural step that stems from our work over the last few years.

I believe that this is another great example of collaboration between vendors (Sun in this case) and members of academia, industry and government. We have all come together for the sole purpose of developing and sharing recommended security practices. By working together in this fashion, we have been able to generate more complete, consistent and supportable advice that will benefit Solaris users and administrators around the world.

This is participation and sharing in action!

Technorati Tag:

Sunday Feb 12, 2006

Sun Ray @ Home Updates

Well, another year has passed for my little Sun Ray user. In Septmeber, I talked about a few updates that we had done to our Sun Ray environment, and I wanted to mention the latest. In late January, we upgraded the operating system on our x86-based Sun Ray server to Nevada (build 32). No issues to report - gotta love the stability of these builds! We are still running SRSS 3.1 as a preview of the next version is not yet available. Certainly, once it is available, we will give is a try.

My son has been using Firefox (from Blastwave) with plugins for Java and Macromedia Flash and has been happily able to access his favorite sites, listen to sounds, play games and puzzles, etc. He is getting more web-savvy by the day and has even been learning to type using gedit for about six months. In fact, he is coming along quite well. I will have him coding in no time now. ;-)

Technorati Tag:

Saturday Feb 11, 2006

Try it for yourself: Solaris 10 Privilege Debugging

Just this month, Darren Moffat and I have published a Sun BluePrint article and opened a OpenSolaris Security Project on privilege debugging which includes a cool, new tool, called privdebug.

Together these resources can help you quickly and easily determine which privileges are used by any process, service or application. With this information, you can configure SMF to limit the privileges granted to it using the approach described here.

Everything is freely available. So why not give it a try! We would love to hear what you think!

Take care,


Technorati Tag:

Updated Solaris 10 Security TOI

While I am at it, how about an update to the Solaris 10 Technical TOI that I had posted a while back. This new version of the TOI includes support for Solaris 10 Update 1 as well as a bunch of other new additions and examples.

I would love to hear what you think about this new version. Remeber, if you would be interested in having someone from Sun come out and talk to you and your organization on this topic, please let us know. We have been giving this (or similar) Solaris 10 Security deep dive talks to customers for some time now, and there has always been a lot of great interaction, discussion and Q&A. Honestly, they are always a lot of fun.

Take care!


Technorati Tag:

Tuesday Sep 20, 2005

Sun announces Solaris 10 3/05 Entering Common Criteria Evaluation

Good news, good news! Hot off the presses!

 Sun Microsystems, Inc. is pleased to announce that the Solaris 10 3/05 
 Operating System has entered into evaluation for Common Criteria evaluation.
 This announcement demonstrates Sun's commitment and leadership in the field
 of independent security certification of operating systems and acts as a 
 catalyst for many world wide government customers wanting to develop and 
 deploy on Solaris 10.

 Common Criteria evaluation represents and agreed upon standard for independent
 certification of various security claims for IT products. The Protection 
 Profiles and Evaluation Assurance Levels are mutually understood, agreed upon
 and accepted by over 22 different countries around the world as being required
 for deploying technology into sensitive scenarios. An example of a recognition
 body includes the National Information Assurance Program Common Criteria 
 Evaluation and Validation Scheme (NIAP CCEVS) in the United States and the 
 Canadian Common Criteria Evaluation and Certification Scheme (CCS) in Canada.

 Stepping above what is normal for the competition, Solaris 10 will be evaluated
 against the Controlled Access Protection Profile (CAPP) and Role Based Access
 Control Protection Profile (RBACPP) at Evaluation Assurance Level 4+ (EAL 4+).

 The Common Criteria testing is being conducted by CGI Information Systems and
 Management Consultants, Inc. in Ottawa, Ontario, Canada, who also conducted 
 the testing of the Solaris 9 Operating System. Actual time to complete the 
 evaluation is under investigation.

 The Communications Security Establishment (CSE) is the Canadian recognition 
 body that will be accepting the evaluation. Formal notice of the evaluation 
 status of Solaris 10 will be posted on CSE's Web site shortly and is available
 at :

Technorati Tag:

Sunday Aug 28, 2005

Sun Rays and Nevada

By way of an update, over the July break (yes, I know it is nearly September!), I completed the upgrade of my laptop to Nevada (build 18). Add to the mix, Casper's frkit, Darren's netprof, and packages from the good folks supporting Blastwave and my laptop is a force to be reckoned! Since then, Nevada has been my only desktop. It has flawless performed on both wired and wireless networks, at home, at the office and at conferences (being projected), ... you name it.

So, since everything has been going so very well, I decided to expose my family to Nevada ;-)

A few weeks ago, we completed the upgrade of our home Sun Ray environment. My family has moved off of the Ultra 10 (running a pre-release of Solaris 10) to a eMachines PC (Pentium 4) system running Nevada (build 18) and SRSS 3.1. I have to say that the transition was completely painless - the SRSS software installed on the Nevada-based x86 platform with no problem and has since been running flawlessly. Gotta love things that "just work".

Isn't technology grand!

Friday Jul 29, 2005

JASS supports Solaris 10!

Today is the big day! The Solaris Security Toolkit version 4.2 has been released. The biggest change in this new release is with its support of the Solaris 10 OS (global and local zones). You can read all about the changes in this new update in the Release Notes. With this release, you have a fully documented and supported tool for hardening the Solaris 10 OS (as well as previous releases) on both SPARC, Intel and AMD platforms!

Download and try it out today!

Technorati Tag:

Wednesday Jun 15, 2005

Solaris 10 Query Appreciation Day

Occasionally, I look through the referer logs to see how people happen to come across my little patch of cyberspace. It is often very interesting to see what people are actually searching for when they are directed to this blog. Today, I would like to give back to those who have taken the time to visit and look around this site after being directed to it by a search engine. To that end, I will list some of the search queries that were in the referer listing today along with answers to questions or pointers that people can use for more information.

So without further ado...

The first search query reference comes from our friends at Yahoo from someone looking for more information on locked accounts in Solaris.

This topic has been covered previously. There is a little more information that can be found in the Solaris 10 What's New document as well as the passwd(1) manual page as well.

The next query comes from our friends at Google from someone looking for steps on how to disable the telnet service in Solaris 10.

The answer to this is very straightforward:

# svcadm disable telnet

That is all there is to it. Keep in mind that if you do not want the telnet service at all on your system you can also simply remove the SUNWtnetd and SUNWtnetr packages using the command:

# pkgrm SUNWtnetd SUNWtnetr

Further, if you want to simply use TCP Wrappers to control access to telnet in Solaris 10, check out this entry.

Another Google query was looking for information on minimal Solaris 10 configurations. This is a great topic. In Solaris 10, a new software installation cluster called the Reduced Networking Meta Cluster is available and should be leveraged when building minimal configurations. You can read about it here. Further, for a great read check out Eric Boutilier's seven part series on building a UNIX OE platform from scratch.

Well, that's enough for today. I would like to occassionally do more entries like this where we can provide more directed feedback based on what people are actually searching for. While it may be too late in some cases for them, it may help people down the road who have similar questions or concerns.

I am off to finalize a presentation on Solaris recommended practices for the NY State Cyber Security Conference. If you will be at the conference tomorrow, please drop by and say hello!

Take care!

Technorati Tag:

Tuesday Jun 14, 2005

Privilege Enabling Set-ID Programs: Part 2

Previously, we talked about how the ping program was modified in Solaris 10 to be privilege aware.  During that discussion, it was noted that the functions used in the ping program were private to the OpenSolaris ON (OS and Networking) consolidation.  While this is fine for programs like ping that reside in that consolidation, it does not offer a solution to programs in other consolidations or for those developed external to OpenSolaris.  As a companion to that article, let's now discuss how we can adapt ping.c to use the public privilege manipulation functions yet still accomplish the same result - making the program privilege-aware and implementing bracketing around privileged operations.

Without further ado, let's just dive into the code.  By way of convention, I will be showing only the changes that need be implemented to covert the original ping.c program to use the new public functions.

The first thing that you will notice is that a different header file is used.  If you want to use the public interfaces, then you should be sure to include priv.h and not priv_utils.h:

< #include <priv_utils.h>
> #include <priv.h>

Next, we move to the section of the code that configured the privilege sets at the start of the program.  This was done in order to drop any privileges that were not needed and disable those that were left (and not needed right now).  This was originally accomplished using the __init_suid_priv function which provided a convenient wrapper for the functionality described below.  Rather than a single line, we need to do a little more work.  To make the code easier to follow, a new function, setup_privs, was created to do the initial privilege operations.  This handles the majority of the work originally done by __init_suid_priv.  This code is fairly well documented, so I will not go into too much detail as to what it does.

> static priv_set_t \*setup_privs(void);
>  \* setup_privs()
>  \*/
> priv_set_t \*
> setup_privs(void)
> {
>     priv_set_t \*pPrivSet = NULL;
>     priv_set_t \*lPrivSet = NULL;
>     /\*
>      \* Start with the 'basic' privilege set and then remove any
>      \* of the 'basic' privileges that will not be needed by this
>      \* process.  The 'net_icmpaccess' privilege will be added
>      \* since we know that we will need it for the permitted set.
>      \*/
>     if ((pPrivSet = priv_str_to_set("basic", ",", NULL)) == NULL) {
>             perror("priv_str_to_set");
>             return (NULL);
>     }
>     /\*
>      \* Let's clear all of the privileges we know we will not
>      \* need from the 'basic' set.
>      \*/
>     (void) priv_delset(pPrivSet, PRIV_FILE_LINK_ANY);
>     (void) priv_delset(pPrivSet, PRIV_PROC_EXEC);
>     (void) priv_delset(pPrivSet, PRIV_PROC_FORK);
>     (void) priv_delset(pPrivSet, PRIV_PROC_INFO);
>     (void) priv_delset(pPrivSet, PRIV_PROC_SESSION);
>     /\* Next add the known required privilege, 'net_icmpaccess' \*/
>     (void) priv_addset(pPrivSet, PRIV_NET_ICMPACCESS);
>     /\* Set the permitted privilege set. \*/
>     if (setppriv(PRIV_SET, PRIV_PERMITTED, pPrivSet) != 0) {
>             perror("setppriv(PRIV_SET, PRIV_PERMITTED)");
>             return (NULL);
>     }
>     /\* Ensure that the 'net_icmpaccess' privilege is off by default. \*/
>             NULL) != 0) {
>             perror("priv_set(PRIV_OFF, PRIV_EFFECTIVE)");
>             return (NULL);
>     }
>     /\* Clear the limit set. \*/
>     if ((lPrivSet = priv_allocset()) == NULL) {
>             perror("priv_allocset");
>             return (NULL);
>     }
>     priv_emptyset(lPrivSet);
>     if (setppriv(PRIV_SET, PRIV_LIMIT, lPrivSet) != 0) {
>             perror("setppriv(PRIV_SET, PRIV_LIMIT)");
>             return (NULL);
>     }
>     priv_freeset(lPrivSet);
>     return (pPrivSet);
> }
> /\*

So, why do we go through the process of starting with the basic set of privileges and removing them all?  Why not just start out with no privileges and simply the code?  The answer lies in the fact that the basic privilege set is not intended to be static.  Over time additional non-administrative privileges may be added.  If you started with simply no privileges, then you may find that your code will fail as it will need a privilege for an operation that previously did not require one.  In essence, this is a way of future-proofing your code so that it can better adapt to changes in Solaris down the road.

So at this point, we have defined a function that will help minic most of the behavior that had been done by __init_suid_priv.  Let's take a look at how this function is used:

>     priv_set_t \*privSet = NULL;
<     (void) __init_suid_priv(PU_CLEARLIMITSET, PRIV_NET_ICMPACCESS,
<         (char \*)NULL);
>     if ((privSet = setup_privs()) == NULL) {
>             exit(EXIT_FAILURE);
>     }
>     /\*
>      \* Reset the real and effective UIDs for this process.
>      \*/
>     if (setreuid(getuid(), getuid()) != 0) {
>             perror("setreuid");
>             exit(EXIT_FAILURE);
>     }

As you can see, the __init_suid_priv call has been replaced by calls to both setup_privs and setreuid(2) functions.  This is a fairly simple replacement since all of the "hard work" was done in the setup_privs function.  We capture the privilege set parameter, privSet, as we will need it later in the code when it comes time to relinquish our privileges.  Let's continue sequentially down the code to see where other replacements are needed.  Frankly, the hard part is over.  The rest of the changes needed to complete the conversion from private to public privilege manipulation functions are trivial.  Let's take a look at the next replacement:

<     __priv_relinquish();
>     /\*
>      \* Clear the permitted set of the 'net_icmpaccess' privilege.
>      \*/
>     (void) priv_delset(privSet, PRIV_NET_ICMPACCESS);
>     if (setppriv(PRIV_SET, PRIV_PERMITTED, privSet) != 0) {
>             perror("setppriv(PRIV_PERMITTED)");
>             exit(EXIT_FAILURE);
>     }
>     priv_freeset(privSet);

In this case, we are replacing the __priv_relinquish function with a call to setppriv(2).  Before we can do this however, we need to remove the net_icmpaccess privilege from privSet using the priv_delset function.  Remember that privSet (returned to us from setup_privs earlier in the code) contains the privileges from the basic set that we had not already dropped as well as the net_icmpaccess privilege.  By removing the net_icmpaccess privilege, setppriv will set to the process' permitted privilege set to the non-dropped basic privileges (which in this particular case is none although as Solaris continues to evolve and new non-administrative privileges are added, this may change).

Moving along to the next section of replacement code, we come to where the bracketing of the net_icmpaccess privilege is enforced.  In thiscase, the call to __priv_bracket is replaced with a call to priv_set(3C) function.  priv_set is called with the PRIV_ON parameter which enables the net_icmpaccess privilege for the process' effective privilege set.

<     (void) __priv_bracket(PRIV_ON);
>             perror("priv_set(PRIV_ON, PRIV_EFFECTIVE)");
>             exit(EXIT_FAILURE);
>     }

Similarly, the companion instance of __priv_bracket is replaced with another call to priv_set once the privileged operations are complete to remove the net_icmpaccess privilege (from the process' effective privilege set) - therefore completing the bracketing of privilege.

<     (void) __priv_bracket(PRIV_OFF);
>             NULL) != 0) {
>             perror("priv_set(PRIV_OFF, PRIV_EFFECTIVE)");
>             exit(EXIT_FAILURE);
>     }

That is all there is to it.  As you can tell, there is a bit more work in the initial setup of a process' privilege sets, but once that is complete, the use of the public privilege manipulation functions is straightforward.  I know that this helps to illustrate how you can privilege enable your code whether you choose to use ON specific functions or the public ones defined in the Solaris product documentation.  For those who just can't get enough, check out Joep Vesseur's discussion of several developer-focused security enhancements in Solaris 10 (and OpenSolaris).

Last, but certainly not least, I would like to offer my sincere thanks to Casper, Joep and Darren for their help with this article.  You guys are the best!

Take care and have fun!

Technorati Tag:

Privilege Enabling Set-ID Programs

There have been quite a few posts, articles,and resources made available discussing the new process privilege model introduced the Solaris 10 operating system. The majority of them have focused on describing what this new privilege model is, why it is useful and how it can be used through mechanisms such as Solaris RBAC, SMF, and ppriv(1). Today, with the launch of OpenSolaris, I feel the urge to discuss privileges from the view of a software developer (not that I am one anymore, but please indulge me a bit).  If you are interested in this kind of thing, you can find more information about this in the Solaris 10 product documentation.

Today, let's look at a how a developer could develop a program to be privilege aware. In particular, for our example, let's take a set-id program and configure it such that it:

  1. drops any privileges that it will never need;
  2. enables the remaining privileges exactly when it needs them;
  3. relinquishes the use of privileges when they are no longer needed

Sounds pretty straight forward, right? Essentially, we just want to ensure that a program is only running with those privileges that it needs, and it activates those privileges only when it needs them. To illustrate this concept, let's take a look at ping.c. This program was converted to use Solaris privileges by Casper Dik way back in 2003. I chose to use it for this example because:

  1. the ping(1M) source code is simple and straightforward to read and understand, and
  2. all of the changes needed to make it privilege aware were contained in one file

There is nothing special about ping with respect to privileges and the same techniques described below could be applied to other programs whether they are set-id or not.

So, let's begin this tale back in February of 2003 before the ping command was made privilege aware. In those days, ping was a set-uid root program that controlled its use of privilege using seteuid(2). When the program started as root, it quickly set its effective UID to the UID of the calling user to run with less privilege. When it came time to execute a privileged operation, the code issued another seteuid call that reset its EUID to root so that the privileged operation could succeed.

With the introduction of process privileges in Solaris 10, this model was no longer needed. Rather than executing code as EUID 0, specific privileges are used to define the types of privileged operations that are be permitted. This is a huge step forward as privilege aware programs will now run only with the privileges that they need (exactly when they need them). So, enough of the fluff, let's get to the code! Note that all of the following code examples were taken from ping.c.

The first thing that you will notice that if you want to configure a program to be privilege aware, you will need to include a new header that will declare functions and define constants used by the privilege functions described below:

     72    #include <priv_utils.h>

With the header out of the way, we move into main where the first thing that we do is drop all of the privileges that we do not need:

    247         /\*
    248          \* This program needs the net_icmpaccess privileges.  We'll fail
    249          \* on the socket call and report the error there when we have
    250          \* insufficient privileges.
    251          \*/
    252         (void) __init_suid_priv(PU_CLEARLIMITSET, PRIV_NET_ICMPACCESS,
    253             (char \*)NULL);

Remember that ping is still set-uid root. This means that when it is started, it will have the privileges that have been assigned to root which by default is all. The purpose of the __init_suid_priv function is to do the following (described in priv_utils.h):

     48 /\*
     49  \* Should be run at the start of a set-uid root program;
     50  \* if the effective uid == 0 and the real uid != 0,
     51  \* the specified privileges X are assigned as follows:
     52  \*
     53  \* P = I + X + B (B added insofar allowable from L)
     54  \* E = I
     55  \* (i.e., the requested privileges are dormant, not active)
     56  \* Then resets all uids to the invoking uid; no-op if euid == uid == 0.
     57  \*
     59  \*
     60  \* Caches the required privileges for use by __priv_bracket().
     61  \*
     62  \*/

So this function (as used in the ping.c code) will reset the real and effective UID of the process to that of the calling user so that it is no longer running as root.  Further, it will clear the limit set of the process which means that any children spawned by this process will themselves have no privileges.  Lastly, this function will also add the net_icmpaccess privilege to the process' permitted set so that it can be enabled and used when necessary.  The process' four privilege sets (effective, inheritable, permitted and limit) will look like this:

# ppriv -S `pgrep ping`
14527: ping localhost
flags = PRIV_AWARE
E: basic
I: basic
P: basic,net_icmpaccess
L: none

According to ppriv, the net_icmpaccess privilege is used to allow a process to send and receive ICMP packets:

$ ppriv -lv net_icmpaccess
Allows a process to send and receive ICMP packets.

So rather than having the potential to access all of root's power, a ping process will now run as the calling user's UID with a single (non-basic) privilege that allows the sending or receiving ICMP packets.  Sounds great, but we are not done yet!  In priv_utils.h, you will find more instruction as to how to proceed:

     65 /\*
     66  \* After calling __init_suid_priv we can __priv_bracket(PRIV_ON) and
     67  \* __priv_bracket(PRIV_OFF) and __priv_relinquish to get rid of the
     68  \* privileges forever.
     69  \*/

Recall that before ping was made privilege aware, it used seteuid to control when its privileges were in effect. This was necessary for the program to only run in a privileged capacity when it needs to execute privileged operations. In the new model, the process leverages a capability called privilege bracketing which controls when a privilege (defined in the process' permitted set) is made effective. To see this capability in action, take a look at the following code which appears in the setup_socket function:

   1196         /\* now we need the net_icmpaccess privilege \*/
   1197         (void) __priv_bracket(PRIV_ON);
   1199         recv_sock = socket(family, SOCK_RAW,
   1200             (family == AF_INET) ? IPPROTO_ICMP : IPPROTO_ICMPV6);
   1202         if (recv_sock < 0) {
   1203                 Fprintf(stderr, "%s: socket %s\\n", progname, strerror(errno));
   1204                 exit(EXIT_FAILURE);
   1205         }
   1207         /\* revert to non-privileged user after opening sockets \*/
   1208         (void) __priv_bracket(PRIV_OFF);

As you can see, the __priv_bracket function is used around the privileged operation (in this case the socket(2) call) to control whether or not the instructions are executed with privilege. This is one form of privilege bracketing that enables and disables all of the privileges cached by the __init_suid_priv function called earlier in the program (and described above). There are other privilege manipulation functions available to allow more fine grained control if needed.

Our final step is to relinquish the privileges when we are sure that we will no longer need them:

    602         __priv_relinquish();

The __priv_relinquish function is called after the setup_socket function has completed in main. Since the program will no longer need the net_raw_icmpaccess privilege (the only non-basic privilege available to the process), it can now be safely dropped. The __priv_relinquish function is used for just this purpose. Note that once a privilege is relinquished, it is gone. If you think that you may need the privilege later in the program, you should simply disable its use (removing it from the process' effective set) until you need it again.

That's all there is to it.  Pretty cool, eh?

One thing that I should mention, however.  In the development of this article, I was reminded by Darren Moffat that the privilege functions and header file described above are private to Solaris (and more specifically the ON [OS and Networking] consolidation).  So, the approach described above will work just fine if you are modifying set-id programs in ON such as atq, atrm, traceroute, lpstat, and the like.  If you want to make other programs privilege aware, you can do this using a set of privilege manipulation functions described in the Solaris 10 product documentation. Regardless of the method you use, however, there should be nothing to stop you from improving your code by making your programs privilege aware and bracketing privileged operations.

Take care and have fun!

Technorati Tag:

Tuesday May 31, 2005

Automating security enforcement and audit with N1 SPS

I noticed over the weekend that Sun's N1 Service Provisioning System (SPS) was featured on The title of the feature was Accelerate Deployment from Days to Minutes. This feature reminded me that I had been wanting to talk about a proof of concept that Dave Walker, Peter Charpentier, and I did with SPS and the Solaris Security Toolkit (aka JASS). So, I guess now is as good a time as any!

For those who may not know, the Solaris Security Toolkit is an officially supported Sun product that can be used to improve the security of Solaris systems running Solaris 2.5.1 through 9 (with support for Solaris 10 on the way). The Toolkit supports SPARC, Intel and AMD platforms as well as Trusted Solaris 8. The Toolkit also supports three modes of operation: hardening (apply), undo, and audit. Lastly, the Toolkit can be used to create a security profile (based on your own security policies and standards) that can then be (re-)applied to systems. You can even use the Toolkit to assess a system against a known profile to determine its degree of compliance.

So what does this have to do with SPS? Well, for sites with tens, hundreds or even thousands of systems, keeping them secure and validating that they are all in compliance with their expected security profiles can be a daunting process. Rather than individually securing (or validating) each system, you can use SPS to do it all for you at the click of a button!

Whether you have a single security profile or many, you can still use SPS to automatically harden your systems (at installation/provisioning time) as well as later in their lifecycle (perhaps after patch or application installation) - all from a centralized management platform. Auditing is made easy as well since you can evaluate all of your systems against the same (or different) profile almost simultaneously. You can even use the SPS command line interface for this functionality so that you can include pre- or post-process the output so that you can automatically create reports from the results. Given that the Solaris Security Toolkit supports 5 levels of verbosity, you can select the one that most fits your needs.

For example, often for large sites, you may want to select a low level of verbosity such as "level 0" which will simply report whether an entire audit run passed or failed (along with a number indicating the failure count).  For example, something like:

# ./jass-execute -a hardening.driver -V 0
hardening.driver               [FAIL] Grand Total: 6 Errors

For assessment runs that result in at least one failure, you could have SPS automatically re-run the report on that system using a higher level of verbosity to see exactly what the failures were.  For example, you could get information like this:

# env JASS_LOG_SUCCESS=0 JASS_LOG_NOTICE=0 ./jass-execute -a hardening.driver -V 2
disable-dmi                    [FAIL] Service lrc:/etc/rc3_d/S77dmi was installed.
disable-dmi                    [FAIL] Process /usr/lib/dmi/dmispd:430:root was found.
disable-dmi                    [FAIL] Process /usr/lib/dmi/dmispd:1240:root was found.
disable-dmi                    [FAIL] Process /usr/lib/dmi/dmispd:1135:root was found.
disable-dmi                    [FAIL] Process /usr/lib/dmi/snmpXdmid:433:root was found.
disable-dmi                    [FAIL] Process /usr/lib/dmi/snmpXdmid:1141:root was found.
disable-dmi                    [FAIL] Script Total: 6 Errors
hardening.driver               [FAIL] Driver Total: 6 Errors
hardening.driver               [FAIL] Grand Total: 6 Errors

This helps reduce the amount of information that an analyst would need to sift through in order to diagnose and fix problems.  In this case, the fix could be to simply ensure that the disable-dmi.fin Finish script was in the security profile of the system before running the Toolkit in hardening (apply) mode.  Further, once the fix was completed, you could use SPS to reassess the system to verify that the fix was correctly implemented (by just using the Toolkit again in audit mode).

You can even use SPS to upgrade the Toolkit software or add, remove or modify security profiles used by the Toolkit. The number of ways you can use SPS is really bounded by your imagination. In addition to the Solaris Security Toolkit, you could use SPS to automate the installation, configuration and use of other security controls like the Basic Auditing and Reporting Toolkit (BART) found in Solaris 10.

If this is a topic of interest to you, please let me know. If we get enough replies then perhaps we will do a more detailed "how-to" article describing how all of this works and could be deployed in an actual data center environment.

Technorati Tag:

Wednesday Apr 20, 2005

Enforcing a Two Man Rule Using Solaris 10 RBAC

The "two man rule" (also sometimes called the "four eyes rule") has its origins in military protocol although for quite some time it has been welcomed into the stockpile of IT security controls used by organizations around the world. The "two man rule" specifies that there must be two individuals that must act in concert in order to perform some action. Further, each individual should have comparable knowledge and skill in order to detect attempts of subversion initiated by the other. One can certainly see why this is essential for tasks such as safeguarding a country's nuclear arsenal. One would not want all of that authority to rest in the hands of one individual.

The "two man rule" is also useful for IT security. Whether you are talking about physical or logical access controls, the "two man rule" has been applied to help secure IT assets for quite some time. Whether you want to protect access to key data sets or restrict who may perform sensitive or high impact operations on a system, using the "two man rule" may be an option. That said, in many circumstances, more traditional IT security controls are likely appropriate. Using the "two man rule" is most often reserved for restricting the most sensitive IT security operations performed within an organization. Whether and where you could apply the "two man rule" to your organization will depend on your policy, architecture, processes and requirements.

Let's assume that you are interested in applying the "two man rule" on a given system. For our example, we will focus on implementing the "two man rule" on the Solaris 10 operating system. It should be noted that the same techniques apply to both Solaris 8 and 9 since all three versions of the operating system included the Solaris Role-based Access Control ("RBAC") facility. We will make use of this facility to implement the "two man rule" as described above.

The content and examples below will include references to both normal users and roles. In the Solaris OS, roles are similar to normal user accounts with two important differences. First, a role cannot be accessed directly over the network or from the console. You can only use the su(1M) command (or smc(1M)) to assume a role. In either case, a user must first authenticate to the system as himself before attempting to access a role. Secondly, a role can only be assumed by authorized users. That is, before a given user can assume a role, an administrator must assign that role to the user otherwise attempts to access the role will fail. Both of these restrictions are important for preserving accountability and will factor quite heavily in our implementation of the two man rule in Solaris 10.

So let's begin. For our example, we will implement the "two man rule" for our hypothetical IT security administrators, joe and john. From here, there are several ways that we can go:

  • Configure both joe and john with normal accounts on the system, each able to assume an individual Solaris role. Neither joe nor john will know the password for the role that they are permitted to assume. For example, joe is permitted to assume the role roleA but is unable to do so since only john knows the password for that role. This option creates two roles (one for each user) each able to perform a restricted operation. This approach has the benefit of either user being able to assume the role (i.e., it does not require that one user be the initiator of the action). Further by permitting both users to be on the system they have more opportunity to monitor the actions of the other (e.g., Solaris auditing, syslog, etc.).

  • Configure only one user on the system with permission to assume one role. In this example, one user would know the initial password while the other user would know the second (i.e., role) password. This case is similar to the first although it only requires one user and one role account on the system. It suffers from the disadvantage of not permitting the second user to log directly into the system thereby potentially missing critical monitoring opportunities. Further, it requires that joe must be first logged into the system before john can assume roleA.

  • Configure both joe and john as in example one but only give them access to the same shared role. In this case, neither user would have the password to authenticate to that role. In order to obtain the authenticator for that role, both users would be required to work together to obtain the password from an external source such as a physical safe. This option has the benefit of greater protection since access to the safe could be placed in an area that requires additional physical controls and provides greater opportunities for monitoring. Further, the authenticator could be monitored and changed by a third party who has no relationship to either joe or john. This approach also preserves the benefits of the first approach where both joe and john can easily monitor the activities of the other.

For our example, I will choose the first option. This option will allow me to showcase the capabilities of Solaris RBAC to implement the "two man rule" without depending on external factors such as those described in the third option above. The actual choice that you make will depend on your policy and requirements. Additional security controls (physical and logical) beyond those described in this article may also be required depending on the level of assurance that you need for your situation.

First, let's verify our users - joe and john:

# getent passwd joe john

You will note that these users have been configured with profile shells. This is only done to simplify some of the commands that follow. If you did want want to use a profile shell, you could prefix your commands with pfexec(1) when you wanted them to be evaluated by Solaris RBAC to run with privilege.

We can verify that these account do not have any special privileges (beyond those available to any regular Solaris user) by running the following commands:

# roles joe john
joe : No roles
john : No roles

# profiles -l joe john



# auths joe john
joe : solaris.device.cdrw,,,solaris.mail.mailq,,,,,,
john : solaris.device.cdrw,,,solaris.mail.mailq,,,,,,

As you can see, neither joe nor john have been granted access to any roles, rights profiles or authorizations (beyond those available to any normal Solaris user). You will notice several authorizations that are available to them. They have been granted by default using the AUTHS_GRANTED and PROFS_GRANTED parameters in the /etc/security/policy.conf file.

To each of these users we will grant the rights profile Audit Review. This will allow both joe and john to review Solaris audit records so that each can monitor the activities of the other. This step is not necessary for the "two man rule" if you have an external third party who is able to monitor the activities of the two users.

# usermod -P "Audit Review" joe
# usermod -P "Audit Review" john

Let's verify that this change has taken effect:

# profiles -l joe john

      Audit Review:
          /usr/sbin/praudit    euid=0
          /usr/sbin/auditreduce    euid=0
          /usr/sbin/auditstat    euid=0

      Audit Review:
          /usr/sbin/praudit    euid=0
          /usr/sbin/auditreduce    euid=0
          /usr/sbin/auditstat    euid=0

Now that we have verified the accounts have been configured as expected, we will create two roles: roleA and roleB. roleA will be assigned to joe, and roleB will be assigned to john. To these roles, our restricted operations will be assigned.

# roleadd -d /export/home/roleA -m roleA
64 blocks

# passwd roleA
New Password:
Re-enter new Password:
passwd: password successfully changed for roleA

# roleadd -d /export/home/roleB -m roleB
64 blocks

# passwd roleB
New Password:
Re-enter new Password:
passwd: password successfully changed for roleB

# usermod -R roleA joe
# usermod -R roleB john
Now, let's verify that the roles have been created and assigned as we expected:

# getent passwd roleA roleB

# roles joe john
joe : roleA
john : roleB

Great. Our last step is to assign the restricted operations to the roles so that joe and john can perform them after they have jointly assumed either roleA or roleB. For our example, we will assign the Crypto Management rights profile to both roleA and roleB. This will allow either of those roles to execute cryptographic administration functions such as those provided by cryptoadm(1M):

# rolemod -P "Crypto Management" roleA
# rolemod -P "Crypto Management" roleB

To see what privileged commands are now available to these roles, use the following command:

# profiles -l roleA roleB

      Crypto Management:
          /usr/sbin/cryptoadm    euid=0
          /usr/sfw/bin/    euid=0
          /usr/sfw/bin/openssl    euid=0

      Crypto Management:
          /usr/sbin/cryptoadm    euid=0
          /usr/sfw/bin/    euid=0
          /usr/sfw/bin/openssl    euid=0

Great! We are all set. At this point, we have two users (joe and john). joe is permitted to assume roleA, and john is permitted to assume roleB. joe does not know the password for roleA (although john does), and similarly john does not know the password for roleB (although joe does). Both of the users have been assigned the Audit Review rights profile allowing them to monitor each other's activities. Both of the roles have been assigned the Crypto Management rights profile allowing them to perform cryptographic management operations on the system.

Let's verify that this all actually works... For my example, all of the users and roles were created within a zone called "blue". The first thing that I will do to test is log into the zone as joe:

# zlogin -l joe blue
[Connected to zone 'blue' pts/2]
Last login: Tue Apr 12 07:20:19 on pts/2
joe$ id -a
uid=105(joe) gid=1(other) groups=1(other)
joe$ auths,solaris.device.cdrw,,,solaris.mail.mailq,,,,,,solaris.admin.procmgr.user,,,,,,,,,
joe$ profiles -l

      Audit Review:
          /usr/sbin/praudit    euid=0
          /usr/sbin/auditreduce    euid=0
          /usr/sbin/auditstat    euid=0
joe$ roles

First, since joe does know the password for roleB, let's see if we can assume that role:

joe$ su roleB
Roles can only be assumed by authorized users
su: Sorry

Even with a valid password, joe is not permitted to assume roleB. Next, let's try to guess the password for roleA:

joe$ su roleA
su: Sorry
joe$ su roleA
su: Sorry
joe$ su roleA
su: Sorry

No luck. In order to prevent brute force password attempts, you could also configure account lockout so that an account will be administratively locked after n consecutive failed authentication attempts, where n is the value defined by the RETRIES parameter in /etc/default/login.

Next, let's see what user john would see in the audit trails after joe executed the above commands. Since john has been granted the Audit Review rights profile, he is able to look at the Solaris audit records. If you wanted to further limit what john could see in the audit trail, you could develop a small wrapper script to call praudit(1M) and auditreduce(1M) to filter out unwanted records. So, let's pick up our example with john logging into the "blue" zone:

# zlogin -l john blue
[Connected to zone 'blue' pts/2]
john$ id -a
uid=106(john) gid=1(other) groups=1(other)
john$ auths,solaris.device.cdrw,,,solaris.mail.mailq,,,,,,solaris.admin.procmgr.user,,,,,,,,,
john$ profiles -l

      Audit Review:
          /usr/sbin/praudit    euid=0
          /usr/sbin/auditreduce    euid=0
          /usr/sbin/auditstat    euid=0
john$ roles

Next, john uses the praudit and auditreduce commands to look at any attmepts to su taken by joe:

john$ auditreduce -m AUE_su -r joe | praudit -s
file,2005-04-12 07:25:06.000 -04:00,
header,97,2,AUE_su,,,2005-04-12 07:28:30.220 -04:00
subject,gmb,root,other,joe,other,1834,3097759606,12114 22
text,bad auth. for user roleB
header,97,2,AUE_su,,,2005-04-12 07:28:40.043 -04:00
subject,gmb,root,other,joe,other,1835,3097759606,12114 22
text,bad auth. for user roleA
header,97,2,AUE_su,,,2005-04-12 07:28:49.940 -04:00
subject,gmb,root,other,joe,other,1836,3097759606,12114 22
text,bad auth. for user roleA
header,97,2,AUE_su,,,2005-04-12 07:28:59.683 -04:00
subject,gmb,root,other,joe,other,1837,3097759606,12114 22
text,bad auth. for user roleA
file,2005-04-12 07:28:59.000 -04:00,

From this audit trail, you can see that user joe attempted to assume both roleA and roleB. In fact, joe attempted to assume roleB three times with each attempt ending in failure. For more information on the audit logs, their format and options for configuring them, see auditd(1M). For the purposes of this example, Solaris auditing was configured with the following policies:

# auditconfig -getpolicy
audit policies = argv,cnt,perzone

Further, the users and roles defined in this example were audited as follows:

# cat /etc/security/audit_user
# Copyright (c) 1988 by Sun Microsystems, Inc.
# ident "@(#)audit_user.txt     1.6     00/07/17 SMI"
# User Level Audit User File
# File Format
#       username:always:never

These settings effectively audited login and logout events, administrative actions and command execution (exec(2) calls). You should configure Solaris auditing to comply with your local auditing requirements and policies. The configuration presented serves only as an example to illustrate the type of information that can be collected.

By now, you can see that joe cannot access the Cryto Management rights profile on his own. Let's see what would happen if joe attempted to simply perform a restricted cryptographic operation on his own:

joe$ cryptoadm stop
cryptoadm: failed to stop cryptographic framework daemon - Not owner.

Still no luck. In order to perform those restricted operations, he will need john to help him assume roleA. In the final example below, we illustrate that working in concert, joe and john together can successfully assume roleA.

joe$ su roleA
roleA$ id -a
uid=107(roleA) gid=1(other) groups=1(other)
roleA$ profiles -l

      Crypto Management:
          /usr/sbin/cryptoadm    euid=0
          /usr/sfw/bin/    euid=0
          /usr/sfw/bin/openssl    euid=0

With these privileges, joe and john can perform operations such as starting and stopping the Solaris cryptographic framework:

roleA$ echo "foo" | digest -a md5
roleA$ cryptoadm stop
roleA$ echo "foo" | digest -a md5
digest: failed to initialize PKCS #11 framework: CKR_GENERAL_ERROR
roleA$ cryptoadm start
roleA$ echo "foo" | digest -a md5

Clearly, you can see that the "two man rule" is enforced since neither joe nor john can perform any cryptographic management operations on the system without knowledge and support of the other. Further, should either user attempt to access their assigned role, the other user can be alerted through the presence of a Solaris audit record (that neither user can modify). Very cool.

Finally, I would like to thank both Collin Sampson and Scott Rotondo for their careful review and feedback provided on this article.

As always, I am interested in your feedback and thoughts. Please let me know if you have any questions. Take care!

Technorati Tag:

Friday Apr 15, 2005

CIS Solaris 10 Security Benchmark Published

It is with great pleasure that I can announce the public availability of the Solaris 10 Security Benchmark published by the Center for Internet Security.

For those who are not aware, for more than two years, Sun has been working quite closely with CIS to refine the Solaris Benchmark and to better align that document with Sun's BluePrints and tools. Frankly, both parties have benefited from this collaboration and has led to the addition or tuning of many recommendations and the filing of several RFEs that will in turn improve the overall quality and security of Solaris. It is great to see and be a part of such a collaborative effort, and this release marks the greatest level of Sun participation yet!

So - congratulations to CIS and the Unix Benchmark team on a job well done.

Technorati Tag:




« April 2014