转载:linux capability深入分析

转至http://www.cnblogs.com/iamfy/archive/2012/09/20/2694977.html

一)概述:

1)从2.1版开始,Linux内核有了能力(capability)的概念,即它打破了UNIX/LINUX操作系统中超级用户/普通用户的概念,由普通用户也可以做只有超级用户可以完成的工作.

2)capability可以作用在进程上(受限),也可以作用在程序文件上,它与sudo不同,sudo只针对用户/程序/文件的概述,即sudo可以配置某个用户可以执行某个命令,可以更改某个文件,而capability是让某个程序拥有某种能力,例如:

capability让/tmp/testkill程序可以kill掉其它进程,但它不能mount设备节点到目录,也不能重启系统,因为我们只指定了它kill的能力,即使程序有问题也不会超出能力范围.

3)每个进程有三个和能力有关的位图:inheritable(I),permitted(P)和effective(E),对应进程描述符task_struct(include/linux/sched.h)里面的cap_effective, cap_inheritable, cap_permitted,所以我们可以查看/proc/PID/status来查看进程的能力.

4)cap_effective:当一个进程要进行某个特权操作时,操作系统会检查cap_effective的对应位是否有效,而不再是检查进程的有效UID是否为0.

例如,如果一个进程要设置系统的时钟,Linux的内核就会检查cap_effective的CAP_SYS_TIME位(第25位)是否有效.

5)cap_permitted:表示进程能够使用的能力,在cap_permitted中可以包含cap_effective中没有的能力,这些能力是被进程自己临时放弃的,也可以说cap_effective是cap_permitted的一个子集.

6)cap_inheritable:表示能够被当前进程执行的程序继承的能力.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

#undef _POSIX_SOURCE
#include <sys/capability.h>

extern int errno;

void whoami(void)
{
  printf("uid=%i euid=%i gid=%i\n", getuid(), geteuid(), getgid());
}

void listCaps()
{
  cap_t caps = cap_get_proc();
  ssize_t y = 0;
  printf("The process %d was give capabilities %s\n",
  (int) getpid(), cap_to_text(caps, &y));
  fflush(0);
  cap_free(caps);
}

int main(int argc, char **argv)
{
  int stat;
  whoami();
  stat = setuid(geteuid());
  pid_t parentPid = getpid();

  if(!parentPid)
  return 1;
  cap_t caps = cap_init();

  cap_value_t capList[5] =
{ CAP_NET_RAW, CAP_NET_BIND_SERVICE , CAP_SETUID, CAP_SETGID,CAP_SETPCAP } ;
  unsigned num_caps = 5;
  cap_set_flag(caps, CAP_EFFECTIVE, num_caps, capList, CAP_SET);
  cap_set_flag(caps, CAP_INHERITABLE, num_caps, capList, CAP_SET);
  cap_set_flag(caps, CAP_PERMITTED, num_caps, capList, CAP_SET);

  if (cap_set_proc(caps)) {
    perror("capset()");

    return EXIT_FAILURE;
  }
  listCaps();   

  printf("dropping caps\n");
  cap_clear(caps); // resetting caps storage

  if (cap_set_proc(caps)) {
    perror("capset()");
    return EXIT_FAILURE;
  }
  listCaps();   

  cap_free(caps);
  return 0;}

编译:

gcc capsettest.c -o capsettest -lcap

编译时找不到sys/capability.h 需要安装libcap(http://www.man7.org/linux/man-pages/man8/setcap.8.html)或者apt-get install libcap-dev

运行:

./capsettest

uid=0  euid=0  gid=0

The process 2383 was give capabilities = cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw+eip

dropping caps

The process 2383 was give capabilities =

注:

1)我们对该进程增加了5种能力,随后又清除了所有能力.

2)首先通过cap_init()初始化存放cap能力值的状态,随后通过cap_set_flag函数的调用,将三种位图的能力设置给了变量caps,再通过cap_set_proc(caps)设定当前进程的能力值,通过cap_get_proc()返回当前进程的能力值,最后通过cap_free(caps)释放能力值.

3)cap_set_flag函数的原型是:

int cap_set_flag(cap_t cap_p, cap_flag_t flag, int ncap,const cap_value_t *caps, cap_flag_value_t value);

我们这里的调用语句是:cap_set_flag(caps, CAP_PERMITTED, num_caps, capList, CAP_SET);

第一个参数cap_p是存放能力值的变量,是被设定值.这里是caps.

第二个参数flag是是三种能力位图,这里是CAP_PERMITTED.

第三个参数ncap是要设定能力的个数,这里是num_caps,也就是5.

第四个参数*caps是要设定的能力值,这里是capList数组,也就是CAP_NET_RAW, CAP_NET_BIND_SERVICE , CAP_SETUID, CAP_SETGID,CAP_SETPCAP.

第五个参数value是决定要设定还是清除,这里是CAP_SET.

4)cap_set_proc函数的原型是:int cap_set_proc(cap_t cap_p);

cap_set_proc函数通过cap_p中的能力值设定给当前的进程.

5)cap_get_proc函数的原型是:cap_t cap_get_proc(void);

cap_get_proc函数返回当前进程的能力值给cap变量.

6)cap_free函数的原型是:cap_free(caps);

cap_free函数清理/释放cap变量.

7)如果我们fork()了子进程,那么子进程继承父进程的所有能力.

8)不能单独设定CAP_EFFECTIVE,CAP_INHERITABLE位图,必须要和CAP_PERMITTED联用,且CAP_PERMITTED一定要是其它两个位图的超集.

9)如果两次调用cap_set_proc函数,第二次调用的值力值不能少于或多于第一次调用.如第一次我们授权chown,setuid能力,第二次只能是chown,setuid不能是其它的能力值.

10)普通用户不能给进程设定能力.

三)进程的能力掩码:

我们可以通过下面的程序获取当前进程的掩码,它是通过capget函数来获取指定进程的能力掩码,当然我们也可以用capset来设定掩码,下面获取掩码的体现:

#undef _POSIX_SOURCE

#include <stdlib.h>

#include <stdio.h>

#include <sys/types.h>

#include <unistd.h>

#include <linux/capability.h>

#include <errno.h>

int main()

{

struct __user_cap_header_struct cap_header_data;

cap_user_header_t cap_header = &cap_header_data;

struct __user_cap_data_struct cap_data_data;

cap_user_data_t cap_data = &cap_data_data;

cap_header->pid = getpid();

cap_header->version = _LINUX_CAPABILITY_VERSION_1;

if (capget(cap_header, cap_data) < 0) {

perror("Failed capget");

exit(1);

}

printf("Cap data 0x%x, 0x%x, 0x%x\n", cap_data->effective,

cap_data->permitted, cap_data->inheritable);

}

gcc capget0.c -o capget0 -lcap

普通用户:

./capget0

Cap data 0x0, 0x0, 0x0

超级用户:

/home/test/capget0

Cap data 0xffffffff, 0xffffffff, 0x0

这也说明了默认情况下,root运行的进程是什么权限都有,而普通用户则什么权限都没有.

时间: 2024-08-24 14:19:38

转载:linux capability深入分析的相关文章

Linux的capability深入分析

Linux的capability深入分析详见:http://blog.csdn.net/u014338577/article/details/48791953 lxd中对容器能力的限制: 普通用户不能修改系统时间,不能插入/删除内核模块, toDrop := "sys_time sys_module sys_rawio" if !aaStacking || c.IsPrivileged() { toDrop = toDrop + " mac_admin mac_overrid

CentOS6.5菜鸟之旅:纯转载Linux目录结构

来自:http://www.iteye.com/topic/1125162 使用linux也有一年多时间了  最近也是一直在维护网站系统主机  下面是linux目录结构说明 本人使用的是centos系统,很久没有发表博文了 近期会整理自己所用所了解知识点,发表linux相关的文章,记录自己的linux点点滴滴. linux 目录结构 /: 根目录,一般根目录下只存放目录,不要存放文件,/etc./bin./dev./lib./sbin应该和根目录放置在一个分区中/bin:/usr/bin: 可执

[转载] Linux/Unix 系统负载原理解析[英文]

PDF下载:http://vdisk.weibo.com/s/cULRe2mYCQsPz/1407491911 [转载] http://yuxu9710108.blog.163.com/blog/static/23751534201022593028822/ CALC_LOAD() calc_load()工作原理 In this two part-series I want to explore the use of averages in performance analysis and ca

[转载] linux下打开windows txt文件中文乱码问题

原文链接 在linux操作系统下,我们有时打开在windows下的txt文件,发现在windows下能正常显示的txt文件出现了中文乱码. 出现这种情况的原因为两种操作系统的中文压缩方式不同,在windows环境中中文压缩一般为gbk,而在linux环境中为utf8,这就导致了在windows下能正常显示 txt文件在linux环境下打开呈现了乱码状态. 解决方法:在linux用iconv命令,如乱码文件名为shujujiegou.txt,那么在终端输入如下命令: iconv -f gbk -t

Linux基本功杂记——[020]——『Linux Capability』

『Linux Capability』 For the purpose of performing permission checks, traditional UNIX implementations distinguish two categories of processes: privileged processes (whose effective user ID is 0, referred to as superuser or root), and unprivileged proc

(转) Linux的capability深入分析(2)

一)capability的工具介绍 在我们的试验环境是RHEL6,libcap-2.16软件包中包含了相关的capability设置及查看工作,如下: rpm -ql libcap-2.16-5.2.el6.i686 /lib/libcap.so.2 /lib/libcap.so.2.16 /lib/security/pam_cap.so /usr/sbin/capsh /usr/sbin/getcap /usr/sbin/getpcaps /usr/sbin/setcap /usr/share

[转载]Linux后门整理合集(脉搏推荐)

我在思考要不要联系下....都禁止转载了.... 简介 利用 Unix/Linux 自带的 Bash 和 Crond 实现远控功能,保持反弹上线到公网机器. 利用方法 先创建 /etc/xxxx 脚本文件(名字自己改),利用该脚本进行反弹.以下脚本代表全自动反弹到 8.8.8.8 的 53 端口. nano /etc/xxxx #!/bin/bash if netstat -ano|grep -v grep | grep "8.8.8.8">/dev/null then echo

[转载] linux find 命令

转载自 http://www.jb51.net/os/RedHat/1307.html Linux下find命令在目录结构中搜索文件,并执行指定的操作. Linux下find命令提供了相当多的查找条件,功能很强大.由于find具有强大的功能,所以它的选项也很多,其中大部分选项都值得我们花时间来了解一下. 即使系统中含有网络文件系统( NFS),find命令在该文件系统中同样有效,只你具有相应的权限. 在运行一个非常消耗资源的find命令时,很多人都倾向于把它放在后台执行,因为遍历一个大的文件系统

[转载]Linux LVM硬盘管理及LVM扩容

最近项目中一直在用Linux,其中涉及到了Linux的LVM,本来想自己写一篇关于LVM的文章,搜了一下,发现了一篇更好的,转载过来,也感谢作者gaojun 原文Linux LVM硬盘管理及LVM扩容 LVM磁盘管理 一.LVM简介... 1 二. LVM基本术语... 2 三. 安装LVM... 3 四. 创建和管理LVM... 4 1. 创建分区 2. 创建PV.. 6 3. 创建VG.. 7 4. 创建LV.. 9 5.LV格式化及挂载... 10 一.LVM简介 LVM是 Logical