我正在使用Ubuntu 12.04(64位)进行一些关于Linux权限的实验。
我创建了以下程序。
#include<stdio.h>
#include <unistd.h>
main(){
printf("euid=%4d uid=%4d egid=%4d gid=%4d\n", geteuid(), getuid(),getegid(),getgid());
system("id");
}
我将其可执行文件设置为setuid / setgid文件:
-rws--s--x 1 root root 8638 Apr 28 02:00 pt*
当从非特权用户运行时,我得到输出:
euid= 0 uid=1001 egid= 0 gid=1001
uid=1001(test1) gid=1001(test1) euid=0(root) egid=0(root) groups=0(root),1001(test1)
我希望在使用system()之后系统调用root权限会被删除(这就是为什么shellcodes通常使用execv()而不是system()),但事实并非如此。< / p>
你能解释一下为什么吗?
谢谢。
答案 0 :(得分:1)
system()
不会删除(或添加或更改)任何权限。没有记录这样做,并且应该没有关于它的实现或使用的任何信息表明它确实如此。我不确定你为什么会这么做。
我认为“shellcodes”(恶意漏洞利用代码)更喜欢execv()
,原因如下:
system()
的功能是分叉一个新进程,用给定的命令行生成一个shell,然后等待它完成。 shellcode不需要派生进程并等待它,并且他们不需要引入额外的shell来解析命令行。execv(2)
是系统调用,而system(3)
是库函数。从外部引入的代码需要正确地猜测库函数的实现所在的地址以便调用它。但是为了调用系统调用,他们只需要系统调用号并调用正确的魔术(特定于平台的)机器指令来陷阱到内核。答案 1 :(得分:0)
system(id)
在内部作为 /bin/sh -c id
执行。
如果从 setuid 二进制文件(对于 bash 版本 >=2 )执行,这将删除提升的权限。
带有额外 /bin/sh -c -p id
的 -p
调用将维持提升的权限,但 system()
调用没有该标志。
那么,如何解决这个问题?在 libc 中使用 execv()
调用(不是 execv() 系统调用) - 如果您有系统的目录访问权限 - 您可以设法创建一个二进制文件来执行需要提升权限的任务,并使用 execv() 执行它