exec执行的程序权限问题

我用c语言封装了一条cat /etc/shadow的命令,设置程序的的suid位并把它的属主设为root,为什么以普通用户执行时,还是不能访问/etc/shadow?难道是exec执行新程序时不继承suid属性吗?

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

int main(){
    printf("uid is %d\n", getuid());
    printf("euid is %d\n", geteuid());
    execlp("/bin/sh", "sh", "-c","echo $UID $EUID;/bin/cat /etc/shadow", (char*)NULL);
    return 0;
}


➜  test gcc encapsulation.c -o encapsulation 
➜  test ./encapsulation 
uid is 1000
euid is 1000

/bin/cat: /etc/shadow: Permission denied
➜  test sudo chown root:root encapsulation
[sudo] password for inovker: 
➜  test ./encapsulation 
uid is 1000
euid is 1000

/bin/cat: /etc/shadow: Permission denied
➜  test sudo chmod u+s encapsulation
➜  test ./encapsulation 
uid is 1000
euid is 0

/bin/cat: /etc/shadow: Permission denied
➜  test sudo ./encapsulation 
uid is 0
euid is 0

root:!:17655:0:99999:7:::
daemon:*:17647:0:99999:7:::
bin:*:17647:0:99999:7:::
sys:*:17647:0:99999:7:::
sync:*:17647:0:99999:7:::
games:*:17647:0:99999:7:::
man:*:17647:0:99999:7:::
...
阅读 4.4k
2 个回答

出于安全原因,bash是会检查euid和uid的,发现不一样就会切换回去,所以会出现Permission denied。

具体实现可以看bash代码里的uidgetdisable_priv_mode

解决方法是用bash的-p,打开特权模式。

execlp("/bin/sh", "sh", "-p", "-c","echo $UID $EUID;/bin/cat /etc/shadow", (char*)NULL);

或者直接不用bash,直接调用cat。

suid只对二进制可执行程序有效,如果你把编译过后的encapsulation设置了4755权限,那么应该是直接./encapsulation执行有效

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题