Page 1 of 2

Beginners trouble generating/writing policies

PostPosted: Fri Jun 15, 2012 11:27 am
by unigood
Hello

i've got a problem with subject and full learning: they builds quite open policies.

First of, i began with full system learning. It's a simple SSH box, so i got this (with minor adjustments):
Code: Select all
# policy generated from full system learning

define grsec_denied {
   /boot   h
   /dev/grsec   h
   /dev/kmem   h
   /dev/mem   h
   /dev/port   h
   /etc/grsec   h
   /proc/kcore   h
   /proc/slabinfo   h
   /proc/modules   h
   /proc/kallsyms   h
   /lib/modules   hs
   /lib64/modules   hs
   /etc/ssh   h
}

role admin sA
subject / rvka
   / rwcdmlxi

role shutdown sARG
subject / rvka
   /
   /dev
   /dev/urandom r
   /dev/random r
   /etc r
   /bin rx
   /sbin rx
   /lib rx
   /lib64 rx
   /usr rx
   /proc r
   $grsec_denied
   -CAP_ALL
   connect disabled
   bind disabled

role default
subject /
   /         h
   -CAP_ALL
   connect   disabled
   bind   disabled

role sshd u
# Role: sshd
subject /  {
   /            h
   -CAP_ALL
   bind   disabled
   connect   disabled
}

role root uG
role_transitions admin shutdown
# Role: root
subject /  {
   /            h
   /dev/initctl         
   /sbin/gradm         x
   -CAP_ALL
   bind   disabled
   connect   disabled
}

# Role: root
subject /usr/sbin/sshd o {
user_transition_allow sshd root
group_transition_allow nogroup root

   /            w
   /bin            h
   /bin/bash         x
   /dev            h
   /dev/log         rw
   /dev/null         rw
   /dev/urandom         r
   /dev/pts         rw
   /dev/ptmx         rw
   /etc            r
   /etc/grsec         h
   /etc/ssh/keys         r
   /lib            rx
   /proc            w
   /proc/filesystems      r
   /proc/sys/kernel/ngroups_max   r
   /usr            h
   /usr/lib         rx
   /usr/sbin         h
   /usr/sbin/sshd         x
   /usr/share         h
   /usr/share/ssh/blacklist.DSA-1024   r
   /usr/share/ssh/blacklist.RSA-2048   r
   /usr/share/ssh/blacklist.RSA-4096   r
   /var            h
   /var/run         
   /var/run/motd         r
   /var/run/utmp         r
   -CAP_ALL
   +CAP_SETGID
   +CAP_SETUID
   +CAP_SYS_CHROOT
   +CAP_SYS_RESOURCE
   bind 0.0.0.0/32:4301 stream tcp
   connect   disabled
   sock_allow_family ipv6 netlink
}


This seems a bit open (or maybe that's where i am wrong), as it set for subject /usr/sbin/sshd o access to root directory to writeable. Ok, i could not login, while RBAC enabled, so i added a learning subject for /bin/bash (as the grsec logs implied):
Code: Select all
subject /bin/bash ol {
   /            h
   -CAP_ALL
   bind   disabled
   connect   disabled
}


The learning itself went without errors:
Code: Select all
$ gradm -E -L /tmp/grsec.bash.logs
# do some hundred logins, try call some shell progs like date, id and such
$ gradm -D
$ gradm -O /tmp/grsec.bash.profile -L /tmp/grsec.bash.logs


The generated subject for /bin/bash looked like this:
Code: Select all
subject /bin/bash o {
   /            rxw
   /dev/grsec         h
   /etc/grsec         h
   -CAP_ALL
   bind   disabled
   connect   disabled
   sock_allow_family unix inet
}


Which again, looks very open to me (rxw to root dir). Maybe /bin/bash is hard to train, so i tried another one: /usr/bin/id, which should be simpler, as it really doesnt do very much (according to strace). Again, got a quit open policy for the subject:
Code: Select all
subject /usr/bin/id o {
   /            rx
   /dev/grsec         h
   /etc/grsec         h
   -CAP_ALL
   bind   disabled
   connect   disabled
   sock_allow_family unix inet
}


So i assume i am doing either something fundamentally wrong or (auto) learning is just meant to "point you in the right direction" (docs state one should better rely on auto learning, rather than creating policies manually).

Also, i tried to build the /usr/bin/id policy manually, by giving access only to anything opened (as seen in the learning logs and strace -f id):
Code: Select all
subject /usr/bin/id o {
   /                        h
   /dev/grsec                  h
   /etc/group                  r
   /etc/grsec                  h
   /etc/locale.alias            r
   /etc/nsswitch.conf            r
   /etc/passwd                  r
   /lib                     h
   /lib/ld-2.11.3.so            r
   /lib/libc-2.11.3.so            r
   /lib/libdl-2.11.3.so         r
   /lib/libnsl-2.11.3.so         r
   /lib/libnss_compat-2.11.3.so   r
   /lib/libnss_files-2.11.3.so      r
   /lib/libnss_nis-2.11.3.so      r
   /lib/libselinux.so.1         r
   /proc/filesystems            r
   /proc/sys/kernel/ngroups_max   r
   /selinux                  r
   /usr/lib/locale/locale-archive   r
   /usr/share/locale/en/LC_MESSAGES/coreutils.mo   r
   /var/run                  r
   /var/run/nscd/socket         r
   -CAP_ALL
   bind    disabled
   connect disabled
   sock_allow_family unix inet
}

However, this did not work, lead to a segmentation fault.

So the questions are:
* How else should subject learning be used - or am i to paranoid about the generated restrictions?
* What is wrong with my manually generated policy for /usr/bin/id? Especially: How can i "debug" this myself?(strace did not work -> either i gave it to open restrictions and no seg fault was thrown, or it failed)

Thanks & Greets
Walt

Re: Beginners trouble generating/writing policies

PostPosted: Fri Jun 15, 2012 11:52 am
by spender
What version of grsecurity is this?

Do you have an /etc/grsec/learn_config ? Is it the default one shipped with gradm?

BTW, it should never be necessary to create subjects for things like 'bash' or 'id' -- general commands of a particular user. Those should fall into the default subject for the associated role.

Your policies definitely don't look like any I've ever created with full learning, and the fact that only /etc/grsec and /dev/grsec remain hidden in the bash subject for instance is troubling. If you compile gradm with -DGRADM_DEBUG, it'll enable some consistency checking when performing the learning. Also, if you're able to, I'd like to see the learning log that produced these policies.

Thanks,
-Brad

Re: Beginners trouble generating/writing policies

PostPosted: Fri Jun 15, 2012 1:38 pm
by unigood
Hello Brat, thanks for your reply.

I am using gradm version 2.9.1. I think you already figured my main problem out: My learn_config was empty..

However, I re-ran the full learn, here are the generated logs: http://pastebin.com/8REiCaw0, here the generated policy: http://pastebin.com/kZBNX4D2

Using the shipped learn_config file, the generated policy is here: http://pastebin.com/WfrupwMy

As mentioned, the box, on which the config shall be applied, provides only ssh for testing. So the command i used to generated the learning logs is:
Code: Select all
for s in $( seq 1 99 ); do ssh testbox exit; done


The new generated policy looks less open (no rw on root dir), however, the default policy (for root) still needs manual adjustment, if it should allow /usr/bin/id and alike. Is this expected or am i still screwing the learning process up somehow?

Greets
Walt

Re: Beginners trouble generating/writing policies

PostPosted: Fri Jun 15, 2012 2:38 pm
by spender
That looks much better. Have you grepped for 'id' in the learning log? It shouldn't be throwing any rules out -- if something was accessed during learning, it will be reflected in the policy.

-Brad

Re: Beginners trouble generating/writing policies

PostPosted: Mon Jun 18, 2012 9:11 am
by unigood
Hello Brad

Thanks for your last reply. This hinted me to look what my train-method (the for-loop) actually did. As it turned out, ssh does not really create a terminal session when called as ssh <hostname> <cmd>, which i did (lazily). Performing the training with "real" ssh <hostname> and then manually execution exit did indeed init a bash session, including calls to [i]id[/id] and so on -> now the policy just works without manual changes, directly after training. Here it is (ftr): http://pastebin.com/vk31xfPv. Based on those logs: http://pastebin.com/LxLtUB6i

Thanks for your help!

Greets
Walt

Re: Beginners trouble generating/writing policies

PostPosted: Mon Jun 18, 2012 10:45 am
by spender
Much better! Looking at the policy makes me think it'd be nice to have some functionality for merging two subjects. For instance, a subject for bash as root was created since it wrote to .bash_history, but it might make sense just to roll that into the default subject for root.

-Brad

Re: Beginners trouble generating/writing policies

PostPosted: Wed Jun 27, 2012 1:19 pm
by unigood
Hello again. I am not sure whether i should create a new topic on this. Somehow, it is a follow up (still trouble ;)) and builds on the previous posted config.

Before i explain the issues, let me outline the setup. It's about an SSH server, to which some users can login. The webserver stuff is handled on another machine, however i require a certain folder structure. Basically it is this way:

Code: Select all
# chroot home
/home/user1/
/home/user1/etc
/home/user1/bin
# ..
# this would be a path to http documents
/home/user1/webdir/user1/www


The user-home folder would be /home/user1/webdir/user1. Please excuse the strangeness, i tried to scale it down to readable (in reallity, the path-names are longer, but from a structural point of view alike)

Assuming the last working config above (from June 18), i've basically added a user-group (ssh-users) which are allowed to login. With disabled grsec it works, with enabled grsec also.

Here is the config snippet (there is no other configuration for this group or any other besides root and the defaults.. see above):
Code: Select all
role ssh-users g
# Role: ssh-users
subject /  {
   /               h
   /home               
   /home/*               r
   /home/*/bin            xi
   /home/*/dev            
   /home/*/dev/tty            rw
   /home/*/dev/null         rw
   /home/*/dev/urandom         r
   /home/*/dev/zero         r
   /home/*/etc            r
   /home/*/lib            rxi
   /home/*/lib64            rxi
   /home/*/proc            r
   # -- %< --
   # here i have some addtional hide-rules, which are removed for better reading
   # -- %< --
   /home/*/tmp            rcwd
   /home/*/usr            
   /home/*/usr/bin            xi
   /home/*/usr/lib            rx
   /home/*/usr/share         r
   /home/*/var            r
   
   # the web-directories look like this:
   #   /home/user1/webdir/user1/www
   #
   /home/*/webdir/*/.bash_history      ra
   /home/*/webdir/*/.ssh         
   /home/*/webdir/*/.ssh/authorized_keys   rw
   /home/*/webdir/*/logs*         r
   /home/*/webdir/*/www         rc
   /home/*/webdir/*/www/*         rcwd
   -CAP_ALL
   bind   disabled
   connect   disabled
}


Here are the issues

1: Giving an object (/bin/something) only excute and inheritance (xi), the user can still read the file
As show above, /bin and /usr/bin shall only have xi, no read rights. However, i can still read the contents (eg $ less /bin/bash).

I suspect the problem is in
Code: Select all
   /home/*               r
   /home/*/bin            xi

The first line allowes read, the next execute and inheritance. However, from my understand grsec uses the most specific object, which is /home/*/bin, which does not grand read capability.

2: Giving an object (dir-path) only read permissions (r), user can still create (but not write into) files
For example, logged in as a user in the ssh-users group i can do this (the directory (~/logs/apache) belongs to user1 and has 0755.):
Code: Select all
$ date > ~/logs/apache/testfile

I am getting an error (which is good):
Code: Select all
-bash: logs/apache/testfile: Permission denied

Also grsec logs (all auditing is enabled):
Code: Select all
(ssh-users:G:/) denied open of /home/user1/webdir/user1/logs/apache/testfile for writing by /home/user1/bin/bash[bash:21891] uid/euid:3001/3001 gid/egid:3000/3000, parent /home/user1/bin/bash[bash:21673] uid/euid:3001/3001 gid/egid:3000/3000

However, and this is the problem, an (empty) file is created in the directory.

Here i really have no clue. There is no preceding or subsequent line granting create-rights.

-------


In total, both issues do not bother me - however, i really would like to understand why grsec behaves the way it does and if i can achieve the desired behavior some other way. Please ask, if further infos are required.

One last thing: probably most of my troubles result from the wildcard-lines. Is there any other way to create rules for a multitude (up to some hundred) of users? I found some forum post about variables in 2003. Did I miss those somehow (could not find them in wikibooks).

Thanks! Walt

Re: Beginners trouble generating/writing policies

PostPosted: Wed Jun 27, 2012 2:14 pm
by spender
What version kernel is this? Are you able to repeat the same behavior if the path doesn't involve a chroot?

-Brad

Re: Beginners trouble generating/writing policies

PostPosted: Thu Jun 28, 2012 6:54 am
by unigood
I am using 2.6.32.59 on the box (cannot use >= 3.0, long story).

I could not reproduce the create-but-not-write issue outside the chroot. However, i was able to solve the can-read issue when for /home/*/bin by moving the /bin-rule before the other:
Code: Select all
/home/*/bin            xi
/home/*               r


One other (strange) fact about the create-but-not-write issue which might help to nail it down: i am not able to create just any file. For example the following "worked":
Code: Select all
logs/apache/foobar
logs/apache/foobar3
logs/apache/foobar34
logs/apache/foobar34444444444
logs/apache/testfil
logs/apache/testfile
logs/apache/testfile34
logs/apache/testfile345
logs/apache/testfile5


The following did not "work":
Code: Select all
logs/apache/testfile3


Also corresponding i see the (expected) log for testfile3:
Code: Select all
(ssh-users:G:/) denied create of /home/user1/webdir/user1/logs/apache/testfile3 for writing by /home/user1/bin/bin/bash[bash:13785] uid/euid:3001/3001 gid/egid:3000/3000, parent /home/user1/bin/bash[bash:12368] uid/euid:3001/3001 gid/egid:3000/3000


Wheras for the other files, which are created, i see this:
Code: Select all
(ssh-users:G:/) denied open of /home/user1/webdir/user1/logs/apache/testfile5 for writing by /home/user1/bin/bash[bash:13787] uid/euid:3001/3001 gid/egid:3000/3000, parent /home/user1/bin/bash[bash:12368] uid/euid:3001/3001 gid/egid:3000/3000


Hope this helps a bit to trace the issue. If i can provide any more infos, let me know.

Greets
Walt

Re: Beginners trouble generating/writing policies

PostPosted: Thu Jun 28, 2012 8:19 am
by spender
Would you be able to strace apache from the admin role to see what syscalls are being used for the creates?

BTW, regarding most specific matches, that applies when using normal objects. I seem to remember posting somewhere the way object matching works in RBAC, but here it is:

objects without any regular expressions can act as "anchors" for objects with regular expressions
given the two objects:
/home
/home/*/bin

/home acts as an anchor for /home/*/bin

A regular expression always attaches to an anchor that is the longest string of non-wildcarded path components in its path (up to the first component containing a wildcard).

In a normal scenario without regular expressions in any objects, if we were to access a /home/blah/bin/sh file, we would check for the following objects in this order:
/home/blah/bin/sh
/home/blah/bin
/home/blah
/home
/

When an anchor has attached regular expressions and the lookup reaches the anchor, then each attached regular expression is evaluated in the order in which it is listed in the policy.

Given the following policy:
/home
/home/*/bin
/home/blah/bin/sh

If we were to access /home/blah/bin/sh, then the explicit object for it would match first.

Given the following policy:
/home
/home/*
/home/*/bin

If we were to access /home/blah/bin/sh, /home/* would match first because it is listed first in the policy.

Hope this clears that part up at least.

-Brad

Re: Beginners trouble generating/writing policies

PostPosted: Thu Jun 28, 2012 10:00 am
by unigood
First of: Thanks for looking into this!

In the scenario, there is (luckily) no apache involved. I simply have an SSH (chrooted-)session open for a user accessing the web-directory which then will be served by apache (from another machine).

So here are the traces. I've used from admin role
Code: Select all
$ strace -p <bash-pid> -f

where bash-bid is the PID from the bash process of the logged in user (child of sshd). As user, i issue the following command
Code: Select all
$ date > logs/apache/testfile1

which creates the file (but does not write into). Here is the strace: http://pastebin.com/s0XCbr1W - the PIDs you want to look at are 12368 (bash) and 18437 (the process which tries to write).

Also the strace for the scenario where everything works as supposed (nothing is created nor written): http://pastebin.com/bt4iXn4E - the PIDs you want to look at are 12368 (bash) and 18577 (the process which tries to write).

Again: if i can provide more info, let me know.

Thanks a lot for your time! Walt

*Edit: Thanks for the clearification about the wildcard-order. Yes, this clears things up pretty much.

Re: Beginners trouble generating/writing policies

PostPosted: Mon Jul 02, 2012 8:29 pm
by spender
Hi Walt,

I tried to reproduce your case here but was unable to.

To debug the problem further, you can change the lines:
Code: Select all
        while (tmp) {
                if (!glob_match(tmp->filename, *path))
                        return tmp;
                tmp = tmp->next;
        }


in grsecurity/gracl.c:chk_glob_label()

to:

Code: Select all
        while (tmp) {
                if (!glob_match(tmp->filename, *path)) {
                        printk(KERN_ALERT "matched %s 0x%x for %s\n", tmp->filename, tmp->mode, *path);
                        return tmp;
                }
                tmp = tmp->next;
        }


Then give me the printks that result from this. I plan to eliminate some policy errors in the future by checking if a globbed object exists that is fully covered by some previous-listed globbed object.

Thanks,
-Brad

Re: Beginners trouble generating/writing policies

PostPosted: Wed Jul 04, 2012 1:16 pm
by unigood
Hello Brad

sorry for the late reply. Saw your post just yesterday and needed to install the patched kernel.

The logs look different, as there are many duplicate lines for the file which is (wrongly) created than for the file which is not.
Here for testfile1, which is created (but should not): http://pastebin.com/Q3HFMnin
Here for testfile3, which is not created (as expected): http://pastebin.com/JEaK3Yey

Hope this helps you to figure this out.

Greets
Walt

*Edit: For completeness sake: I used touch ../testfile[13], not date > ../testfile[13] this time, hope this makes no difference (realized it afterwards).

Re: Beginners trouble generating/writing policies

PostPosted: Wed Jul 04, 2012 2:06 pm
by spender
Have you been replacing a real username with "user1" in these reports? /home/*/var should never be matching the path it says it's matching. I've confirmed here by ripping out glob_match and running it standalone that those two pathnames will not match.

-Brad

Re: Beginners trouble generating/writing policies

PostPosted: Thu Jul 05, 2012 6:40 am
by unigood
Hallo Brad

Yes, as mentioned in post from 27th June, i've scaled the paths down, for readability. Also the structure and the user username has changed since the initial posting.

I've sent you (PM) the original structure.

Greets
Walt