使用 SETUID 时,`/proc/PID/status` 中的 eUID 错误

使用 SETUID 时,`/proc/PID/status` 中的 eUID 错误

在进行兵棋挑战时,我遇到了权限问题。提供的信息/proc/PID/status不符合应授予进程的权限。

我是用户user1。我应该使用一个 SETUID 程序:

-r-sr-x---  1 user2 user1       6297 Jun 20  2013 program

所以它应该以 user2 的有效 UID 执行。

我在启动后暂时停止该程序,以防止其终止:

~/program "test" &
PID=$!
kill -SIGSTOP $PID
echo $PID

然后,我cat /proc/$PID/status,我看到:

Uid:    1003    1003    1003    1003
Gid:    1003    1003    1003    1003

ID 是:

$ id user1
uid=1003(user1) gid=1003(user1) groups=1003(user1)
$ id user2
uid=1035(user2) gid=1035(user2) groups=1035(user2),1003(user1)

给定手册(man 5 proc),/proc/$PID/status应给出Uid, Gid: Real, effective, saved set, and filesystem UIDs (GIDs).

但在这里,该进程的有效ID是user1,而它应该具有 user2 的有效 ID

我想这可能是因为我太早停止了程序,所以我尝试附加gdb到它,并继续执行,直到它实际执行main函数program(给出了源)中的代码,但给出的有效UID/proc/$PID/status仍然是user1 而不是 user2。

我错过了什么吗?

编辑:删除挑战的来源,我可能无权发布它。

答案1

这是因为你太早了,如果你等到 UID 更改,那么你的进程就会以user2.这对我有用:

./program "test" &
PID=$!
sleep 0.0005
kill -SIGSTOP $PID
grep ^Uid /proc/$PID/status

另一种尝试是添加延迟并在睡眠期间usleep()发送后者。SIGSTOP然后程序以user2有效的 uid 运行。您可以检查这一点,但无需附加gdbstrace。最有可能的是某种 linux 内核内部的问题,该进程需要一些时间来更改 UID。

当从终端运行进程时,execve()系统调用被调用;从联机帮助页:

如果在 filename [...] 指向的程序文件上设置了 set-user-ID 位,并且调用进程没有被跟踪,则调用进程的有效用户 ID 将更改为该程序所有者的用户 ID。程序文件。

当您附加gdb到进程时,您将看不到 的 uid user2,因为您正在ptraceing 该进程,如上面的手册页中所述。或者你可以附加到一个sudo进程并获得 root 权限。

然而,这个程序永远不会出现分段错误 ( SIGSEGV) ,除非您使用kill -SIGSEGV $PID.如果你的程序得到一个SIGSEGV例程launch_debugger()被调用。这将调用 agdb并作为参数只是您的program二进制文件,不带任何参数,这将替换当前正在运行的进程。因此,在调试器中将拥有 的权限user2,因此您可以在其中执行您想要的操作,并user2具有 的权限。

例如,您可以在内部执行以下操作gdb

(gdb) file bash
Reading symbols from /bin/bash...(no debugging symbols found)...done.
(gdb) run
Starting program: /bin/bash
user2@host:~$ id
uid=1035(user2) gid=1003(user1) groups=1035(user2),1003(user1)

现在,考虑具有 setuid 位的相同二进制文件,并且所有者是 root。

答案2

程序是否在支持setuid文件位 ( mount -o nosuid) 的文件系统上运行?

getuid()如果我正在调试这个,我会在程序启动时打印和的输出geteuid(),以查看该setuid位是否得到遵守。

相关内容