【问题标题】:How to get shell_exec to run on IIS 6.0如何让 shell_exec 在 IIS 6.0 上运行
【发布时间】:2010-02-19 04:17:51
【问题描述】:

问题

我有一个 PHP 脚本,它使用 shell_exec 运行 pdf 到文本转换器。为了简化问题,我创建了一个简短的脚本,它使用shell_exec 来回显dir 命令的输出。

<?php
$cmd = 'C:\\WINDOWS\\system32\\cmd.exe /c ';
echo shell_exec($cmd.' dir');
?>

当我在我的 Apache 服务器上运行它时,一切都按预期工作。当我切换到 IIS 时,就好像完全跳过了这行:没有错误、没有输出、没有日志、什么都没有。

不幸的是,我需要使用 IIS,因为我要针对 Active Directory 对我的用户进行身份验证。


这是我迄今为止尝试过的:

  • 通过cmd.exe /c发出命令而不是直接发出命令
  • 在“C:\WINDOWS\system32\cmd.exe”上将Read &amp; Execute 权限授予SERVICE
  • 在“C:\WINDOWS\system32\cmd.exe”上将Read &amp; Execute 权限授予NETWORK SERVICE
  • 在“C:\WINDOWS\system32\cmd.exe”上将Read &amp; Execute 权限授予IUSR_MACHINENAME
  • 在“C:\WINDOWS\system32\cmd.exe”上将Read &amp; Execute 授予Everyone 的权限(别担心,它不会长时间保持这种状态,哈哈)
  • 将 PHP 作为 ASAPI 模块运行
    • 这是我的标准配置
  • 将 PHP 作为 CGI 扩展运行
    • 这不起作用,我收到一个错误:CGI Error The specified CGI application misbehaved by not returning a complete set of HTTP headers.
  • 在 IIS 管理器中,将您网站上的 Execute Permissions 设置为 Scripts and Executables
  • 在脚本中添加了 html 标记和其他 php 函数,以查看是否得到处理;确实如此。就好像 shell_exec 位被跳过了一样。

非常感谢您查看这个问题,我现在正在解决这个问题

干杯, 伊恩


更新 1

我真的不想这样做,但作为权宜之计,直到我找到合适的解决方案,我正在 Web 服务器上运行 Apache(它可以正常运行 shell_exec)并通过 cURL 调用我的 apache 脚本。这很丑陋,但它有效:)。


更新 2

我开始认为这不是 IIS 或权限本身的问题,而是我们网络上的某些策略的结果 - 尽管我无法想象是什么。左派有什么想法吗?

【问题讨论】:

  • 这可能是有史以来最愚蠢的建议,但如果这是您的整个脚本,并且当您从 IIS 请求时查看源代码,您真的看到 PHP 源代码吗?尝试在 PHP 文件的开始标记之前添加

    HERE!

    和 echo '

    and here!

    ';在开始 PHP 标记之后。只是为了确保正确解析 PHP。 :-)
  • 感谢 janmoesen 的建议,不是一个愚蠢的建议,很好的解决问题!事实上,我已经尝试过了,并且确实从其他所有内容中获得了输出。就好像整个脚本都在运行,只是方便地跳过了shell_exec() 部分。

标签: php windows iis shell-exec


【解决方案1】:

以下是确定需要授予哪些用户权限的更系统的方法

确认您在 C:\WINDOWS\SYSTEM32(或更一般的 %systemroot%\system32)中有以下可执行文件

cmd.exe  
whoami.exe  

检查这些可执行文件的当前 ACL

c:\windows\system32> cacls cmd.exe  
c:\windows\system32> cacls whoami.exe  

如果用户“Everyone”未被授予读取 (R) 访问权限,则临时授予如下

c:\windows\system32> cacls cmd.exe /E /G everyone:R  
c:\windows\system32> cacls whoami.exe /E /G everyone:R  

使用以下内容创建 whoami.php

<?php  
$output = shell_exec("whoami");  
echo "<pre>$output</pre>";  
?>  

在网络浏览器上加载 whoami.php 并记下显示的用户名,例如就我而言,它显示了

ct29296\iusr_template

如果必须在上述步骤中添加,请撤销“所有人”权限

c:\windows\system32> cacls cmd.exe /E /R everyone  
c:\windows\system32> cacls whoami.exe /E /R everyone  

仅将步骤 5 中找到的具有读取+执行权限 (R) 的用户名授予 cmd.exe

c:\windows\system32> cacls cmd.exe /E /G ct29296\iusr_template:R  

请记住为您自己的系统使用正确的用户名。

见:http://www.myfaqbase.com/index.php?q=php+shell_exec&ul=0&show=f

【讨论】:

    【解决方案2】:

    这里有几点:

    • 关于 PHP 跳过 shell_exec 函数,请确保 PHP 没有在安全模式下运行。来自 PHP 手册 - 在 shell_exe page:

    注意:当 PHP 在安全模式下运行时,此功能被禁用。

    这似乎也是在 Windows 中从 PHP 执行 shell 命令的一个众所周知的问题。共识似乎是让它工作的最好方法是让 PHP 在 FastCGI 模式下运行(我知道你已经尝试过这个并且说你无法让它工作 - 因此我的第二点)。你可能会发现这个Microsoft IIS Forum thread 很有帮助。


    • 现在,就必须在 Windows 上运行 PHP 以针对 Active Directory 进行身份验证而言 - 您不必这样做!

    Apache 通过mod_auth_ldap 提供LDAP 身份验证。而 PHP 通过以下函数提供 LDAP 支持:

    Active Directory 是 LDAP 的一种实现。因此,您可以使用任何 LDAP 客户端对 Active Directory 执行身份验证。

    附:您可以使用 Apache mod_auth_ldap 或 PHP LDAP 函数 - 您不需要同时使用这两个函数来完成这项工作。 Apache mod_auth_ldap 在 HTTP 协议级别工作,而 PHP LDAP 函数让您可以更好地控制身份验证和授权过程。

    【讨论】:

    • 谢谢 Miky,我一定会调查的。至于运行 IIS 而不是 Apache;这不仅仅是身份验证,我们几乎所有基于 Web 的基础架构都在 IIS 上运行,因此迁移到 Apache 将是一个非常大胆的举动——而且我无权做出这样的举动。我确实使用 PHP 的 ldap 功能在应用程序上进行身份验证,这更多是因为 IIS 将以经过身份验证的用户身份运行 - 允许使用和修改网络上属于该人的文件。
    【解决方案3】:

    几个笔记

    如果你想直接执行一个 .exe,你可以使用 proc_open() 和 $other_options=array('bypass_shell'=>TRUE)

    procmon.exe (sysinternals) 也是你研究这类问题时最好的朋友

    【讨论】:

      【解决方案4】:

      我会对运行 IIS 的用户说 Read &amp; Execute 权限(如果那不是 IUSR_MACHINENAME)

      【讨论】:

      • 感谢关键。运行 IIS 的用户实际上是 IUSR_MACHINENAME。出于绝望,我还尝试在每个人上设置 Read & Execute 以查看是否是权限问题;没有骰子。谢谢你提醒我把这个放在我的尝试清单中:)
      【解决方案5】:

      不幸的是,我需要使用 IIS,因为我要针对 Active Directory 对我的用户进行身份验证。

      将应用程序基于 IIS 的前提是有缺陷的。没有什么可以阻止您使用 Apache 执行此操作。事实上,您甚至不需要在 MS-Windows 操作系统上运行它。

      请谷歌了解如何设置所有这些。

      请注意,对于可能使用 NTLM 的 IIS 和本地客户端,安全策略会被抛到窗外。 IIS 处理程序线程可以使用 NTLM MSIE 客户端的凭据运行。或不。调试这些东西会让你发疯的!

      C.

      【讨论】:

      • 正如我对 Miky D 所做的评论一样,从 IIS 迁移到 Apache 对我来说并不是一个真正的选择,因为我们的组织几乎所有基于 Web 的基础架构都使用它。 WIMP 在所有其他方面都运行良好,因此彻底改造我们的 Web 基础设施来解决一个问题对我们来说是不合理的。但感谢您的洞察力和时间。
      【解决方案6】:

      我使用 READ & EXECUTE, READ 将用户 NETWORK SERVICE 添加到我的应用程序的可执行文件所在的目录中。自从这个改变,问题就消失了。 尽管如此,还需要将 READ & EXECUTE、READ for IUSR_ 的权限授予 cmd.exe。

      我从这里得到的解决方案http://forums.iis.net/t/1147892.aspx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-01
        • 2010-09-05
        • 1970-01-01
        • 1970-01-01
        • 2023-01-18
        • 2011-01-01
        • 1970-01-01
        相关资源
        最近更新 更多