2021-2022-1 20212822 《Linux内核原理与分析》第十二周作业

  • 实验简介

    • Linux内核从2.1版本开始,就开始支持Capabilities的安全机制。Capabilities安全机制提出的目的在于实现系统特权操作的更加细粒度的访问控制,使用户能够根据实际的安全需求来控制root进程拥有的权限范围,从而取消root进程多余权限带来的安全隐患。在Capabilities机制中,所有权限被分割成比较具体和细小的权限(并将分割出来的每种细小权限称为权能),每种权能代表着root用户进行某种特权操作的权限;系统中只有进程和可执行文件具有权能,系统根据一定的安全策略来赋予进程权能,并根据进程拥有的权能来进行特权操作的访问控制。
  • 实验要求

    • 掌握使用Capability达到遵守最小权限原则的目的,并分析linux中基于Capability访问控制的设计。
  • 实验环境搭建

    • 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
  • 在实验楼中运行如下:
    • 在这里插入图片描述
    • 分别为make和make install的截图
    • 在这里插入图片描述
  • 登陆运行

    • 知识
      • 在操作系统中,有许多只允许超级用户使用的操作,比如配置网卡,备份所有用户文件,关闭计算机等,但如果要进行这些操作就必须先成为超级用户的话,那就违背了最小权限原则。
      • Set-UID程序允许用户暂时以root权限进行操作,即使程序中所进行的权限操作用不到root权限的所有权利,这很危险:因为如果程序被入侵了的话,攻击者可能得到root权限。
      • Capabilities将root权限分割成了权利更小的权限。小权限被称作capability。如果使用capabilities,那么攻击者最多只能得到小权限,无法得到root权限。这样,风险就被降低了。
      • 在kernel版本2.6.24之后,Capabilities可以分配给文件(比如程序文件),线程会自带程序文件被分配到的capabilities。
    • 操作
      • 安装完成后,我们首先以普通用户登录并运行以下命令:
      • $ ping -c 3 www.baidu.com
      • 在这里插入图片描述
      • ping百度发现不行(尴尬),赶紧换成ping实验楼,就可以了…
      • 从上图可以看出,ping命令成功运行。如果ping命令中包含漏洞,那么整个系统可能会被入侵,我们能否移除这些权限 ?
      • 接下来让关闭程序的suid位:
      • $ sudo su
      • # chmod u-s /bin/ping
      • # exit
      • 显示当前目录下文件详细信息:文件所有者具有读取写入执行的所有权限,同组用户具有读取执行的权限、其他用户具有读取执行的权限.
      • 再ping百度看看会怎么样:
      • $ ping www.shiyanlou.com
      • 在这里插入图片描述
      • 它会提示你操作不被允许。这是因为ping命令需要打开RAW套接字,该操作需要root权限,这就是为什么ping是Set-UID程序了。现在我们分配cap_net_raw给ping:
$ sudo su
# setcap cap_net_raw=ep /bin/ping
# exit
$ ping -c 3 www.shiyanlou.com
  • 实验结果截图如下:
  • 在这里插入图片描述
  • 发现此时又可以连接到shiyanlou.com3
  • 接着我们进行修改密码, seed 用户的密码是 dees
  • 试图改密码但是失败了,后来执行setcap后成功
$ 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
  • 截图如下:
  • 在这里插入图片描述
  • 调整权限

    • 知识
      • 跟使用ACL的访问控制相比,capabilities有其它优势:它可以动态调整大量线程的权限,这对于遵守最小权限原则是很有必要的。当线程中某个权限不再需要时,它应当移除所有相对应的capabilities。这样,即使线程被入侵了,攻击者也得不到已经被删除的capabilities。使用以下管理操作调整权限:
        • Deleting:线程永久删除某个capability
        • Disabling:线程会暂时停用某个capability。
        • Enabling:对应Disabling,启用capability。
      • 为了支持动态的capability分配,Linux使用一个与Set-UID相近的机制。举个例子,一个线程具有3组capability设置:允许(permitted P),可继承(inheritable I),和有效(effective E)。允许组由允许线程使用的cap组成,但其中的cap可能还没有激活。有效组由线程当前可以使用的cap组成。有效组是允许组的子集。线程可以随时更改有效组的内容只要不越过允许组的范围。可继承组是在程序运行exec()调用后计算新子线程的cap组用的。
      • 当一个线程fork新线程的时候,子线程的cap组从父线程拷贝。当在一个线程中运行一个新程序时,它的新cap组将根据以下公式计算:
pI_new = pI
pP_new = fP | (fI & pI)
pE_new = pP_new if fE = true
pE_new = empty if fE = false
  • new后缀指新计算值,p前缀指线程,f前缀指文件cap。I,P,E分别指代 inheritable,permitted,effective,是一个cap位一个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;
}
  • 然后运行make与make install安装libcap
    • 在这里插入图片描述
    • 在这里插入图片描述
    • 编译安装完成之后,我们在 /home/shiyanlou/libcap-2.21/libcap 目录下新建一个 use_cap.c 文件,写入如下代码:
#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的使用权限。
    • 本次实验中间未遇到相关问题,唯一的问题就是ping百度ping不通…,改用ping实验楼了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值