1, Test task
The principle of using Capability to achieve minimum permission is used, and the design of access control based on Capability in Linux is analyzed
2, Experimental preparation
Download Libcap
libcap Libraries enable user level programs and capability Some linux distributions do not include this library, which is already available in the environment / usr/include/sys/capability.h In order to avoid the influence of the old version, we'd better delete the previous one and download it again. The specific operations are as follows:
$ cd $ wget http://labfile.oss.aliyuncs.com/libcap-2.21.tar.gz $ tar xvf libcap-2.21.tar.gz $ sudo rm /usr/include/sys/capability.h $ sudo rm /lib/libcap.so* $ cd /home/shiyanlou/libcap-2.21/ $ sudo make $ sudo make install
The actual operation screenshot is as follows:
In this experiment, familiar instructions are required:
setcap//Assign capabilities to a file getcap//Displays the capabilities of the file getpcaps//Displays the capabilities of the thread
3, Experimental process
The following experiment demonstrates how capabilities can remove unnecessary rights from root privileged programs.
First, log in as a normal user and run the following command:
$ ping -c 3 www.baidu.com
The command runs successfully. If you check the attribute of / bin/ping, you will find that it is a set uid program owned by root. If the ping contains vulnerabilities, the whole system may be invaded. The question is whether we can remove these permissions from ping.
Next, close the suid bit of the program:
$ sudo su # chmod u-s /bin/ping
be careful:
a. Please confirm which ping is the real location of the ping first;
b, # At the beginning, the command is run with root permission. For ordinary users, please add sudo before the command
ping Baidu again to see what happens:
# exit $ ping www.baidu.com ping: icmp open socket: Operation not permitted
It will prompt you that the operation is not allowed. This is because the ping command needs to open the RAW socket. This operation requires root privileges, which is why Ping is a set uid program.
The actual operation screenshot is as follows:
Let's assign a cap_net_raw ping to see what happens:
$ sudo su # setcap cap_net_raw=ep /bin/ping # exit $ ping -c 3 www.baidu.com
Assign cap_ net_ After the raw is ping ed, the command runs successfully.
The actual operation screenshot is as follows:
Canceling the Set UID of the following program does not affect its behavior.
The following steps prove that the password cannot be changed at first, but the password can be changed successfully after the cap is assigned (the password of the seed user is dees):
$ sudo su seed $ sudo chmod u-s /usr/bin/passwd $ passwd $ sudo setcap cap_chown,cap_dac_override,cap_fowner=ep /usr/bin/passwd $ passwd
The actual operation screenshot is as follows:
Adjust permissions
Compared with ACL access control, capabilities has other advantages: it can dynamically adjust the permissions of a large number of threads, which is necessary to abide by the principle of minimum permissions. When a permission in a thread is no longer needed, it should remove all corresponding capabilities. In this way, even if the thread is invaded, the attacker will not get the deleted capabilities.
Adjust permissions using the following administrative actions:
a. Deleting: the thread permanently deletes a capability
b. Disabling: the thread will temporarily disable a capability.
c. Enabling: corresponding to Disabling, enable capability.
Switch to / home/shiyanlou/libcap-2.21/libcap Directory, edit cap_proc.c file, the specific instructions are as follows:
$ exit $ cd /home/shiyanlou/libcap-2.21/libcap $ sudo vi cap_proc.c
Add the following three functions to / home/shiyanlou/libcap-2.21/libcap/cap_proc.c in
/* Disable a cap on current process */ int cap_disable(cap_value_t capflag) { cap_t mycaps; mycaps = cap_get_proc(); if (mycaps == NULL) return -1; if (cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_CLEAR) != 0) return -1; if (cap_set_proc(mycaps) != 0) return -1; return 0; } /* Enalbe a cap on current process */ int cap_enable(cap_value_t capflag) { cap_t mycaps; mycaps = cap_get_proc(); if (mycaps == NULL) return -1; if (cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_SET) != 0) return -1; if (cap_set_proc(mycaps) != 0) return -1; return 0; } /* Drop a cap on current process */ int cap_drop(cap_value_t capflag) { cap_t mycaps; mycaps = cap_get_proc(); if (mycaps == NULL) return -1; if (cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_CLEAR) != 0) return -1; if (cap_set_flag(mycaps, CAP_PERMITTED, 1, &capflag, CAP_CLEAR) != 0) return -1; if (cap_set_proc(mycaps) != 0) return -1; return 0; }
Compile and install libcap:
$ sudo make $ sudo make install
The actual operation screenshot is as follows:
stay / home/shiyanlou/libcap-2.21/libcap Create a new directory use_cap.c File and assign cap_dac_read_search give it.
#include <fcntl.h> #include <sys/types.h> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <linux/capability.h> #include <sys/capability.h> int main( void ) { if ( open( "/etc/shadow", O_RDONLY ) < 0 ) printf( "(a) Open failed\n" ); if ( cap_disable( CAP_DAC_READ_SEARCH ) < 0 ) return(-1); if ( open( "/etc/shadow", O_RDONLY ) < 0 ) printf( "(b) Open failed\n" ); if ( cap_enable( CAP_DAC_READ_SEARCH ) < 0 ) return(-1); if ( open( "/etc/shadow", O_RDONLY ) < 0 ) printf( "(c) Open failed\n" ); if ( cap_drop( CAP_DAC_READ_SEARCH ) < 0 ) return(-1); if ( open( "/etc/shadow", O_RDONLY ) < 0 ) printf( "(d) Open failed\n" ); if ( cap_enable( CAP_DAC_READ_SEARCH ) == 0 ) return(-1); if ( open( "/etc/shadow", O_RDONLY ) < 0 ) printf( "(e) Open failed\n" ); }
Compile run:
$ gcc -c use_cap.c $ gcc -o use_cap use_cap.o -lcap $ ./use_cap
The actual operation screenshot is as follows:
4, Experimental problems
1. Familiar with cap function
CAP_DAC_READ_SEARCH: ignoring DAC access restrictions for file reading and directory search
CAP_DAC_OVERRIDE: ignoring DAC access restrictions for files
CAP_CHOWN: modify the permission of the file owner
CAP_SETUID: the user ID of the process is allowed to be changed
CAP_KILL: allows sending signals to processes that do not belong to them
CAP_NET_RAW: raw socket allowed
2. What should we do when we want to dynamically adjust the number of ACL based access control permissions? Which is more convenient than capabilities?
ACL access control obtains the access control of access subject permission by querying the access control list. We dynamically adjust the number of ACL based access control permissions by modifying the access permissions of users in the access control list.
Compared with capabilities, ACL is more convenient.
Linux provides a system call sys that directly modifies the process capabilities_ Capset(), the process can use sys_ The capset () call is used to directly modify the power sets of any process except init process. The ACL needs to adjust the security domain and permissions of the files in the access control list. Compared with the two methods, capabilities is more convenient.
3. When a program (running as an ordinary user) disables cap A, it is subject to a buffer overflow attack. The attacker successfully injected malicious code and ran it. Can he use cap A? If the thread deletes cap A, can cap A be used?
When a program (running as an ordinary user) disables cap A, it is subject to a buffer overflow attack. If cap A is not disabled successfully, and the attacker successfully injects malicious code and runs it, cap A can be used.
If the thread deletes capA, then capA has been successfully disabled, and the attacker cannot use capA.
4. The problem is as above. Use race conditional attack instead. Can he use cap A? If the thread deletes cap A, can cap A be used?
Use race condition attack instead. The program disables cap A. the race attacker preempts resources and can obtain the use permission of cap A.
If the thread deletes the capA, the contention attacker can still seize the resources and obtain the permission to use the capA.