오염 모드 펄:시스템을 통해 외부 프로그램을 실행할 때 유지()
문제
레거시 스크립트에 기능을 추가하려고합니다.스크립트는 수드이며 펄-티(오염 모드)를 사용합니다.:맨 펄섹),추가 보안을 위해.내가 추가해야 할 기능은 파이썬에서 구현됩니다.
내 문제는 내가 환경과 내 명령 줄을 얼마나 많이 세탁 할지라도 펄섹을 설득 할 수 없다는 것이다.
이것은 다른 바이너리(예:/빈/아이디)에 대한 수이드를 보존하기 때문에 실망 스럽습니다.에 대한 문서화되지 않은 특별한 경우가 있습니까?이 가능성이 보인다.
이 작업을 수행 할 수있는 방법을 아는 사람이 있습니까?(있는 그대로:우리는 이 모든 것을 다시 설계할 자원이 없습니다.)
솔루션: (@지바콘에 따라)
# use the -p option to bash
system('/bin/bash', '-p', '-c', '/usr/bin/id -un');
# or set real user and group ids
$< = $>;
$( = $);
system('/usr/bin/python', '-c', 'import os; os.system("/usr/bin/id -un")');
원하는 결과를 제공합니다!
여기 내 스크립트의 컷 다운 버전이 있습니다.이 버전은 여전히 내 문제를 보여줍니다.
#!/usr/bin/perl -T
## This is an SUID script: man perlsec
%ENV = ( "PATH" => "" );
##### PERLSEC HELPERS #####
sub tainted (@) {
# Prevent errors, stringifying
local(@_, $@, $^W) = @_;
#let eval catch the DIE signal
$SIG{__DIE__} = '';
my $retval = not eval { join("",@_), kill 0; 1 };
$SIG{__DIE__} = 'myexit';
return $retval
}
sub show_taint {
foreach (@_) {
my $arg = $_; #prevent "read-only variable" nonsense
chomp $arg;
if ( tainted($arg) ) {
print "TAINT:'$arg'";
} else {
print "ok:'$arg'";
}
print ", ";
}
print "\n";
}
### END PERLSEC HELPERS ###
# Are we SUID ? man perlsec
my $uid = `/usr/bin/id --user` ;
chomp $uid;
my $reluser = "dt-pdrel";
my $reluid = `/usr/bin/id --user $reluser 2> /dev/null`;
chomp $reluid;
if ( $uid ne $reluid ) {
# what ? we are not anymore SUID ? somebody must do a chmod u+s $current_script
print STDERR "chmod 4555 $myname\n";
exit(14);
}
# comment this line if you don't want to autoflush after every print
$| = 1;
# now, we're safe, single & SUID
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# BEGIN of main code itself
print "\nENVIRON UNDER BASH:\n";
run('/bin/bash', '-c', '/bin/env');
print "\nTAINT DEMO:\n";
print "\@ARGV: ";
show_taint(@ARGV);
print "\%ENV: ";
show_taint(values %ENV);
print "`cat`: ";
show_taint(`/bin/cat /etc/host.conf`);
print "\nworks:\n";
run('/usr/bin/id', '-un');
run('/usr/bin/id -un');
print "\ndoesn't work:\n";
run('/bin/bash', '-c', '/usr/bin/id -un');
run('/bin/bash', '-c', '/bin/date >> /home/dt-pdrel/date');
run('/bin/date >> /home/dt-pdrel/date');
run('/usr/bin/python', '-c', 'import os; os.system("/usr/bin/id -un")');
run('/usr/bin/python', '-c', 'import os; os.system("/usr/bin/id -un")');
sub run {
my @cmd = @_;
print "\tCMD: '@cmd'\n";
print "\tSEC: ";
show_taint(@cmd);
print "\tOUT: ";
system @cmd ;
print "\n";
}
그리고 여기에 출력이 있습니다:
$ id -un
bukzor
$ ls -l /proj/test/test.pl
-rwsr-xr-x 1 testrel asic 1976 Jul 22 14:34 /proj/test/test.pl*
$ /proj/test/test.pl foo bar
ENVIRON UNDER BASH:
CMD: '/bin/bash -c /bin/env'
SEC: ok:'/bin/bash', ok:'-c', ok:'/bin/env',
OUT: PATH=
PWD=/proj/test2/bukzor/test_dir/
SHLVL=1
_=/bin/env
TAINT DEMO:
@ARGV: TAINT:'foo', TAINT:'bar',
%ENV: ok:'',
`cat`: TAINT:'order hosts,bind',
works:
CMD: '/usr/bin/id -un'
SEC: ok:'/usr/bin/id', ok:'-un',
OUT: testrel
CMD: '/usr/bin/id -un'
SEC: ok:'/usr/bin/id -un',
OUT: testrel
doesn't work:
CMD: '/bin/bash -c /usr/bin/id -un'
SEC: ok:'/bin/bash', ok:'-c', ok:'/usr/bin/id -un',
OUT: bukzor
CMD: '/bin/bash -c /bin/date >> /home/testrel/date'
SEC: ok:'/bin/bash', ok:'-c', ok:'/bin/date >> /home/testrel/date',
OUT: /bin/bash: /home/testrel/date: Permission denied
CMD: '/bin/date >> /home/testrel/date'
SEC: ok:'/bin/date >> /home/testrel/date',
OUT: sh: /home/testrel/date: Permission denied
CMD: '/usr/bin/python -c import os; os.system("/usr/bin/id -un")'
SEC: ok:'/usr/bin/python', ok:'-c', ok:'import os; os.system("/usr/bin/id -un")',
OUT: bukzor
CMD: '/usr/bin/python -c import os; os.system("/usr/bin/id -un")'
SEC: ok:'/usr/bin/python', ok:'-c', ok:'import os; os.system("/usr/bin/id -un")',
OUT: bukzor
해결책
당신은 당신의 실제 사용자를효과(수이드-에드)로 설정해야합니다.당신은 아마 당신의 실제 그룹 아이디에 대해 동일한 작업을 수행 할:
#! /usr/bin/perl -T
use warnings;
use strict;
$ENV{PATH} = "/bin:/usr/bin";
system "id -un";
system "/bin/bash", "-c", "id -un";
# set real user and group ids
$< = $>;
$( = $);
system "/bin/bash", "-c", "id -un";
샘플 실행:
$ ls -l suid.pl -rwsr-sr-x 1 nobody nogroup 177 2010-07-22 20:33 suid.pl $ ./suid.pl nobody gbacon nobody
당신이보고있는 것은 문서화되어 있습니다 bash
행동:
-p
권한 모드를 켭니다.이 모드에서는
$BASH_ENV
그리고$ENV
파일은 처리되지 않으며,셸 함수는 환경으로부터 상속되지 않으며,SHELLOPTS
,BASHOPTS
,CDPATH
그리고GLOBIGNORE
변수가 환경에 나타나면 무시됩니다.셸이 실제 사용자(그룹)아이디와 같지 않은 유효 사용자(그룹)아이디로 시작되면-p
이 옵션은 제공되지 않으며 이러한 작업이 수행되고 실제 사용자 아이디로 설정됩니다.만약-p
이 옵션은 시작시 제공되며 유효 사용자 아이디는 재설정되지 않습니다.이 옵션을 끄면 실제 사용자 및 그룹 아이디로 설정되는 효과적인 사용자 및 그룹 아이디가 발생합니다.
이것은 당신이 또한 할 수 있다는 것을 의미합니다
#! /usr/bin/perl -T
use warnings;
use strict;
$ENV{PATH} = "/bin:/usr/bin";
system "/bin/bash", "-p", "-c", "id -un";
얻을 수
nobody
여러 인수를 전달하는 것을 상기하십시오 system
쉘을 우회합니다.단일 인수는 쉘로 이동하지만 아마도 그렇지 않을 것입니다 bash
-의 출력을 봐 perl -MConfig -le 'print $Config{sh}'
.