问题
我有一个 PHP 脚本,它使用 shell_exec
来运行 pdf 到文本转换器。为了简化问题,我创建了一个简短的脚本,它使用 shell_exec
来回显 dir
命令的输出。
<?php
$cmd = 'C:\\WINDOWS\\system32\\cmd.exe /c ';
echo shell_exec($cmd.' dir');
?>
当我在 Apache 服务器上运行它时,一切都按预期运行。当我切换到 IIS 时,就好像该行被完全跳过:没有错误、没有输出、没有日志、什么都没有。
不幸的是,我需要使用 IIS,因为我要根据活动目录对我的用户进行身份验证。
这是我迄今为止尝试过的:
- 通过
cmd.exe /c
发出命令,而不是直接发出
- 它对“C:\WINDOWS\system32\cmd.exe”上的
SERVICE
执行 权限
- 给予
Read &对“C:\WINDOWS\system32\cmd.exe”上的NETWORK SERVICE
执行
权限
- 给予
读取&对“C:\WINDOWS\system32\cmd.exe”上的 IUSR_MACHINENAME
执行
权限
- 给予
Read &对“C:\WINDOWS\system32\cmd.exe”上的Everyone
执行
权限(别担心,它不会保持这种状态太久,哈哈)
- 将PHP作为ASAPI模块
- 将 PHP 作为 CGI 扩展运行
- 这不起作用,我收到错误:
CGI 错误
指定的 CGI 应用程序行为不当,未返回完整的 HTTP 标头集。
- 在 IIS 管理器中,将网站上的
执行权限
设置为脚本和可执行文件
- 添加了 html 标记和其他 php 函数编写脚本以查看是否得到处理;确实如此。就好像
shell_exec
位被跳过了。
非常感谢您看这个问题,我现在正在为这个问题而
烦恼,干杯,
Iain
更新 1
我真的不想这样做,但作为权宜之计,直到我找到合适的解决方案,我在 Web 服务器上运行 Apache(它运行 shell_exec 正常),然后我调用我的通过 cURL 的 apache 脚本。它很丑陋,但它有效:)。
更新 2
我开始认为这并不是 IIS 或权限本身的问题,而可能是我们网络上的某些策略的结果 - 尽管我无法想象是什么。有什么来自左翼的想法吗?
The Problem
I have a PHP script that uses shell_exec
to run a pdf-to-text converter. To simplify the problem I've created a short script that uses shell_exec
to just echo the output of the dir
command.
<?php
$cmd = 'C:\\WINDOWS\\system32\\cmd.exe /c ';
echo shell_exec($cmd.' dir');
?>
When I run this on my Apache server, everything works as expected. When I switch to IIS, it's as though the line is skipped entirely: no errors, no output, no logs, no nothing.
Unfortunately, I need to use IIS because I'm going to authenticate my users against active directory.
Here's what I've tried so far:
- Issue the command through
cmd.exe /c
rather than issuing it directly
- Give
Read & Execute
permission to SERVICE
on "C:\WINDOWS\system32\cmd.exe"
- Give
Read & Execute
permission to NETWORK SERVICE
on "C:\WINDOWS\system32\cmd.exe"
- Give
Read & Execute
permission to IUSR_MACHINENAME
on "C:\WINDOWS\system32\cmd.exe"
- Give
Read & Execute
permission to Everyone
on "C:\WINDOWS\system32\cmd.exe" (don't worry, it didn't stay like that for long, haha)
- Run PHP as an ASAPI module
- This is my standard configuration
- Run PHP as a CGI extention
- This does not work, I get an error:
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers.
- In IIS Manager, set
Execute Permissions
to Scripts and Executables
on your website
- Added html markup and other php functions to script to see if that gets processed; it does. It's as if the
shell_exec
bit just gets skipped.
Thank you so much for looking at this question, I am now pulling my hair out with the problem
Cheers,
Iain
Update 1
I really didn't want to do this, but as a stop gap until I find a proper solution I'm running Apache on the web server (which runs shell_exec fine) and I call my apache script via cURL. It's ugly, but it works :).
Update 2
I'm beginning to think this isn't so much an issue with IIS or permissions as such, but perhaps a result of some policy we have on our network - although I can't imagine what. Any ideas from left of field?
发布评论
评论(6)
以下是确定需要授予哪个用户权限的更系统的方法
确认您在 C:\WINDOWS\SYSTEM32(或更一般的 %systemroot%\system32)中有以下可执行文件
检查这些可执行文件的当前 ACL
如果用户“未授予“Everyone”读取 (R) 访问权限,然后临时授予如下
内容 创建 whoami.php 并包含以下内容
在 Web 浏览器上加载 whoami.php 并记下显示的用户名,例如在我的情况下,它显示
ct29296\iusr_template
撤销“Everyone's”权限(如果必须在上述步骤中添加)
仅授予在步骤 5 中找到的用户名以及 cmd.exe 的读取+执行权限 (R)
请记住为您自己的系统使用正确的用户名。
请参阅:http://www.myfaqbase.com /index.php?q=php+shell_exec&ul=0&show=f
Below is a more systematic way to determine which user needs to be granted permission
Confirm that you have the following executables in C:\WINDOWS\SYSTEM32 (or more generically %systemroot%\system32)
Check the current ACL for these executables
If the user "Everyone" is not granted Read (R) access, then TEMPORARILY grant as follows
Create whoami.php with the following content
Load whoami.php on a web browser and note the username displayed e.g. in my case it showed
ct29296\iusr_template
Revoke "Everyone's" permission if it had to be added in above steps
Grant only the username found in step 5 with the Read+Execute permission (R) to cmd.exe
Remember to use the correct username for your own system.
See: http://www.myfaqbase.com/index.php?q=php+shell_exec&ul=0&show=f
这里有几点:
shell_exec
函数,请确保PHP没有运行在安全模式下。来自 PHP 手册 - shell_exe 页面:这似乎也是在 Windows 中从 PHP 执行 shell 命令的一个众所周知的问题。共识似乎是让它工作的最好方法是让 PHP 在 FastCGI 模式下运行(我知道你已经尝试过这个并说你无法让它工作 - 因此我的第二点)。您可能会发现此Microsoft IIS 论坛帖子很有帮助。
Apache 通过 mod_auth_ldap。 PHP 通过以下函数提供 LDAP 支持:
Active Directory 是 LDAP 的实现。因此,您可以使用任何 LDAP 客户端针对 Active Directory 执行身份验证。
PS 您可以使用Apache mod_auth_ldap 或 PHP LDAP 函数 - 您不需要同时使用两者来完成这项工作。 Apache mod_auth_ldap 在 HTTP 协议级别工作,而 PHP LDAP 函数使您可以更好地控制身份验证和授权过程。
Here's a few points:
shell_exec
function, make sure that PHP is not running in safe mode. From the PHP manual - on the shell_exe page:It also appears that this is quite a known problem with executing shell commands from PHP in Windows. The consensus seems to be that the best way to get it to work is to have PHP running in FastCGI mode (I know you tried this already and said you couldn't get it to work - hence my second point). You may find this Microsoft IIS Forum thread helpful.
Apache provides LDAP authentication via the mod_auth_ldap. And PHP provides LDAP support through the following functions:
Active Directory is an implementation of LDAP. So, you with any LDAP client you can perform authentication against Active Directory.
P.S. You can either use the Apache mod_auth_ldap, or the PHP LDAP functions - you don't need to use both at the same time to make this work. The Apache mod_auth_ldap works at the HTTP protocol level, whereas the PHP LDAP Functions give you more control over the authentication and authorization process.
另外
如果你想直接执行 .exe,你可以使用 proc_open() 和 $other_options=array('bypass_shell'=>TRUE) ,
procmon.exe (sysinternals) 是你深入研究此类的最好的朋友。问题
couple of notes
if you want to execute a .exe directly, you can use proc_open() with $other_options=array('bypass_shell'=>TRUE)
also procmon.exe (sysinternals) is you best friend when digging into this class of problem
我会说
Read &对运行 IIS 的用户执行
权限(如果不是 IUSR_MACHINENAME)I'd say
Read & Execute
permission to the User thats running IIS (if thats not IUSR_MACHINENAME)将应用程序基于 IIS 的前提是有缺陷的。没有什么可以阻止您使用 Apache 进行此操作。事实上,您甚至不需要在 MS-Windows 操作系统上运行它。
谷歌一下如何设置这一切。
请注意,由于 IIS 和本地客户端可能使用 NTLM,因此安全策略将被排除在外。 IIS 处理程序线程可以使用 NTLM MSIE 客户端的凭据运行。或不。调试这些东西会让你发疯的!
C.
The premise for basing your application on IIS is flawed. There's nothing to stop you doing this with Apache. Indeed, you don't even need to run it on a MS-Windows OS.
Have a google for how to set up all this up.
Note that with IIS and local clients potentially using NTLM, the security policy gets thrown out of the window. The IIS handler thread may run with the credentials of a NTLM MSIE client. Or not. Debugging this stuff will drive you mad!
C.
我用 READ & 添加了用户 NETWORK SERVICE执行、读取我的应用程序的可执行文件所在的目录。自从这个改变之后,问题就消失了。
尽管如此,还需要授予 READ & 权限。执行、读取 IUSR_ 到 cmd.exe。
我从这里得到的解决方案 http://forums.iis.net/t/1147892.aspx
I added the user NETWORK SERVICE with READ & EXECUTE, READ to the directories where the executables of my application resides. Since this alteration, the problem is gone.
Nevertheless, it's also neccessary to grant the permissions READ & EXECUTE, READ for IUSR_ to cmd.exe.
The solution I got from here http://forums.iis.net/t/1147892.aspx