如何获得似乎需要 root 权限才能通过 www-data 用户运行的简单脚本?

如何获得似乎需要 root 权限才能通过 www-data 用户运行的简单脚本?

我正在编写一个小型 Web 界面来控制 Debian(内核 2.6.32-5-686)上的 samba。我首先编写简单的脚本来添加用户、创建文件夹等。以 root 身份运行时它们工作得很好。然而,当使用其中一些通过网络(apache + php)运行时,php: shell_exec()它们不起作用。它们看起来像这样:

#!/bin/sh
#archive the userprofile
cp /home/samba/profile/$1 /home/samba/archive/$1
smbpasswd -LU $1 -x
userdel $1 
exit 0

我尝试使用 sudo 来运行脚本,但这似乎不起作用。我添加了这一行:(jupiter 是服务器名称)

%sudo jupiter=(ALL)NOPASSWD:/bin/<script>

到 /etc/sudoers 文件,给我的 www-data 用户 sudo 组,什么也没有。

然后我读了一些我应该读的地方chmod 4755chown脚本。还是没用。

此时我很好奇问题是什么,我将 STDERR 重定向到一个文件。我运行了一个小脚本,它将调用cpsmbpasswduserdel来删除用户并存档他的共享。所有调用都返回退出代码 1,据我所知,这表明某物出错。 STDERR 给了我一点线索:

userdel: cannot lock /etc/passwd; try again later.

这似乎是由一些 *.lock 文件引起的,但我的 /etc/ 文件夹中没有。

此时我有点沮丧,并尝试通过将 www-data 添加到根组来赋予其更多根权限。事情仍然没有进展。

到目前为止,对于我的进展,我不知道下一步该做什么。我的问题是:如何获得似乎需要 root 权限才能通过 www-data 用户运行的简单脚本?我认为这可能是 /etc/passwd 文件的问题,因为我可以想象只有 root 用户有权更改它。

答案1

我的回答只与该行有关

sudo jupiter=(ALL)NOPASSWD:/bin/<script>

使用此行,您允许用户以任何用户身份在主机上sudo运行,​​无需身份验证。我不认为你想要这个。/bin/<script>juptier

如果我理解正确的话,你希望用户以 rootwww-data身份执行/bin/<script>。在这种情况下,适当的行看起来像

www-data jupiter=(root) NOPASSWD:/bin/<script>

现在您可以通过调用以特权/bin/<script>方式www-data执行root

www-data:~ $ sudo /bin/<script>

或者通过shell_exec("sudo /bin/<script>")你的 php 脚本(我希望你关心安全问题)。

欲了解更多详情,请参阅man sudoers或在线版本sudoers.man。为了快速理解,我建议查看该EXAMPLES部分。

答案2

有几种不同的方法...

  • 如前所述使用 sudo
  • 使用 suEXEC 功能配置 Apache(可能不是 php 的选项?)
  • 使用一个小的 setuid 程序来调用您的代码
  • 还有更多...

最简单的可能是使用 sudo,这已经被描述过。

sudo 选项的快速总结:

  1. 确保 /etc/sudoers 没有“默认 requiretty”
  2. 将此行添加到该文件“apache ALL = NOPASSWD:/path/to/command”,这意味着“sudo /path/to/commandwhatever”如果作为apache调用,将以root身份运行。 (这假设您的 Web 服务器以 apache 用户身份运行。)

然而,如果你这样做,让我指出这一切的危险。任何可以访问您的页面的人都可以做任何它想做的事——因此,通过 userdel,他们可以删除用户(可能还有他们的所有文件),并且根据代码的编写方式,他们可能能够欺骗它让他们以 root 身份运行任意命令。

(现在,如果配置正确, sudo 可以限制它们可以执行的操作,正确编写的程序也可以(尽管编写安全的 setuid、CGI 和 php(像您一样使用 shell_exec() 的程序)可能很棘手)但 userdel 可以很漂亮本身具有破坏性。)

所以...如果你这样做,至少要确保 sudo (如果你使用 sudo)配置为仅运行绝对需要运行的命令,并确保你的页面不能被任何人访问 - - 例如,将其锁定在 Apache 中的密码后面,如果它位于互联网上而不是在公司防火墙后面,则要特别小心(但即便如此 - 不要相信防火墙会确保其安全。)还要确保不受信任的其他人无法在此主机上添加 php 或 CGI 程序,因为他们也可以在 /etc/sudoers 中使用该行。

由于您使用的是 php 的 shell_exec(),因此请非常小心代码提供给该命令的参数。如果你让用户把他想要的任何东西放在那里,他就可以让它做任何事情。

假设您的命令是“userdel $user”并且$user直接来自该网页的用户。如果用户=“foo;重新启动”。如果以 root 身份运行...您的计算机将重新启动。但即使不以 root 身份运行,他也可以以 apache 用户身份运行代码,尝试进入机器。

也就是说,如何正确清理您的输入是一个比这个简单答案真正允许的更长的主题——我并不是真的试图涵盖整个主题,只是简单地触及它。

相关内容