简体   繁体   English

使用 setuid 调试 setuid 程序/“权限被拒绝”

[英]Debugging a setuid program / "Permission denied" with setuid

This is actually a three-part question, which I'll explain below, but the questions are:这实际上是一个三部分的问题,我将在下面解释,但问题是:

  • Using gdb, how can I run part of a program with root authority, and the rest with normal?使用gdb,我如何才能以root权限运行程序的一部分,而其余部分以正常方式运行?
  • Why would I get "permission denied" using mkstemp to create a file in /tmp in a setuid (to root) program?为什么在 setuid(到 root)程序中使用 mkstemp 在 /tmp 中创建文件时会得到“权限被拒绝”?
  • Why would "sudo program_name" perform any differently from just./program_name with setuid to root?为什么“sudo program_name”的执行方式与 setuid 为 root 的 just./program_name 有任何不同?

I have a C program running on Linux (multiple distributions) that normally is run by a user with normal privileges, but some parts of the program must run with root authority.我有一个在 Linux(多个发行版)上运行的 C 程序,通常由具有普通权限的用户运行,但程序的某些部分必须以 root 权限运行。 For this, I have used the set-UID flag, and that works fine, as far as it goes.为此,我使用了 set-UID 标志,就目前而言,它工作正常。

However, now I would like to debug the program with normal user authority, and I find I have a catch-22.但是,现在我想用普通用户权限调试程序,我发现我有一个 catch-22。 I have just added a function to create a temporary file (/tmp/my_name-XXXXXX), and that function is called from many points within the program.我刚刚添加了一个函数来创建一个临时文件 (/tmp/my_name-XXXXXX),并且从程序中的许多点调用该函数。 For whatever reason, this function issues the following message when running:无论出于何种原因,此函数在运行时都会发出以下消息:

sh: /tmp/my_name-hhnNuM: Permission denied

(of course, the actual name varies.) And yet, the program is able to execute raw socket function that I absolutely know cannot be done by users other than root. (当然,实际名称会有所不同。)然而,该程序能够执行原始套接字功能,我绝对知道除了 root 以外的用户不能执行的操作。 (If I remove the setuid flag, the program fails miserably.) (如果我删除 setuid 标志,程序就会失败。)

If I run this program via gdb without sudo, it dies on the raw socket stuff (since gdb apparently doesn't --or probably cannot-- honor the setuid flag on the program).如果我在没有 sudo 的情况下通过 gdb 运行这个程序,它会死于原始套接字的东西(因为 gdb 显然不——或者可能不能——遵守程序上的 setuid 标志)。 If I run it under "sudo gdb" then everything works fine.如果我在“sudo gdb”下运行它,那么一切正常。 If I run it as "sudo./my_name, everything works fine.如果我以“sudo./my_name”运行它,一切正常。

Here is the ls -l output for that program:这是该程序的 ls -l 输出:

-rwsr-xr-x 1 root root 48222 Jun 23 08:14 my_name

So my questions, in no particular order:所以我的问题,没有特别的顺序:

  • (How) can I run different parts of a program with different effective UID under gdb? (如何)我可以在 gdb 下运行具有不同有效 UID 的程序的不同部分?
  • Why is "sudo./program" different from "./program" when./program has set-uid to root?为什么“sudo./program”与“./program”不同,当./program 将 uid 设置为 root 时?
  • Why would mkstemp fail when called by a normal user in a setuid (to root) program?为什么 mkstemp 在 setuid(到 root)程序中被普通用户调用时会失败?

1 The only way to debug the setuid application properly under gdb is to run gdb as root. 1在 gdb 下正确调试 setuid 应用程序的唯一方法是以 root 身份运行 gdb。 The most sensible way to do this for a setuid application is to attach to the application once it starts.对 setuid 应用程序执行此操作的最明智方法是在应用程序启动后附加到该应用程序。 A quick trick to doing this is to add a line into the setuid application:一个快速的技巧是在 setuid 应用程序中添加一行:

kill(getpid(), SIGSTOP);

This causes it to stop at this point, then you attach gdb using:这会导致它在此时停止,然后使用以下命令附加 gdb:

sudo gdb <application> <pid>

Then you are attached to the application and can debug it as normal.然后您连接到应用程序并可以正常调试它。

2 sudo changes the rules as it allows a variety of items from the current user's environment to be exported into the root user's environment. 2 sudo 更改规则,因为它允许将当前用户环境中的各种项目导出到根用户环境中。 This is wholly dependent on the current sudo configuration and can leave you with a very different environment than a setuid application which is why you need to rely on tricks like stopping the application and then attaching to it at run time.这完全取决于当前的 sudo 配置,并且会给您留下一个与 setuid 应用程序截然不同的环境,这就是为什么您需要依赖一些技巧,例如停止应用程序,然后在运行时附加到它。

Additionally there may be logic in the application to detect if it's running in a setuid environment which is not actually the case when run under sudo - remember that sudo sets all the process's id fields (real uid, effective uid and saved uid) to the same value, which setuid doesn't (the real uid is still that of the original caller).此外,应用程序中可能有逻辑来检测它是否在 setuid 环境中运行,而在 sudo 下运行时实际上并非如此 - 请记住 sudo 将所有进程的 id 字段(真实 uid、有效 uid 和保存的 uid)设置为相同值,setuid 没有(真正的 uid 仍然是原始调用者的 uid)。 You can use the getresuid() call to determine the state of the three variables.您可以使用getresuid()调用来确定三个变量的状态。

3 The thing is that the Permission Denied message has a prefix of sh: ; 3问题是Permission Denied消息的前缀为sh: ; this seems to imply that another sub-process is being executed that is trying to access the file.这似乎暗示正在执行另一个试图访问该文件的子进程。 After you've invoked mkstemp, you may want to loosen up the permission to read the file so that the subprocess is able to read the file.调用 mkstemp 后,您可能希望放宽读取文件的权限,以便子进程能够读取文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM