TL;DR 例如,su 或 sudo 如何在没有 PAM 的情况下工作?
你好,
我想玩弄 suid 之类的东西, 我已经得到了 SUID 部分和 SUID 位 等等,但问题是它没有要求我 一个密码,因为我希望它询问密码 并发现 su 和 sudo 在源代码中相当混乱 我很困惑。
我查看了 setsuid() 和 getuid() 文档 似乎没有什么关于 密码验证。
如何实现密码认证 没有 PAM,我使用 sudo 没有 pam 它工作正常,su 和 pam,两者都工作 好吧,我很困惑如何让它发挥作用
这个 C++ 代码就是我现在所拥有的:
// a.cc //
#include <iostream>
#include <unistd.h>
#include <cerrno>
#include <cstring>
int main(int argc, char *argv[]) {
uid_t user = getuid();
if (setuid(0) == -1) {
std::cerr << strerror(errno) << '\n';
return 1;
}
system(argv[1]);
if (setuid(user) == -1) {
std::cerr << errno << '\n';
return 1;
}
return 0;
}
使用 GCC 进行编译后,文件名为 a.cc:
$ g++ a.cc -o a
并授予其执行和SUID权限并授予 所有权为root
$ sudo chown root:root ./a
$ sudo chmod 4555 ./a
它可以工作,但没有密码验证
$ ./a id
uid=0(root) gid=1000(ari) groups=1000(ari),5(tty),10(wheel),27(video),78(kvm),250(portage)
(ari是我的用户)
即使注销或运行
sudo -k
结束 sudo 超时它仍然可以在没有密码的情况下工作
身份验证。
感谢您的提前答复
首先,基础知识:每个进程都有一个用户 ID 和一个组 ID(我将忽略附加属性,例如附加组 ID)。
用户 ID 0 是 root。就这样,故事结束。
当你有一个用户ID为0的进程时,它是一个根进程。故事结束。
进程如何获取其用户 ID 0 并不重要。如果进程的 userid 为 0,则它是根进程,仅此而已。
当您完成设置 setuid 进程的动作时,
setuid(0)
本身,您就完成了。你是一个根进程。就是这样。没什么可说的了。
setsuid() 和 getuid() 文档,似乎没有 有关密码验证的任何信息。
正确。他们所做的只是调整/更新用户 ID。就是这样。没有什么更多的了。
su
和sudo
进程执行以下操作:
$ ls -al /bin/su /bin/sudo
-rwsr-xr-x. 1 root root 57504 Aug 17 04:59 /bin/su
---s--x--x. 1 root root 185440 Aug 7 13:17 /bin/sudo
你觉得这很熟悉吗?你手工制作的 setuid 程序的权限看起来与此相同,不是吗?
su
中的密码)情况,或 sudo
配置中可接受的匹配)。如果您不这样做,他们将终止且不会采取进一步行动。涉及 PAM 或其他身份验证框架的所有密码验证逻辑均由
su
和 sudo
进程本身实现。除非您提供可接受的身份验证凭据(无论它对 su
或 sudo
意味着什么),它们都会终止,并且不会发生进一步的操作。成功的身份验证会生成 shell 或执行的命令,但这是出于非常简单、基本的原因,su
和 sudo
程序本身使用 setuid(权限位和系统调用)来获取 root 权限,如下所示第一笔生意。