Unix Security ============= Delve into the idea of privilege separation from last lecture in the context of Unix security. Primarily established using access control rules that determine who has how much access to a particular resource. Implemented using the following key ideas: Unix Principals Permission bits on individual objects User ids and Group Ids Temporary Elevated privileges Chroot and jails Unix Principals: Entities that can own and have certain privileges on a certain set of files Determines access control rules Users - typically individual accounts to distnguish resources that only that individual can access Groups - useful when you want a set of users to have access to some common resource; each user can be a part of multiple groups and each group consists of multiple users Names vs ids: Names that are easy to remember and login using on a user's end Numbers that the system uses to identify you once you are logged in - filesystems use ids Password file (/etc/passwd) maps user names to id It also lists group names/ids Conventions: UID values in the range 0 to 99 should be statically allocated by the system, shall not be created by applications, UIDs from 100 to 499 should be reserved for dynamic allocation by system administrators and post install scripts Root/Superuser: Uid = 0 Highly privileged user that can run all administrative tasks on a given machine It is able to access all files/directories/executables and is also able to modify other users permissions This includes access to /etc/passwd and other sensitive resources Nobody: typically a user with no privileges if you know that certain processes like web browsers should not attempt to access or execute any local files Demo: $ whoami $ id $ sudo adduser abc -u uid $ su abc $ su httpd $ sudo deluser abc sudo: command that allows you to execute a particular command that follows it as a particular user typically used to execute commands as the superuser - for instance file installations that might need you to modify root directories Sample commands: # potentially dangerous opens the file as super user - allowing you to edit it $ sudo vi /etc/passwd # when this only gives you readonly access $ vi /etc/passwd Permission bits: tells you what access level a given user/group/world has on a particular resource - file or directory mean different things in the context of a file and a directory user/group/other: User: principal that owns the resource Group: group that controls this resource other or world: everyone else who doesn't match the uid or isn't part of the above group Why is group useful? Say user x and y both have two files a and b that they exclusively want to own, but a file c that they both want to have access to. With just user names that is not possible. But, with groups, if they both belonged to a common group z that had access to file c (regardless of what the user on c is), they'd be able to both have separate/exclusive access over thir files while having joint access over c $ groupadd $ usermod are useful commands to modify groups/users. read/write/execute: Files: read means the ability to read/view a file write - ability to modify the file execute - ability to execute or run the file/binary Directories: read: ability to just read the names of the files in a directory, but no further info including ownership/size/contents write: ability to create/delete/rename files in a given directory execute: ability to search the directory, but needs read for listing file names Effectively, need all 3 to do anything useful in a directory Sticky bit: When set on a directory restricts who can delete or rename files in that directory, otherwise any user can. Any user can append new files to the directory, but can only delete or rename fiiles if you have write permissions over the directory and ownership over file or directory (or are the superuser). Typically used in the /tmp/ directory Representation: run `ls -l` on a directory to see the long description of every file including who the owner/group is along with their access rights Interpreting output: d implies directory rwx - read/write/executable a "-" in a particular place implies that particular bit is not set or the corresponding principal doesn't have that particular ability on the resource in context to be read as user/group/other rights in order for every set of 3 bits t denotes sticky bit Octal representation: Convert to binary 7 becomes 111 implies rwx 5 becomes 101 implies r-x 3 becomes 011 implies -wx and so on Examples: The binary `print_user.sh` is owned by httpd and is rwx only by the user. So if you run it as httpd, you can access it. However, if you switch user to abc, you cannot run it as expected. Changing permission bits/ownership: chown: Changes the user id or group id associated with the file depending on what is specified If you want to change it for a directory, you need to use the -R flag to recursively change owner for all the files in the directory can only be run by super user # example # works as httpd and not as abc $ ./print_user.sh # Now, what if as admin you want to change the owner to abc for `print_user.sh` $ sudo chown abc print_user.sh` $ su abc $ ./print_user.sh chgrp: changes the group id of the file to the specified file Similarly, use a -R to recursively set it for all files in the directory chmod: change the file permissions (or mode) of a given file +/- to grant or revoke corresponding access a/u/g/o - to change permissions for all/user/group/others r/w/x - to give read/write/executable permissions t - to set sticky bit s - to make it a setuid binary - (to be covered later) You can run `ls -l print_user.sh` after every one of these to see what the permission bits are. # creates a file by default with rw permissions for user and r for group/others. $ touch print_user.sh you can explicity state what permissions you want on a file in octal form but can only run chmod as owner, so you need to be abc based on where we last left off for this user # gives everyone rwx access $ chmod 777 print_user.sh let's reset this to just read permissions for all: $ chmod 444 print_user.sh If you want to just make it executable for all (user/group and other): $ chmod +x print_user.sh $ chmod a+x print_user.sh to be read as give All(a) executable(x) access To give executable access just for the group $ chmod g+x print_user.sh To revoke write access just for the user $ chmod u-w x What if I forgot what the relevant symbol for the "other" is? $ man chmod Real/effective/saved UIDs and GIDs Linux programs run under a particular user ID and group ID For running program, can query procfs: `/proc//status` `id` program: shows current user identity information Used for access control checks (e.g. in file system ops) Effective UID used in checks Why do you need more than one (why real/effective/saved)? setuid binaries Might need programs to run at a higher authority than current user Flag on a binary: `chmod u+s` Makes binary run with EUID of owner (usually root) Examples: passwd, chsh, su, sudo setuid on directories does nothing setgid bit: makes all files created automatically have group of dir Consider a setuid binary: runs with EUID root, RUID user May need to temporarily take another user's identity (=> need RUID) Need a way to switch back (=> need SUID) How do you switch permissions? setuid() / setgid() family of system calls (see man pages) Note: different from setuid bit on an executable setresuid() Permissions rules: each new value has to be one of the current values (current RUID, current EUID, current SUID) Example: setuid root binary run by UID 1000 now: R=1000, E=0, S=0 seteuid(getruid()) now: R=1000, E=1000, S=0 seteuid(0) now: R=1000, E=0, S=0 Demo: printuid $ ./printuid $ sudo ./printuid $ sudo chown root printuid $ ./printuid $ sudo chmod u+s printuid $ ls -l printuid $ ./printuid Demo: setresuid $ ./setresuid $ sudo chown root setresuid $ chmod u+s setresuid $ ./setresuid GIDs are analogous to UIDs chroot Change (apparent root), process retains open file descriptors Many uses; we're using it for "jailing" Setup requires great care Lots of details: look up "escaping chroot" E.g. should only be used for processes that don't run as root E.g. shouldn't have setuid binaries in the jail Correct usage: // be root chdir(JAIL_DIR); chroot(JAIL_DIR); setuid(UID); // UID > 0 Have to ensure that all dependencies are present (e.g. if you're launching a program, shared libraries should be present) Demo: $ ./chroot $ sudo ./chroot IPC Inter-process communication: mechanism for parts of privilege-separated program to communicate Many implementations: shared memory, pipes, UNIX domain sockets Lab 2: UNIX domain sockets + Python rpclib Demo: sockserver / sockclient $ ./sockserver sock $ ls -l sock $ file sock $ ./sockclient sock 123 Misc lab 2 tips mkdir Used for creating directories Demo $ mkdir foo/bar $ mkdir foo $ mkdir foo/bar $ mkdir foo $ rm -r foo $ mkdir -p foo/bar/baz $ mkdir -p foo $ tree foo umask masks permissions of files/directories being created Linux: default directory 777, file 666, default umask 022 file permission = default & ~(umask) Demo $ umask $ touch foo $ ls -l $ umask 077 $ touch bar $ ls -l $ umask -S g+rw $ umask $ mkdir baz $ ls -l special directories '~' means your home directory (expanded by shell) In lab, /home/httpd Can also use $HOME (also expanded by shell) '/tmp': special directory for temporary stuff Other sandboxing techniques Unix originally designed for multi-user environment: DAC over files DAC vs MAC: see notes from l06-capsicum.txt Unix DAC model not great for expressing security policies Other mechanisms SELinux and AppArmor: per-program security policies (a form of MAC) seccomp ("secure computing"): severely restrict syscalls Originally designed for running untrusted compute-bound programs for public grid computing Only exit(), sigreturn(), read() and write() on open FDs seccomp-bpf: customizable syscall filtering with Berkeley Packet Filter In practice, many techniques can be used together Example: Google Chrome uses privilege separation with multiple processes, chroot, Linux namespaces, seccomp-bpf