Linux Capability exploration experiment

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.

Keywords: Linux Operation & Maintenance server

Added by blogfisher on Thu, 09 Dec 2021 05:59:01 +0200