Linux Security Basics
User
- In Linux, each user is assigned a unique user ID
- User ID is stored in /etc/passwd

- Find user ID
- ‘id’ command prints real and effective user and group IDs

- Add users
- Directly add to /etc/passwd
- Use “adduser” command

- Switch to another user

Group
- Represent a group of users
- Assigning permissions based on group
- A user can belong to multiple groups
- A user’s primary group is in /etc/passwd

- Group Management

Permissions and Access Control
- Types of access on files
- read (r): user can view the contents of the file
- write (w): user can change the contents of the file
- execute (x): user can execute or run the file if it is a program or script
- Types of access on directories
- read (r): user can list the contents of the directory (e.g., using ls)
- write (w): user can create files and sub-directories inside the directory
- execute (x): user can enter that directory (e.g., using cd)

- Changing File Permissions
- ‘chmod’ command changes file mode bits

- Default File Permissions
- umask value: decides the default permissions for new files
Note. The operation of umask is not XOR or AND.
The actual operation of umask is AND with the complement!
- Access Control List (ACL)
- Assign permissions to individual users/groups
- Coexist with the traditional permission model
- Get file access control lists

- set file access control lists

Running Commands with Privilege
- Three Ways
- sudo
- Set-UID programs (covered in next section)
- POSIX capabilities
- Using sudo
- sudo: Super-user Do
- Run commands as a superuser
- A user must be authorized (/etc/sudoers)
- Here is how the seed user is allowed to run sudo

- In Ubuntu 20.04, the root user account is locked
- Cannot log into the root account
- There are many ways to get a root shell
- sudo–s
- sudo bash
- sudo su

- It is not recommended to run commands using a root shell. Instead, use sudo to run individual commands
- Run command using another user (instead of root, default)

- POSIX Capabilities
- Divide the root privilege into smaller privilege units
- Known as capabilities
- Use “man capabilities” to find all the capabilities
- CAP_CHOWN
- Make arbitrary changes to file UIDs and GIDs → chown
- CAP_DAC_OVERRIDE
- Bypass file read, write, and execute permission checks
- CAP_DAC_READ_SEARCH
- Bypass file read permission checks and directory read and execute permission checks
- CAP_NET_RAW
- Use RAW and PACKET sockets
- Setting File Capabilities


- Wireshark
- Sniffing tool, needs privilege
- The graphic part is not privileged
- The sniffing part is done by dumpcap, privileged

- ping
- Uses raw socket
- Has the CAP_NET_RAW capability

Authentication
- Authentication Methods
- A process to verify a user’s identity
- Typical authentication methods
- based on something the user knows: password
- based on something the user has: ID card
- based on something the user is or does: fingerprint
- Multi-factor authentication
- The Password File
- Each entry contains a user account information
- Password is not stored in /etc/passwd

- First Command After Login
- The last field of each entry

- The Shadow File
- Store password, why not use /etc/passwd anymore?
- Structure for each entry

- Password: Hashing and Salting
- Salting the password
- When storing the encrypted password, append something to it.

- Purpose of Salt
- Slow down brute-force attacks
- Dictionary attack, rainbow table attack
- These 3 accounts have the same password

- Locking Account
- Putting an invalid value in the password field
- The root account is locked

Set-UID Programs
- Password dilemma
- Permissions of /etc/shadow File :

- How would normal users change their password?

- Two-Tier Approach

- Implementing fine-grained(세분화된) access control in operating systems make OS over complicated.
- OS relies on extension to enforce(적용하다) fine-grained access control
- Privileged programs are such extensions
- Daemons
- Computer program that runs in the background
- Needs to run as root or other privileged users
- Set-UID Programs
- Widely used in UNIX-like systems
- Program marked with a special bit
- Applied to executable files
- Run with the permission of the file’s owner instead of the user who executed it
Set-UID Concept
- Allow user to run a program with the program owner’s privilege
- Allow users to run programs with temporary elevated privileges
- Example: the password program (passwd)

- Every process has two User IDs
- Real UID (RUID): Identifies real owner of process
- Effective UID (EUID): Identifies privilege of a process
- Access control is based on EUID
- When a normal program is executed, RUID == EUID, they both equal to the ID of the user who runs the program
- When a Set-UID is executed, RUID ≠ EUIDs. RUID still equal to the user’s ID, but EUID equals to the program owner’s ID.
- If the program is owned by root, the program runs with the root privilege
- Change the owner of a file to root

- Before enabling Set-UID bit

- After enabling the Set-UID bit

- A Set-UID program is just like any other program, except that it has a special marking, which a single bit called Set-UID bit

- Example

How is Set-UID Secure?
- Allows normal users to escalate privileges
- This is different from directly giving the privilege (sudo command)
- Restricted behavior – similar to iron man’s suit designed computer chips
- Unsafe to turn all programs into Set-UID
- Example: /bin/sh
- Example: vi
Attack Surfaces of Set-UID Programs
- Buffer overflow
- Overflowing a buffer to run malicious code
- Format string vulnerability
- Changing program behavior using user inputs as format strings
- Race condition
- Symbolic link to privileged file from a unprivileged file
- Influence programs
- Writing inside world writable folder
Attacks via Environment Variables
- Environment variables
- Dynamic values that affect the behavior of processes on a computer.
- They store configuration settings for applications and system functions.
- These can be set by a user before running a program.
- PATH Environment variable
- Used by shell programs to locate a command if the user does not provide the full path for the command
- system(): call /bin/sh first
- system("ls")
- /bin/sh uses the PATHenvironment variable to locate "ls"
- Attacker can manipulate the PATHvariable and control how the "ls"command is found
Capability Leaking
- In some cases, privileged programs downgrade themselves during execution
- Example: The su program
- This is a privileged Set-UID program
- Allows one user to switch to another user (say user1 to user2)
- Program starts with EUID as root and RUID as user1
- After password verification, both EUID and RUID become user2’s (via privilege downgrading)
- Such programs may lead to capability leaking
- Programs may not clean up privileged capabilities before downgrading
- Attacks via Capability Leaking


- Case Study: Capability Leaking in OS X
- OS X Yosemite found vulnerable to privilege escalation attack related to capability leaking in July 2015 (OS X 10.10)
- Added features to dynamic linker dyld
- DYLD_PRINT_TO_FILE: environment variable
- The dynamic linker can open any file, so for root-owned Set-UID programs, it runs with root privileges. The dynamic linker dyld, does not close the file. There is a capability leaking.
- Scenario 1 (safe): Set-UID finished its job and the process dies.
Everything is cleaned up and it is safe.
- Scenario 2 (unsafe): Similar to the “su” program, the privileged
program downgrade its privilege, and lift the restriction
Invoking Programs
- Invoking external commands from inside a program
- External command is chosen by the Set-UID program
- Users are not supposed to provide the command (or it is not secure)
- Attack
- Users are often asked to provide input data to the command.
- If the command is not invoked properly, user’s input data may be turned into command name. This is dangerous
- Unsafe Approach
- The easiest way to invoke an external command is the system() function.
- This program is supposed to run the /bin/cat program.
- It is a root-owned Set-UID program, so the program can view all files, but it can’t write to any file.
Question: Can you use this program to run other command, with the root privilege?
- Safely: using execve()
- Code (command name) and data are clearly separated; there is no way for the user data to become code


- Some functions in the exec() family behave similarly to execve(), but may not be safe
- execlp(), execvp() and execvpe() duplicate the actions of the shell.
- These functions can be attacked using the PATH Environment variable
- Invoking External Commands in Other Languages
- Risk of invoking external commands is not limited to C programs
- We should avoid problems similar to those caused by the system() functions
- Examples:
- Perl: open()function can run commands, but it does so through a shell
- PHP: system()function

- Attack:
Principle of Isolation
- Principle: Don’t mix code and data
- Attacks due to violation of this principle
- system() code execution
- Cross Site Scripting → More information in web security
- SQL injection → More information in web security
- Buffer overflow attacks → More Information in the next chapter
Principle of Least Privilege
- A privileged program should be given the power which is required to perform it’s tasks.
- Disable the privileges (temporarily or permanently) when a privileged program doesn’t need those.
- In Linux, seteuid() and setuid() can be used to disable/discard privileges.
- Different OSes have different ways to do that.
Environment Variables
- A set of dynamic named values
- Part of the operating environment in which a process runs
- Affect the way that a running process will behave
- Introduced in Unix and also adopted by Microsoft Windows
- Example: PATH variable
- When a program is executed the shell process will use the environment variable to find where the program is, if the full path is not provided.
Access environment variables
- From the main function

- More reliable way: using the global variable

Get environment variables
- Two ways
- If a new process is created using fork() system call, the child process will inherits its parent process’s environment variables.
- If a process runs a new program in itself, it typically uses execve() system call.
- In this scenario, the memory space is overwritten and all old environment variables are lost.
- execve()can be invoked in a special manner to pass environment variables from one process to another.
- Passing environment variables when invoking execve():

- The program executes a new program /usr/bin/env, which prints out the environment variables of the current process.
- We construct a new variable newenv, and use it as the 3rd argument.


Memory Location for Environment Variables
- envp and environ points to the same place initially.
- envp is only accessible inside the main function, while environ is a global variable.
- When changes are made to the environment variables (e.g., new ones are added), the location for storing the environment variables may be moved to the heap, so environ will change (envp does not change)

Shell Variables
- People often mistake shell variables and environment variables to be the same.
- Shell Variables:
- Internal variables used by shell
- Shell provides built-in commands to allow users to create, assign and delete shell variables.
- In the example, we create a shell variable called FOO

Side Note on The /proc File System
- /proc is a virtual file system in linux. It contains a directory for each process, using the process ID as the name of the directory
- Each process directory has a virtual file called environ, which contains the environment of the process.
- e.g., virtual file /proc/932/environ contains the environment variable of process 932
- The command “strings /proc/$$/environ” prints out the environment variable of the current process (shell will replace $$ with its own process ID)
- When env program is invoked in a bash shell, it runs in a child process. Therefore, it print out the environment variables of the shell’s child process, not its own.
- Shell variables and environment variables are different
- When a shell program starts, it copies the environment variables into its own shell variables. Changes made to the shell variable will not reflect on the environment variables, as shown in example

- Right shows how shell variables affect the environment variables of child processes
- It also shows how the parent shell’s environment variables becomes the child process’s environment variables (via shell
variables)
- When we type env in shell prompt, shell will create a child process

Attack Surface on Environment Variables
- Hidden usage of environment variables is dangerous.
- Since users can set environment variables, they become part of the attack surface on Set-UID programs.

Attacks via Dynamic Linker
- Linking finds the external library code referenced in the program
- Linking can be done during runtime or compile time:
- Dynamic linking – uses environment variables, which becomes part of the attack surface
- Static linking
- We will use the following example to differentiate static and dynamic
linking:
- Static linking
- The linker combines the program’s code and the library code containing the printf() function
- We can notice that the size of a static compiled program is 100 times larger than a dynamic program

- Dynamic linking
- The linking is done during runtime
- Shared libraries (DLL in windows)
- Before a program compiled with dynamic linking is run, its executable is loaded into the memory first

- We can use “ldd” command to see what shared libraries a program depends on :

- The Risk
- Dynamic linking saves memory
- This means that a part of the program’s code is undecided during the compilation time
- If the user can influence the missing code, they can compromise the integrity of the program
- Case Study 1 ( Example 1: Normal Programs )
- LD_PRELOAD contains a list of shared libraries which will be searched first by the linker
- If not all functions are found, the linker will search among several lists of folder including the one specified by LD_LIBRARY_PATH
- Both variables can be set by users, so it gives them an opportunity to control the outcome of the linking process
- If that program were a Set-UID program, it may lead to security breaches
- Program calls sleep function which is dynamically linked:

- Now we implement our own sleep() function

- We need to compile the above code, create a shared library and add the shared library to the LD_PRELOAD environment variable

- Case Study 2 ( Example 2: Set-UID Program )
- If the technique in example 1 works for Set-UID program, it can be very dangerous. Lets convert the above program into Set-UID

- Our sleep() function was not invoked.
- This is due to a countermeasure implemented by the dynamic linker. It ignores the LD_PRELOAD and LD_LIBRARY_PATH environment variables when the EUID and RUID differ.
- Lets verify this countermeasure with an example in the next slide.
- Make a copy of the env program and make it a Set-UID program :

- Export LD_LIBRARY_PATH and LD_PRELOAD and run both the programs:

- Case study: OS X Dynamic Linker
- As discussed in previous section (in capability leaking), apple OS X 10.10 introduced a new environment variable without analyzing its security implications perfectly.
- DYLD_PRINT_TO_FILE
- Ability for users to supply filename for dyld
- If it is a Set-UID program, users can write to a protected file
- Capability leak – file descriptor not closed
- Exploit example:
- Set DYLD_PRINT_TO_FILE to /etc/sudoers
- Switch to Bob’s account
- The echo command writes to /etc/sudoers

Attacks via External Program
- An application may invoke an external program.
- The application itself may not use environment variables, but the invoked external program might.
- Typical ways of invoking external programs:
- exec() family of function which call execve(): runs the program directly
- system()
- The system()function calls execl()
- execl()eventually calls execve()to run /bin/sh
- The shell program then runs the program
- Attack surfaces differ for these two approaches
- We have discussed attack surfaces for such shell programs. Here we will focus on the Environment variables aspect.
- Case Study
- Shell programs behavior is affected by many environment variables, the most common of which is the PATH variable.
- When a shell program runs a command and the absolute path is not provided, it uses the PATH variable to locate the command.
- We will force the left program to execute the right program


- Attack Surfaces
- Compared to system(), execve()’s attack surface is smaller
- execve() does not invoke shell, and thus is not affected by environment variables
- When invoking external programs in privileged programs, we should use execve()
- Refer to the previous section for more information
Attacks via Application Code
- Programs may directly use environment variables. If these are privileged programs, it may result in untrusted inputs.

- The program uses getenv() to know its current directory from the PWD environment variable
- The program then copies this into an array “arr”, but forgets to check the length of the input. This results in a potential buffer overflow.
- Value of PWD comes from the shell program, so every time we change our folder the shell program updates its shell variable.
- We can change the shell variable ourselves.

- Countermeasures
- When environment variables are used by privileged Set-UID programs, they must be sanitized properly.
- Developers may choose to use a secure version of getenv(), such as secure_getenv().
- getenv() works by searching the environment variable list and returning a pointer to the string found, when used to retrieve a environment variable.
- secure_getenv() works the exact same way, except it returns NULL when “secure execution” is required.
- Secure execution is defined by conditions like when the process’s user/group EUID and RUID don’t match
Set-UID Approach vs. Service Approach
- Most operating systems follow two approaches to allow normal users to perform privileged operations
- Set-UID approach: Normal users have to run a special program to gain root privileges temporarily
- Service approach: Normal users have to have to request a privileged service to perform the actions for them. Figure in the earlier slide depicts these two approaches
- Set-UID has a much broader attack surface, which is caused by environment variables
- Environment variables cannot be trusted in Set-UID approach
- Environment variables can be trusted in Service approach
- Although, the other attack surfaces still apply to Service approach (discussed in previous section), it is considered safer than Set-UID approach
- Due to this reason, the Android operating system completely removed the Set-UID and Set-GID mechanism
HGU 전산전자공학부 고윤민 교수님의 24-2 컴퓨터 보안 수업을 듣고 작성한 포스트이며, 첨부한 모든 사진은 교수님 수업 PPT의 사진 원본에 필기를 한 수정본입니다.