【问题标题】:PHP sudo in shell_execshell_exec 中的 PHP sudo
【发布时间】:2011-08-04 21:50:36
【问题描述】:

我想用 shell_exec 以 root 身份执行命令。现在我知道这很危险,但请相信我,您需要使用 MOD_AUTH 登录并拥有访问此页面的正确权限。它是安全的。我怎样才能完成这项工作?

【问题讨论】:

  • 无论你做什么,都不是secure..

标签: php shell root sudo shell-exec


【解决方案1】:

问题不在于 您的 页面是否安全,问题在于赋予 php 页面运行某些 sudo 命令的能力会将其提供给 all em> 页面,包括服务器上任何站点上任何不安全页面上的任何注入代码。

也就是说,最好制作一个只执行需要执行的一项工作的包装脚本,然后让 http 用户以 sudo 的形式访问该 ONE 命令

http  ALL=(ALL) NOPASSWD:/user/local/bin/your_wrapper_script.sh

【讨论】:

  • 我忘了提到一个不带参数的包装器!制作不接受任何参数的包装脚本会减少攻击面。如果使用某些参数执行,某些程序将能够被操纵来做坏事。使用包装器可以让您以更可控的方式启动程序。
  • 所有需要root权限的文件都位于/var/private-www/,只有root权限才能使用。是否可以让他们使用 sudo?我试过http ALL=(ALL) NOPASSWD:/var/private-www/,但没用。
  • 或者只是提到在您传递的任何参数上使用:php.net/manual/en/function.escapeshellcmd.php
  • 没有。像这样对它们进行通配符会引入更多的安全问题。一一列出。另外,如果你真的有不止一个,我认为你需要重新考虑你的整个架构。听起来你应该有更好的方法来做到这一点,但由于我们不知道你的情况,我们不能确切地建议一个。想到的唯一技巧是让你的包装脚本根据参数决定执行什么,但你又一次引入了安全问题。
  • @kevin,也请务必将http 更改为运行它的实际用户(如果不是http),仅供参考。
【解决方案2】:

您可以使用最新的 SVN 版本的phpseclib, a pure PHP SSH implementation 来执行此操作。例如。

<?php
include('Net/SSH2.php');

$ssh = new Net_SSH2('www.domain.tld');
$ssh->login('username', 'password');

$ssh->read('[prompt]');
$ssh->write("sudo command\n");
$ssh->read('Password:');
$ssh->write("Password\n");
echo $ssh->read('[prompt]');
?>

【讨论】:

  • 喜欢这个解决方案:),我会用那个。
【解决方案3】:

Definitley 不建议使用。但是,您需要查看编辑 sudoers 文件并添加用户 php is running 作为您需要运行的命令的 NOPASSWD。这将只允许他在不输入密码的情况下sudo 该命令。

如果您需要更多命令,请添加更多命令。 Sudoers Configuration 我知道论坛/帖子是基于 debian 的,但 sudo 并不是严格意义上的 debian,这应该可以帮助您解决需要放置的 sudo 配置值。

【讨论】:

    【解决方案4】:

    我刚刚在 Google 上搜索了 php sudo shell_exec,这是排名第一的匹配项:

    http://www.php.net/manual/en/function.shell-exec.php#101440

    ilya 在 linemedia dot ru 16-Dec-2010 04:36
    sudo 可以在不将 pass 存储在文件中的情况下执行

    system('echo "PASS" | sudo -u root -S COMMAND');
    

    【讨论】:

    • 谢谢,但我发现这不起作用?我试过system('echo "mypass" | sudo -u root -S mkdir /testdir');,但在我执行脚本后/testdir不存在。
    • @Kevin:您可能必须将COMMAND 用引号括起来,或者(如果我对*nix 的了解是正确的)您不能在/ 中创建文件夹。
    • 您不能也不应该将字符串通过管道传输到交互式密码提示中
    • 这确实帮助了我,但我确实需要像这样更改它:system('echo "PASS" | echo sudo -u root -S COMMAND');
    【解决方案5】:
    $aux=echo "admin-pass" | your command;
    echo $aux;
    

    /************************************ ************例子************* *******************************/

    运行一个名为my_perl_script.pl的Perl脚本:

    $aux=echo "admin-pass" | sudo -u root -S perl /path-to-the-script/my-perl-script.pl;
    echo $aux;
    

    【讨论】:

      【解决方案6】:

      最好的方法:

      $descriptorSpec = array(
          0 => STDIN,
          1 => STDOUT,
          2 => STDERR,
      );
      
      if (posix_getuid() === 0) {
          echo "Root\n";
      } else {
          echo "No root\n";
          $command = 'sudo ' . PHP_BINARY . ' ' . implode(' ', $_SERVER['argv']);
      
          $pipes = [];
          $process = proc_open($command, $descriptorSpec, $pipes);
          if (is_resource($process)) {
              proc_close($process);
          }
      }
      

      它再次运行相同的命令,带有 sudo 前缀。

      【讨论】:

        猜你喜欢
        • 2016-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多