【问题标题】:Switch to Linux root account in executing C++ binary with password, POSSIBLE?在使用密码执行 C++ 二进制文件时切换到 Linux root 帐户,可能吗?
【发布时间】:2016-08-02 15:41:52
【问题描述】:

我正在尝试将一些文件从非常低(几乎没有特权)的用户复制到 root 用户。我需要允许有权访问低帐户的人将一些文件复制到更高帐户。我曾考虑过使用 bin/Bash 脚本,但我不想查看文件中的任何密码。

我决定创建一个 C++ 应用程序,其中包含我想传递给 su/setuid 命令的帐户密码。我知道密码可以在二进制文件中查看,但不是问题。密码不是纯文本就足够了。

我的问题是我无法弄清楚如何以用户身份“登录”,我需要更新在该帐户中运行的服务的文件。我有用户帐户名 localadmin 和该帐户的密码。但是如何将这些传递给 Linux 以将文件从 C++ 应用程序复制到 localadmin 帐户主/子目录?

我在 C++ 中尝试过:

system("su localadmin"); // 这里提示输入密码,但不知道如何传递密码。

setuid(0); // 同样,我在哪里传递密码以获得帐户权限?我得到的只是“不允许的操作”。

如果这是一个简单的问题,我深表歉意。我只是想以 localadmin 身份运行命令并完成。

【问题讨论】:

  • 在你的程序中记录 root 密码是一个糟糕的主意,有几个原因,至少包括 (1) 可以从二进制文件中提取密码,以及 (2) 如果 root 用户程序会中断密码已更改。这就是为什么必须为非特权用户提供提升权限的程序通常设置为 setuid-root 的原因,这是他们的所有权和模式的函数,而不是他们的实现。
  • 听起来像XY problem。带有 ACL(访问控制列表)的公共目录如何为非特权用户提供仅插入权限?
  • @JohnBollinger,感谢您的回复,非常感谢。我确实了解将密码嵌入二进制文件的后果,但这不是问题。我给这个的人没有那种知识。我只需要这个二进制文件以 root 用户身份执行所有命令。我希望通过给他们一个二进制文件来实现这一点。
  • @JayMa:你错过了分数!如果密码改变了怎么办?恶意软件可以轻松扫描二进制文件以获取密码。无论您需要,您的方法都是错误的!没有任何借口!
  • @Olaf,感谢您提供的信息。我明白这一切。这是我需要执行的一次性更新。我可以控制 root 密码,所以没有人会更改它,尤其是在远程系统上。我确实需要它按照所说的执行。我不知道有任何其他方法可以从无权访问 root 帐户的帐户复制文件,而所有操作都必须从低级别帐户完成。

标签: c++ linux shell setuid


【解决方案1】:

您无需提供密码。使您的应用程序 setuid 为 root,以便它以 root 权限运行。

使用 root 权限,执行以下操作:

chown root {program}
chmod 4755 {program}

现在您的可执行文件归根用户所有,并且设置了 setuid 位。因此,当任何用户运行它时,它都会以 root 身份运行。然后程序就可以做它需要做的事情了。

在创建 setuid 根程序时,需要特别注意确保所有输入都经过适当的清理,以防止缓冲区溢出或格式字符串漏洞。此外,如果您的程序不仅仅是调用另一个程序,它应该在开始使用 seteuid({callers_uid}) 时放弃权限,在需要时使用 seteuid(0) 提升权限,并在完成后再次将其放下。

如果您只希望特定用户运行此程序,您可以使用sudo 而不是将程序设置为 root。 root 用户需要更新 /etc/sudoers 文件并为相关用户和程序添加一个条目,并包含一个不需要密码的选项。

例如:

user_name ALL = (root) NOPASSWD:program_to_run

然后用户就可以运行了:

sudo program_to_run

然后这个用户(并且只有这个用户)可以以root权限运行程序来执行它需要做的任何事情。

【讨论】:

  • 你打败了我。但是,添加一些关于 setuid-root 程序可能存在的潜在安全问题的评论会很有用。
  • 感谢您的信息,但我只是将此二进制文件提供给没有 linux 经验且没有低帐户权限的人执行。我需要它来获得 root 权限以将文件复制到 root 帐户子目录。我希望在一个二进制可执行文件中完成这一切。
  • @JayMa:如果他们没有权限,也不知道su获取他们的密码,那么他们应该如何获得权限?如果您有权限,那么您可以在目标机器上创建 setuid 程序并告诉他们。
  • @JayMa 如果您对用户所在的系统拥有 root 权限(或知道谁拥有),那么您可以使用适当的权限设置可执行文件,并让用户知道它在哪里。
  • 如果您知道 root 密码,只需登录系统,在其中部署您的二进制文件,并为其提供 setuidchmod(以及 root 所有权)。您还需要将其执行权限授予所有人(或者您的用户所属的某个组)然后您的目标用户可以执行此二进制文件并在其执行期间成为 root,而无需输入任何密码或您的二进制源代码需要他们。
【解决方案2】:

我认为您误解了setuid 通常是如何工作的。无需在您的应用程序中存储任何类型的密码:您只需像往常一样对其进行编码以执行您需要执行的操作,就像您是 root 一样。获得二进制文件(由 root 拥有)后,您可以使用chmod 将其setuid 权限设置为二进制文件的属性。

在此之后,以任何允许执行的用户身份执行二进制文件后,它将提升他们为 root 以执行二进制文件的代码。无需为此提供密码。

请注意,您需要小心setuid 程序:它们可能会由于其root 权限而导致安全问题。最好让它们尽可能简单和集中,尽可能减少实际需要 root 权限的工作,让其他非setuid 程序去做任何非特权工作,以尽量减少潜在的可利用错误。

【讨论】:

  • OP 建议使用setuid() 函数,他的程序如果没有权限就无法成功。既然重点是用户没有有特权,那不会满足他的需要,但这并不是对文件模式意义上的setuid的误解。
  • 感谢您的信息,但我只是将此二进制文件提供给没有 linux 经验且没有低帐户权限的人执行。我需要它来获得 root 权限以将文件复制到 root 帐户子目录。我希望在一个二进制可执行文件中完成这一切。
  • 在二进制文件上设置setuid 属性后,任何人都可以在没有特权的情况下执行它。二进制是具有属性的,而不是需要使用它的用户。想想 linux passwd 程序是如何工作的:任何人都可以使用它来更改他们的密码,但它实际上需要成为 root 才能这样做。这无需用户输入 root 密码或具有任何特殊权限即可实现:拥有特权的是 passwd 程序本身。
猜你喜欢
  • 2020-10-06
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
相关资源
最近更新 更多