Linux Capability exploration experiment

Posted by jake2891 on Thu, 09 Dec 2021 01:53:35 +0100

Linux Capability exploration experiment

Experimental description

In this experiment, we will feel the advantages of linux capability function in access control, master the purpose of using Capability to comply with the principle of minimum permission, and analyze the design of access control based on Capability in linux.

Environment construction

Download Libcap

$ 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

Experimental process

In the operating system, there are many operations that are only allowed to be used by super users, such as configuring network cards, backing up all user files, shutting down the computer, etc., but if you have to become super users to perform these operations, it violates the principle of minimum permission.

The Set UID program allows the user to temporarily operate with root permission, even if the permission Operation in the program does not use all the rights of root permission, which is very dangerous: if the program is invaded, the attacker may get root permission.

Capabilities divides root permissions into smaller permissions. Small permissions are called capabilities. If capabilities is used, the attacker can only get small privileges at most and cannot get root privileges. In this way, the risk is reduced.

1. Log in as an ordinary user

$ ping -c 3 www.baidu.com

2. Run the first step command with root privileges and execute the following commands

$ sudo su
# setcap cap_net_raw=ep /bin/ping
# exit
$ ping -c 3 www.baidu.com

The experimental results are as follows

$ 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 experimental results are as follows

This step proves that the password cannot be changed at the beginning, but the password can be changed successfully after the cap is assigned:
The password of the seed user is dees.

3. Adjust authority
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:

Deleting: the thread permanently deletes a capability
Disabling: the thread will temporarily disable a capability.
Enabling: corresponding to Disabling, enable capability.
In order to support dynamic capability allocation, Linux uses a mechanism similar to Set UID. For example, a thread has three sets of capability settings: allowed (P), inheritable (I), and effective (E). The allow group consists of caps that are allowed to be used by threads, but the caps in them may not have been activated. A valid group consists of the caps currently available to the thread. A valid group is a subset of the allowed groups. A thread can change the contents of a valid group at any time as long as it does not exceed the range of allowed groups. The inheritable group is used to calculate the cap group of the new sub thread after the program runs the exec() call.

When a thread fork s a new thread, the cap group of the child thread is copied from the parent thread. When a new program is run in a thread, its new cap group will be calculated according to the following formula:

pI_new = pI
pP_new = fP | (fI & pI)
pE_new = pP_new if fE = true
pE_new = empty if fE = false

The new suffix refers to the newly calculated value, the P prefix refers to the thread, and the f prefix refers to the file cap. 1. P and E refer to inheritable, permitted and effective respectively. They are calculated by cap bit by cap bit.

Switch to / home/shiyanlou/libcap-2.21/libcap directory and edit cap_proc.c file. To make it easier for the program to operate cap, add the following three functions to / home/shiyanlou/libcap-2.21/libcap/cap_ In proc. C.

/* 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;
}

Then compile and install.

Create a new use in / home/shiyanlou/libcap-2.21/libcap directory_ 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" );

}

Finally, compile and run. The experimental results are as follows

Experimental summary

Question 1. 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 is to obtain the access control of access subject permission by querying the access control list. When we want to dynamically adjust the number of ACL based access control permissions, we adjust them 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.

Problem 2. When the program (running as an ordinary user) disables cap A, it is attacked by buffer overflow. 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. As a result, cap A is not disabled successfully. The attacker successfully injects malicious code and runs it. You can use cap A. If the thread deletes capA, capA has been successfully disabled and the attacker cannot use capA.

Question 3. 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 competitive condition attack instead. The program disables cap A. competitive attacker can seize resources and obtain capA permission. If the thread deletes the capA, the concurrency attacker can still seize the resources and obtain the permission of the capA.

Topics: Linux Operation & Maintenance server