Search This Blog

Showing posts with label linux capabilities. Show all posts
Showing posts with label linux capabilities. Show all posts

Thursday, 23 June 2016

Frustrating Sysadmins, pentesters and adversaries with Linux Attributes



Following on from my article on Linux Capabilities I thought I would cover another, interesting, but yet not that well known feature on Linux – that of filesystem attributes. This is not to be confused with extended ACLs.

Linux (file) attributes cover a wide range of features, such as the ability to mark a file as immutable, require secure deletion (read the caveats in the man page), or to exclude it from backups (aka. no dump). Some are user modifiable (with appropriate permissions), some are not.

You can view user attributes for a file using lsattr and change them using chattr.

[root@centos-7-2-t1 ~]# echo hello world > a.a
[root@centos-7-2-t1 ~]# lsattr a.a
---------------- a.a
[root@centos-7-2-t1 ~]# chattr +i a.a
[root@centos-7-2-t1 ~]# lsattr a.a
----i----------- a.a

The man page chattr(1) gives you an idea of some of the features; to quote:

 The letters 'aAcCdDeijsStTu' select the new attributes for  the  files:
 append only (a), no atime updates (A), compressed (c), no copy on write
 (C), no dump (d), synchronous directory updates (D), extent format (e),
 immutable  (i),  data journalling (j), secure deletion (s), synchronous
 updates (S), no tail-merging (t), top of directory hierarchy  (T),  and
 undeletable (u).

Of particular interest from a security point-of-view are the append-only and immutable attributes. These prevent changes, even by root, to such files. This includes renaming and changing permissions.

The exceptions are changing the append-only/immutable attributes (if you are privileged) and appending to an append-only file. For example, following on from the a.a file change above to being immutable, if we try to alter it as root we get the following:

[root@centos-7-2-t1 ~]# rm -f a.a
rm: cannot remove ‘a.a’: Operation not permitted
[root@centos-7-2-t1 ~]# unlink a.a
unlink: cannot unlink ‘a.a’: Operation not permitted
[root@centos-7-2-t1 ~]# chmod 777 a.a
chmod: changing permissions of ‘a.a’: Operation not permitted
[root@centos-7-2-t1 ~]# mv a.a b.b
mv: cannot move ‘a.a’ to ‘b.b’: Operation not permitted
[root@centos-7-2-t1 ~]# echo more >> a.a
-bash: a.a: Permission denied
[root@centos-7-2-t1 ~]# ls -l a.a
-rw-r--r--. 1 root root 12 Jun 23 12:34 a.a

So the file looks normal from an ls, but even root cannot appear to do anything. An unsuspecting sysadmin or adversary is going to be at best confused by such a thing.

OK; you could (attempt to) update the raw device, for example ;-), but isn't this all about raising the bar.

We can always, as root, clear the attribute then delete:

[root@centos-7-2-t1 ~]# chattr -i a.a
[root@centos-7-2-t1 ~]# rm a.a
rm: remove regular file ‘a.a’? y
[root@centos-7-2-t1 ~]#

Does this infer there are limited benefits, in that this only protects files by non-root users? Well, not exactly.

First, as root, as an additional step you need to remove the attribute or change it (eg from immutable to append-only). You need to be in a situation that a) you can do this (an exploit may not initially give you that ability) and b) you know it needs to be done (awareness).

[root@centos-7-2-t1 ~]# lsattr a.a
----i----------- a.a
[root@centos-7-2-t1 ~]# chattr =a a.a
[root@centos-7-2-t1 ~]# lsattr a.a
-----a---------- a.a

Secondly, when we combine this with Linux Capabilities, we can have powerful 'root-like' accounts that cannot change the attribute – because you need the CAP_LINUX_IMMUTABLE capability to do this; a normal user cannot set/clear this flag – even on files they own.

As for root itself, we can always use setpriv or something else to spawn a (root) program with CAP_LINUX_IMMUTABLE removed from the bounding and inheritable set.

This doesn't prevent privilege escalation in various circumstances with these 'root-like' accounts. For example, if you have CAP_DAC_OVERRIDE you could change /etc/shadow and then become root; but it makes compromise noisier and thus more likely to be detected.

I hope you find this useful.

Monday, 2 May 2016

Linux Capabilities - A friend and foe



As an infrastructure engineer (3rd line support) with a healthy interest in security I like to discover and play with the less well known features of technology. It is surprising how many people are not aware of these, even some senior administrators, yet such features can offer both strong mechanisms to improve the security of a system and strong mechanism for a more nefarious individual to compromise or otherwise abuse that system.

One of these are Linux Capabilities, which can be thought of a division of root's capabilities into discrete parts, such as the ability to open a privileged port or bypass discretionary access controls. This allows for a more fine-grained approach to security. Rather than a user or process having root privileges or not, they can have a subset.

If the process is "capabilities aware", then rather than the traditional "become_root" and "unbecome_root" functions that a SUID root process may use to protect itself, it can enable/disable the specific bits it needs. For example, if you only want to open a privileged port, you don't need to enable the ability to read/write any file.

Solaris has something similar - Privileges - but here I'm going to concentrate on the Linux variant.

Processes and files can have a number of "capability sets". These are bitmasks of the discrete capabilities. Of particular interest are:

Permitted - this is the set of capabilities that the process or file can assume
Effective - this is the set of capabilities that the process or file has
Inheritable - this is the set of capabilities that are preserved across an exec or fork e.g. that can be passed on to a sub-process.

The possible configurations are quite extensive, so reading the man page is encouraged. But let's look at some examples.

First, the classic example; ping. On older distributions this was SUID root to allow it to open raw sockets. However, on CentOS 7.1 for example, it isn't. Instead we now use capabilities:

[root@centos7-1 ~]# ls -l /bin/ping
-rwxr-xr-x. 1 root root 44896 Jun 23  2015 /bin/ping
[root@centos7-1 ~]# getcap /bin/ping
/bin/ping = cap_net_admin,cap_net_raw+p

In addition to 'getcap', we can also view the capabilities of a process in a number of ways, such as using the proc filesystem:

[root@centos7-1 ~]# grep ^Cap /proc/$$/status
CapInh:     0000000000000000
CapPrm:     0000001fffffffff
CapEff:     0000001fffffffff
CapBnd:     0000001fffffffff

Or 'getpcaps' to give a more friendly output:

[root@centos7-1 ~]# getpcaps $$
Capabilities for `3506': = cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,35,36+ep

However, as you probably noticed when we listed the 'ping' executable, other than the colour (if use are using ls with colours set), there are no obvious signs that it is a privileged file. Indeed, the traditional 'find' for SUID/SGID files won't show this up. So, unless you are looking for them, these are good places to hide.

So, if an adversary has root and wishes to maintain privileged access, but stay off the radar, they may try a capabilities enabled shell:

[root@centos7-1 mnt]# cp -p /bin/bash /mnt/myBash
[root@centos7-1 mnt]# setcap all+epi /mnt/myBash
[root@centos7-1 mnt]# getcap /mnt/myBash
/mnt/myBash =eip

Then as a non-privileged user we can try this:

[paul@centos7-1 ~]$ /mnt/myBash
[paul@centos7-1 ~]$ wc -l /etc/shadow
wc: /etc/shadow: Permission denied

That is because the processes initial inheritable set (the non-privileged user) is empty and on an exec it is and'ed with the inheritable set of the file. But this is easy to work around; we just get myBash to open the file and hand over the contents to the child:

[paul@centos7-1 ~]$ grep ^Cap /proc/$$/status
CapInh:     0000000000000000
CapPrm:     0000001fffffffff
CapEff:     0000001fffffffff
CapBnd:     0000001fffffffff
[paul@centos7-1 ~]$ wc -l < /etc/shadow
20

But, as an adversary, I feel we can do better. Luckily, rather than rolling our own program to make the relevant system calls to the kernel, we also have a program called setpriv. This unprivileged executable allows a privileged caller to set the inheritable capability set of a process and its uid/gid. So, if we were to create our own privileged copy:

[root@centos7-1 mnt]# cp -p /bin/setpriv /mnt/mySetpriv
[root@centos7-1 mnt]# setcap all+epi /mnt/mySetpriv
[root@centos7-1 mnt]# getcap /mnt/mySetpriv
/mnt/mySetpriv =eip

And then use it as an unprivileged user:

[paul@centos7-1 ~]$ echo $0
-bash
[paul@centos7-1 ~]$ /mnt/mySetpriv --inh-caps +all --reuid 0 /bin/bash
[root@centos7-1 ~]# id -a
uid=0(root) gid=1000(paul) groups=0(root),10(wheel),1000(paul) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

Success. The problem is that this shows up as root:

[root@centos7-1 ~]# ps -fp $$
UID         PID   PPID  C STIME TTY          TIME CMD
root       3693   3455  0 09:17 pts/0    00:00:00 /bin/bash

Instead, let's combine the inheritable set for the process with the privileged shell:

[paul@centos7-1 ~]$ /mnt/mySetpriv --inh-caps +all /mnt/myBash
[paul@centos7-1 ~]$ wc -l /etc/shadow
wc: /etc/shadow: Permission denied

Well that didn't work; but as we are in a capabilities environment, our capabilities are determined by the relationship between the process and files capabilities. This time we lost the permitted set:

[paul@centos7-1 ~]$ /bin/bash
[paul@centos7-1 ~]$ grep ^Cap /proc/$/status
CapInh: 0000001fffffffff
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000001fffffffff

But then there are a multitude of ways we can play with this; just limited to your imagination. e.g. short "one-off" commands via mySetperm will probably get missed by an admin running 'ps'.

Fortunately, one good countermeasure is that setting a filesystem as "nosuid" also disables files from taking on capabilities. But if an adversary is using it to maintain access, then any writable "suid" permitted filesystem will do.

The key is that 'find' SUID won't work, you need to be looking for these privileged files as well.

Finally, if you are looking at assigning users restricted capabilities, you may find pam_setcap of interest.