2023-2024-1 20232820 陈彦霖《Linux内核原理与分析》第十三周作业

Linux Capability探索实验


一、实验描述


本实验中,学生将感受到linux capability功能在访问控制上的优势,掌握使用Capability达到遵守最小权限原则的目的,并分析linux中基于Capability访问控制的设计。

二、环境搭建


在进行实验之前,首先需要做一些准备工作。

下载Libcap
libcap 库能够使用户级别的程序与 capability 特性做交互,一些linux发行版不包括这个库,在环境中已经有 /usr/include/sys/capability.h 这个文件,为了避免老版本的影响,我们还是删掉以前的,然后重新下载一个。

$ 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
 

在本实验中,你需要熟悉以下命令:

·setcap: 给一个文件分配capabilities
·getcap: 显示文件所带的capabilities
·getpcaps: 显示线程所在的capabilities

三、 实验内容


在一个capability系统中,当一个程序运行时,对应的线程会初始化一系列capabilities(令牌)。当线程尝试访问某个对象时,操作系统会检查该线程的capabilities,并决定是否授权访问。

3.1 感受一下Capabilities

首先,以普通用户登录并运行以下命令:

$ ping -c 3 www.baidu.com


命令成功运行,如果你查看/bin/ping的属性会发现它是一个root所有的Set-UID程序。如果ping中包含漏洞,那么整个系统就可能被入侵。问题是是否能移除ping的这些权限。
关闭程序的suid位

$ sudo su
# chmod u-s /bin/ping

现在再ping百度看会发生些什么:

# exit
$ ping www.baidu.com


它会提示你操作不被允许。这是因为ping命令需要打开RAW套接字,该操作需要root特权,这就是为什么ping是Set-UID程序了。但有了capability,我们就可以杯酒释兵权了,让我们分配cap_net_raw给ping,看看会发生什么:

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

1.取消下列程序的Set-UID并不影响它的行为。
这一步证明一开始无法修改密码,但是在分配了cap之后就可以成功修改密码:
seed 用户的密码是 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


效果如下:


3.2 调整权限


切换到 /home/shiyanlou/libcap-2.21/libcap 目录下,编辑 cap_proc.c文件。

$ exit
$ cd /home/shiyanlou/libcap-2.21/libcap
$ sudo vi cap_proc.c


为了让程序操作cap变得简单,添加以下三个函数到 /home/shiyanlou/libcap-2.21/libcap/cap_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;
}


运行以下命令编译安装libcap:

$ sudo make
$ sudo make install    

在 /home/shiyanlou/libcap-2.21/libcap 目录下新建一个 use_cap.c 文件,并分配cap_dac_read_search给它。
以普通用户登录并运行程序。描述并解释观察。

#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" );
}


使用以下命令编译运行:

$ gcc -c use_cap.c
$ gcc -o use_cap use_cap.o -lcap
$ ./use_cap


结果如下:


四、课后问题
问题1: 当我们想动态调整基于ACL访问控制权限的数量时,应该怎么做?与capabilities比较哪种更加便捷?
ACL访问控制即通过查询访问控制列表来获得访问主体权限的访问控制。当我们想动态调整基于ACL访问控制权限的数量时,我们通过修改访问控制列表中用户的访问权限来进行调整。ACL方式与capabilities相比,capabilities更便捷。Linux提供了直接修改进程权能的系统调用sys_capset(),进程可以通过sys_capset()调用来直接修改除init进程以外的任何进程的各权能集。而ACL需要调整访问控制列表中文件的安全域和权限等进行权限调整。
问题2: 当程序(以普通用户运行)禁用cap A时,它遭到了缓冲区溢出攻击。攻击者成功注入恶意代码并运行。他可以使用cap A么? 如果线程删除了cap A呢,可以使用cap A么?
当程序(以普通用户运行)禁用cap A时,它遭到了缓冲区溢出攻击。导致cap A没有成功禁用,攻击者成功注入恶意代码并运行,可以使用capA。如果线程删除了capA,则capA已经成功禁用,攻击者不可以使用capA。
问题3: 问题如上,改用竞态条件攻击。他可以使用cap A么? 如果线程删除了cap A呢,可以使用cap A么?
改用竞态条件攻击,程序禁用cap A,竞态攻击者抢占资源,可以获得capA使用权限。如果线程删除了capA,竞态攻击者依然可以抢占资源,取得capA的使用权限。

  • 23
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值