1

我的原始脚本如下:

my $cmd = "dir";
open (H, "$cmd |");
my @result = <H>;
close (H);
print STDERR @result,"\n";

这个脚本工作正常。如果我在脚本中添加以下行,它将无法工作:

$ENV{"LD_LIBRARY_PATH"} = "/opt/VRTSsfmh/lib";
$ENV{PATH}="/usr/bin:/bin:/sbin:/usr/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

当调用管道打开时 Perl 使用什么?

添加以下代码解决了该问题:

if ($^O =~ /Win32/i) 
{
    $ENV{'SystemRoot'} =~ /([A-Z]:(\\[A-Za-z0-9_]+)+)/;
    my $system32_dir = $1."\\system32";
    $ENV{'PATH'} = $system32_dir;
}
4

2 回答 2

7

您的问题与污染模式无关。你设置

$ENV{PATH}="/usr/bin:/bin:/sbin:/usr/sbin";

这些目录通常不存在于 Windows 机器上。dir是一个 cmd.exe 内部命令,因此为了能够执行它,您需要将它所在的目录添加到路径中。

现在,请注意,您执行此操作的方式与将路径设置到已知确定位置的整个要点相矛盾。恶意用户绝对有可能更改此环境变量以指向他危险的dir.

如果您依赖任何内置的 shell,Windows 不一定安装在 C:\Windows 中的事实会使在 Windows 上编写污染安全脚本变得复杂。

编辑:这是一个可以用作基线的简短测试程序:

#!/usr/bin/perl -T

use strict;
use warnings;

$ENV{PATH} = join(';', qw(C:\Windows C:\Windows\System32) );
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};

open my $pipe_h, '-|', 'dir'
    or die "Cannot open pipe to dir: $!";

print while <$pipe_h>;

close $pipe_h
    or die "Cannot close pipe to dir: $!";

__END__

C:\Temp> perl -T v.pl

...

2009/05/25  08:58 AM             3,584 zzz.exe
              64 File(s)     32,125,365 bytes
              14 Dir(s)  39,251,894,272 bytes free

基本上,您需要的是系统管理员在安装时硬编码可接受的路径,并且不受信任的用户对脚本没有写权限。

于 2009-06-08T11:42:42.013 回答
0

污点模式很复杂。你真的必须阅读和理解perldoc perlsec。您的问题已在清理路径部分的第一句中得到解决。

于 2009-06-08T13:44:50.440 回答