11 April,19 at 11:50 AM
In modern IT environments, the need for implementing least-privilege access is often driven because of a combination of tightening security and regulatory compliance:
For example, traditionally in most environments, UNIX system administrators have full access to the root account of the systems they manage. Unbridled access to the system root account prevents or severely complicates the requirement of traceability: as multiple system administrators know the root password, it is not possible to differentiate between who did what using the shared root account. As the root account provides full system access, this creates a huge gap in security.
This requirement does not limit itself to the root account; application users often access systems with a shared account, which has the same consequences for traceability.
Application users and consultants usually need access to a well-defined subset of commands that need to be run as a shared application account. Giving them the ability to run any command as the target application account may open up a path of potential abuse; not only by the user that is granted these permissions themselves, but any intruder that manages to compromise the account of this target user.
It may even be desired to limit the list of commands that a user can run, beyond what the operating system considered privileged commands (i.e. entries in the sudoers file); For example, to reduce the attack surface of an unprivileged user's shell, or maybe to prevent users with limited UNIX knowledge from inflicting damage on all user-writable files.
The standard tool to address the above concerns on Unix/Linux operating systems is sudo; The sudo package allows enforcement of a policy, defined in /etc/sudoers, that contains entries specifying users with access to specific commands, which can then be run with pre-defined privileges ('the runas credentials'). Centrify provides its own tools that supports the same functionality as sudo, as well as a range of features that sudo does not provide.
Each time a user runs a command with sudo, it is being recorded in the system's log. Keylogging and screen output capture can be enabled by specifying the log_output sudo option in the sudoers file. This records input and output data into various files in a tree-like structure in the local filesystem.
Proper implementation of the log_output data in a large environment is not for the faint-hearted, nor is querying the keyboard input or screen output (input is recorded as raw scan codes). To get a complete picture, enabling log_output would commonly need to be combined by logging of system calls with the audit daemon (auditd) and centralisation using remote syslog and storage into a backend database or search server like ElasticSearch and/or SIEM solution.
Centrify makes implementation of auditing requirements much easier, through its DirectAudit component, part of Centrify Server Suite Enterprise Edition. However, in this article the focus does not lie on DirectAudit; instead the core functionality of sudo, that allows implementation of least privileges, is explored in-depth.
Centrify provides its own sudo-like tool, called dzdo, which provides full command-line compatibility with sudo, but differs substantially from sudo in certain key areas:
Various information has previously been released on the first four bullet-points. For example:
In this article we'll explore the Restricted Shell further. When organisations mention regulatory compliance for least-privilege, and use terms like 'whitelisting' and 'blacklisting' in combination with unprivileged accounts, usage of the Restricted Shell comes into play. The terms blacklisting and whitelisting commonly are used as follows:
Whitelisting refers to the fact that by default, no command is allowed, except for a specific list of commands, which is the so-called 'whitelist'.
Whitelisting is the basic operation of dzsh; without any command definitions in place, dzsh allows a user only to run the built-in shell commands (for a complete list of built-in shell commands on a Linux distribution, run 'man bash' and search for the section 'SHELL BUILTIN COMMANDS').
Blacklisting refers to the ability of denying access to specific commands that would otherwise be allowed. This can be used in two ways:
During my work, the second blacklisting scenario has been brought up several times. Unfortunately, implementation of this type of blacklisting on linux does not translate into any meaningful security, but may require some examples to show why this is the case.
Suppose an unprivileged user is allowed to run any command, except '/bin/ls'.
Next, access to the '/bin/cp' command is denied too.
In a further step, suppose all user-writeable paths on the system are eliminated.
...This list could go on almost endlessly with methods to bypass the blacklist alternated by more severe restrictions to prevent the bypass method. In short, it's a very time-consuming game of catch-up, that will never be able to fully stop insistent and creative UNIX user with shell access, from performing those actions that administrators are trying to deny.
While dzdo does not allow identifying binaries through file hash or signature (for signed code), these features would not help in the above blacklisting examples either. Signature data can easily be stripped, and strings in a file can be modified, resulting in a different hash value of the binary.
Instead of following this fruitless approach of blacklisting, in an environment where by default all commands are allowed, a better approach has previously been mentioned:
Using the Restricted Shell
To use the restricted shell, first add a new Centrify Role definition to the target Centrify zone. This role definition can be named accordingly, e.g. 'UNIX Restricted Shell'. In the System Rights tab, make sure the following options are set:
Note to make sure that 'Login with non-Restricted Shell' has NOT been checked.
Now click on OK to confirm the new Role Definition.
Right-click the new Role definition, and select Add right... ; now add the ssh and sshd PAM access rights, allowing the users to access target machines through SSH.
You can now assign this role definition like any other, either through zone-wide Role Assignments, or through Computer Roles.
Next, to allow a user to run any binaries in addition to the built-in shell commands, you'll need to create explicit command rights.
For example, you can grant a user access the right to run the dzinfo command, which shows the Centrify authorization data on the machine on which they have access. This allows users of the restricted shell to see what exactly they can run.
In the Restricted Shell tab, make sure that the Can be used in a restricted role option has been checked, and that the Run this command as data is set to the User running the command (unless you want to define a privileged command in the restricted shell, i.e. similar to what the Run As tab does for dzdo commands in a regular shell).
In the Run As tab, disable the option Can be used by dzdo; if you don't do this, you'll grant any user that has been granted permission to run the dzdo command, the ability to run the unprivileged command as root (this is the default setting when you create a new command right). This step is extremely important, as the pam access right to the dzdo PAM facility is implicitly granted to all users; there are no further barriers in place, other than having to allow the users to run the dzdo binary (it is a bad idea to grant users access to the dzdo command in the restricted shell, as you can run privileged commands by setting a different user in the Restricted Shell tab of the command right definition. Combining the dzdo tab with the restricted shell in one command right definition leads to poor visibility of the effective rights, and can easily lead to accidentally granting more access than desired).
Now add the newly defined command right for use in the Restricted Shell to the Role definition that grants access to the Restricted Shell.
For examples on how to limit the scope of the whitelist by adding certain command line parameters to the blacklist, I'd suggest you to look at the example in the blog post of my colleague Fabrice.
Note that careful attention needs to be paid to any command that has the ability to spawn child processes and run arbitrary code. For example, even a text editor such as 'vi' can be used to run shell commands. For this reason, the Allow nested command execution option in the Attributes tab should be disabled, unless explicitly required; and in that case, it should be enabled only after careful validation that the target program cannot run arbitrary user-specified code in the child processes.