作者godspeedlee (你,我可以)
看板LinuxDev
标题[问题] suid 的效果与预期不符
时间Wed Aug 28 14:24:37 2013
环境: ubuntu 11.04
首先我用帐号 styx, babe 各用 touch 产生了一个档案:
(放到 /tmp)
-rw-r----- styx styx maury
-rw-r----- babe babe mjb
接着在帐号 styx 下编译以下程式:
/*
step1. gcc setuid-test.c -o suidtest
step2. cd /tmp
step3. cp ~/suidtest .
*/
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main(void)
{
int uid, euid, fdmjb, fdmaury;
int egid;
uid = getuid();
euid = geteuid();
printf("uid = %d, euid = %d, egid = %d\n", uid, euid, getegid());
fdmjb = open("mjb", O_RDONLY);
fdmaury = open("maury", O_RDONLY);
printf("fdmjb = %d, fdmaury = %d\n", fdmjb, fdmaury);
setuid(uid);
printf("after setuid(%d): uid = %d, euid = %d, egid = %d\n", uid,
getuid(), geteuid(), getegid());
fdmjb = open("mjb", O_RDONLY);
fdmaury = open("maury", O_RDONLY);
printf("fdmjb = %d, fdmaury = %d\n", fdmjb, fdmaury);
setuid(euid);
printf("after setuid(%d): uid = %d, euid = %d, egid = %d\n", euid,
getuid(), geteuid(), getegid());
return 0;
}
然後改变他的 suid 并且复制到 /tmp :
chmod u+s suidtest
退出帐号 styx,改进入帐号 babe,执行 ./suidtest 得到结果:
注 styx, babe 的 id:
uid=1004(babe) gid=1005(babe) groups=1005(babe)
uid=1003(styx) gid=1004(styx) groups=1004(styx)
/tmp$ ./suidtest
uid = 1004, euid = 1003, egid = 1005
fdmjb = 3, fdmaury = 4
after setuid(1004): uid = 1004, euid = 1004, egid = 1005
fdmjb = 5, fdmaury = -1
after setuid(1003): uid = 1004, euid = 1003, egid = 1005
原本小弟预期第一次 open("mjb") == -1,因为 euid = styx,但是可能
因为 egid = babe 的缘故,造成 open("mjb") != -1,於是小弟又加上
sgid:
chmod g+s suidtest
再次执行,这次的结果更惊奇了:
uid = 1004, euid = 1003, egid = 1004
fdmjb = 3, fdmaury = 4
after setuid(1004): uid = 1004, euid = 1004, egid = 1004
fdmjb = 5, fdmaury = 6
after setuid(1003): uid = 1004, euid = 1003, egid = 1004
照道理说这次第一次 open("mjb") == -1 (因为 euid 与 egid 都是 styx),
怎麽会这样呢!?
最後没招了,只好:
chmod g-s suidtest (先退回原本的状态)
chmod g-r mjb (-rw-r----- 变为 -rw-------)
./suidtest
最後这才是我一开始预期的结果:
uid = 1004, euid = 1003, egid = 1005
fdmjb = -1, fdmaury = 3
after setuid(1004): uid = 1004, euid = 1004, egid = 1005
fdmjb = 4, fdmaury = -1
after setuid(1003): uid = 1004, euid = 1003, egid = 1005
请各位有空帮小弟看看,感恩!
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 171.25.193.131
1F:推 yvb:都是因为 groups 造成的, 但一般使用者又没权限 setgroups() 08/29 22:19
2F:→ yvb:另外, fdmaury = 6 那边因为你没使用 setgid(), 只用 setuid() 08/29 22:21
3F:→ godspeedlee:我有用 chgrp 指令强迫变更 mjb 的 group,就达到我要 09/01 04:29
4F:→ godspeedlee:的效果了 09/01 04:30
5F:→ godspeedlee:fdmaury = 6,那个暂且不论,一开始euid与egid都已经是 09/01 04:31
6F:→ godspeedlee:styx,为什麽还能开启babe的档案(mjb)呢? 09/01 04:33
7F:推 yvb:你打命令 "id" 时会列出三项: id, gid, 和 groups 09/01 22:56
8F:→ yvb:那个 groups 称做 supplementary groups 09/01 23:00
9F:→ yvb:只要存取的档案, gid出现在其中, 就视做以该gid进行存取, 09/01 23:02
10F:→ yvb:因此而可以存取 mjb. 09/01 23:03
11F:→ godspeedlee:uid也有出现,那为什麽拿掉mjb group r属性就不能存取 09/02 01:44
12F:→ godspeedlee:了呢? 09/02 01:44
13F:推 yvb:档案的存取权限判断: 09/02 21:02
14F:→ yvb:(1) 档案 uid 等於 euid ==> 取得 user 存取权限 09/02 21:03
15F:→ yvb:(2) 否则, 档案 gid 等於 egid, 或在 groups 中 ==> 09/02 21:05
16F:→ yvb: 取得 group 存取权限 09/02 21:05
17F:→ yvb:(3) 否则, 取得 others 存取权限. 09/02 21:05
18F:推 yvb:有 supplementary groups, 但没有 supplementary users. 09/02 21:09
19F:→ yvb:不过, 要达到你要的权限存取, 在 file mode 为 -rw-r---- 时, 09/02 21:11
20F:→ yvb:Linux 还是有别的方式: 要使用 setfsuid() 和 setfsgid(). 09/02 21:12
21F:→ godspeedlee:babe只有primary group,没有supplementary group 09/07 16:10
22F:→ godspeedlee:还是说supplementary包含了primary group 09/07 16:10
23F:推 yvb:不清楚是否有文件规范是否 supplementary 包含 primary group, 09/09 19:41
24F:→ yvb:但目前所使用的 login 程式, 都会叫用 initgroup(), 09/09 19:42
25F:→ yvb:将 primary group 设进 supplementary. 09/09 19:43
26F:→ yvb:更正, initgroups(), 09/09 19:44
27F:→ godspeedlee:谢谢,查了一下UNP,的确是如此 09/12 13:38