cap_setuid能力分析
cap_setuid: 允许普通用户使用setuid函数
让我们通过下面的例子了解
cap_setuid
- 创建用户
test,用于测试
$ adduser test
root身份创建文件/tmp/ddd
$ whoami
root
$ echo "123" > /tmp/ddd
$ chmod 640 /tmp/ddd
- 编写一个
c程序来使用setuid()函数
函数说明:setuid()用来重新设置执行目前进程的用户识别码。
不过, 要让此函数有作用, 其有效的用户识别码必须为0(root). 在Linux下, 当root使用setuid()来变换成其他用户识别码时, root权限会被抛弃, 完全转换成该用户身份。
也就是说, 该进程往后将不再具有可setuid()的权利, 如果只是想暂时抛弃root权限, 稍后想重新取回权限, 则必须使用seteuid().
$ su - test
$ tee ~/demo.c <<EOF
#include <unistd.h>
int main ()
{
gid_t uid = 0;
setuid(uid);
system("/bin/cat /tmp/ddd");
return 0;
}
EOF
- 以
test用户执行demo程序
$ whoami
test
$ gcc demo.c -o demo
$ ./demo
/bin/cat: /tmp/ddd: Permission denied
显然默认情况下不具备调用setuid()函数的权限
- 切换
root用户,授予/home/test/demo以CAP_SETUID能力
$ whoami
root
$ setcap cap_setuid=eip /home/test/demo
- 切换至
test用户再次执行/home/test/demo
$ whoami
test
$ /home/test/demo
123
此时test用户通过执行demo程序,拥有了读取/tmp/ddd文件内容的权限,而test用户依旧不具备该权限:
$ whoami
test
$ cat /tmp/ddd
cat: /tmp/ddd: Permission denied
这是因为通过对/home/test/demo程序授予了cap_setuid的能力,允许程序可以使用setuid()函数。而通过setuid()函数,/home/test/demo修改了进程属主为root(修改前为test)
进而拥有了对/tmp/ddd文件的读权限。
清理测试用例
$ userdel -r test