L1B0 / LSM-demo

It's my easy RBAC demo in os security class.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RBAC访问控制实验

Author:l1b0

实验环境

Ubuntu 18.04 64bits Linux 4.4

实验过程

1. 创建用户

sudo adduser user_name # 新建用户user1和user2 cat /etc/passwd # 查看用户信息

image-20210428154711853

2. 用户、角色和权限的设计

本次作业我设计了两个用户,分别为user1和user2;以及两个角色fish1和fish2,支持的三种操作为执行、删除和修改文件,其中fish1具有创建和重命名文件的权限,fish2只有删除文件的权限。

image-20210428154720273

image-20210428153535228

3. 用户层程序:角色、用户的管理

角色的信息存储在/etc/lsm/roleconfig,用户的信息存储在/etc/lsm/userconfig,权限只支持三种,即MKDIR、RENAME和RENAME,如下图。

image-20210428153613084

由于这两个文件需要管理员权限编辑,故执行lsm_init程序需要 sudo。 用户层程序lsm_init通过对文件/etc/lsm/roleconfig和/etc/lsm/userconfig进行读写,该程序具有以下功能:

  1. 输出系统的所有用户信息(name,uid,gid);
  2. 输出userconfig;
  3. 更新userconfig;
  4. 删除userconfig的一个用户;
  5. 添加userconfig支持的一个用户;
  6. 输出roleconfig;
  7. 更新roleconfig;
  8. 删除roleconfig的一个角色;
  9. 添加一个角色;

image-20210428153628335

3.1 输出系统的所有用户信息

调用system函数执行命令实现,使用者通过该功能查看当前系统的用户信息。 system("cat /etc/passwd|grep -v nologin|grep -v halt|grep -v shutdown|awk -F\":\" '{ print $1\"|\"$3\"|\"$4 }'|more"); image-20210428153652789

3.2 输出userconfig

通过该功能查看lsm_module支持的用户id及其拥有的角色。 image-20210428153726542

3.3 更新userconfig

可以看到用户user1的角色由fishone更新为fishtwo。 image-20210428153745036

3.4 删除lsm支持的一个用户

删除uid为1001的用户。 image-20210428153802307

3.5 添加lsm支持的一个用户

添加uid为1001的用户,赋予角色fishone。 image-20210428153817994

3.6 输出roleconfig

通过该功能查看lsm_module支持的角色及其拥有的权限。 image-20210428153828417

3.7 更新roleconfig

角色fishone的权限由可创建和可重命名变更为仅可重命名。 image-20210428153840493

3.8 删除lsm的一个角色

删除角色fishone。 image-20210428153851076

3.9 添加lsm的一个角色

添加角色fishone,并赋予权限mkdir和rename。 image-20210428153914260

4. LSM内核模块的实现

安全功能的开关

通过文件/etc/lsm/config的内容进行判断,为T时表示开启,为F时表示关闭。 image-20210428153936450

hook操作原理

为了不用每次导入模块时都重新编译内核,在内核源码/security/security.c的结尾处中添加如下代码,将符号security_add_hooks和security_hook_heads导出。 image-20210428153950808

本次实验支持三种操作,创建文件、删除文件以及重命名文件,对应角色结构体的syscall变量的第1位、第3位和第2位。 image-20210428154035908

image-20210428154019938

三种操作分别对应lsm hook的函数inode_mkdir、inode_rmdir和inode_rename,其函数定义可以在/security/security.c中查看,如下图。 image-20210428154047733

首先定义一个security_hooks_list类型的结构体数组,存放要hook的函数以及自定义的函数。 image-20210428154056966

模块注册函数lsm_init

调用security_add_hooks函数,添加hook。 image-20210428154110132

模块卸载函数lsm_exit

在模块卸载时需要实现对hook的钩子删除,否则在模块卸载后lsm安全功能仍有效。 由于lsm提供的security_delete_hook(位于/include/linux/lsm_hook.h)是一个内联函数,无法导出,所以这里将其源码直接复制过来。

image-20210428154142576

自定义函数my_inode_mkdir

由于mkdir、rmdir和rename的自定义函数流程相似,所以仅对my_inode_mkdir函数进行描述。

函数首先检查安全功能是否开启(读取文件/etc/lsm/config内容判断); 若开启则获取当前用户的uid,并读取user_config和role_config获取到其对应的角色和权限,如果当前用户不在user_config中,说明lsm尚未支持该用户,则直接返回0表示校验通过; 最后判断权限中mkdir操作对应的位是否为1,若为1则表示具有该操作权限,函数返回0(表示通过),否则返回EACCES(表示Permission denied)。

5. 功能性测试

切换用户:su - username

5.1 关闭lsm安全功能

user1在lsm中不具有删除文件夹的权限,但是在关闭lsm功能时可以删除文件夹。 image-20210428154158140

image-20210428154213559

5.2 具有MKDIR权限对应角色fishone的用户user1进行MKDIR

结果如下图,在主目录下创建文件夹aaa成功。 image-20210428154235390

dmesg查看内核输出,首先校验lsm安全开关,然后校验当前用户uid及拥有的角色,最后判断该角色的权限是否能够mkdir。 image-20210428154248901

5.3 具有RENAME权限对应角色fishone的用户user1进行RENAME

将文件夹aaa重命名为bbb。 image-20210428154301390 dmesg查看内核输出 image-20210428154313255

5.4 具有RMDIR权限对应角色fishtwo的用户user2进行RMDIR

删除文件夹aaa。 image-20210428154326380 dmesg查看内核输出。 image-20210428154343173

5.5 不具有RMDIR权限对应角色fishtwo的用户user1进行RMDIR

删除文件夹aaa。 image-20210428154353686 dmesg查看内核输出。 image-20210428154407874

5.6 不具有MKDIR权限对应角色fishone的用户user2进行MKDIR

创建文件夹aaa。 image-20210428154418144 dmesg查看内核输出。 image-20210428154430369

5.7 不具有RENAME权限对应角色fishone的用户user2进行RENAME

重命名文件夹aaa为bbb。 image-20210428154442312 dmesg查看内核输出。 image-20210428154455872

5.8 lsm不支持的用户r11t

用户r11t进行删除文件夹操作,由于lsm的user_config中没有该用户,所以直接通过。 image-20210428154509994 dmesg查看内核输出。 image-20210428154520411

6. 安全性测试

  1. 用户user1拥有rename权限,尝试修改/etc/lsm/config直接关闭lsm安全功能,失败。 image-20210428154535249

image-20210428154548173

  1. 用户user2拥有删除文件夹权限,尝试直接删除/etc/lsm文件夹,失败; image-20210428154607831

  2. /etc/lsm/config文件不存在时,不执行lsm功能; image-20210428154616062

image-20210428154626011

7. 待修复的bug

  1. 虚拟机OS禁用CPU

加载模块lsm_module一段时间后,出现下图弹窗,只能通过恢复快照解决。 image-20210428154642292

附录

内核编译过程

r11t@ubuntu:/usr/src/linux-4.4$ cp /boot/
config-5.4.0-42-generic      memtest86+.elf
config-5.4.0-70-generic      memtest86+_multiboot.bin
config-5.4.0-72-generic      System.map-5.4.0-42-generic
grub/                        System.map-5.4.0-70-generic
initrd.img-5.4.0-42-generic  System.map-5.4.0-72-generic
initrd.img-5.4.0-70-generic  vmlinuz-5.4.0-42-generic
initrd.img-5.4.0-72-generic  vmlinuz-5.4.0-70-generic
memtest86+.bin               vmlinuz-5.4.0-72-generic
r11t@ubuntu:~/Desktop$ uname -r # 查看内核版本    
5.4.0-70-generic
r11t@ubuntu:/usr/src/linux-4.4$ sudo cp /boot/config-5.4.0-70-generic ./config # 复制当前内核的配置
r11t@ubuntu:/usr/src/linux-4.4$ sudo make menuconfig # 直接退出
r11t@ubuntu:/usr/src/linux-4.4$ vim config # set CONFIG_MODULE_SIG=n,关闭内核模块签名验证
r11t@ubuntu:/usr/src/linux-4.4$ sudo make clean
r11t@ubuntu:/usr/src/linux-4.4$ sudo make modules -j3
r11t@ubuntu:/usr/src/linux-4.4$ sudo make modules_install
r11t@ubuntu:/usr/src/linux-4.4$ sudo make -j 3
r11t@ubuntu:/usr/src/linux-4.4$ sudo make install

遇到的问题及解决方法

  1. 【已解决】编译内核出现:cc1: error: code model kernel does not support PIC mode
    • 方法:sudo vim Makefile # 添加-fno-pie
    • image-20210428155430096
  2. 【已解决】make modules_install出现sign-file: certs/signing_key.pem: No such file or directory
  3. 【已解决】内核签名验证关闭:CONFIG_MODULE_SIG=n
  4. 【已解决】make[1]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'. Stop.
    • 方法:在.config 中把CONFIG_SYSTEM_TRUSTED_KEYS=""设置为空值,重新make
  5. 【待解决】linux-4.12.1,编译内核完成并加载内核后,加载lsm_module模块,demsg出现security_add_hooks: kernel tried to execute NX-protected page - exploit attempt? (uid: 0)
    • 方法:更换为版本4.4的内核源码。

参考资料

About

It's my easy RBAC demo in os security class.


Languages

Language:C 98.3%Language:Makefile 1.7%