0

このスクリプトのアクセス許可がスクリプトである場合、スクリプトはu=rwx,g=rwx,o=r正常に動作します...ただし、setuid ビットをオンにして、smartctl の呼び出しがエラーではなく目的のデータを返すようにする必要があります。

#!/usr/bin/perl

use strict;
use warnings;
use CGI qw(:standard);

my $device = param("device") || "sda";

print header("text/plain");

print "device = $device\n\n";


$ENV{"PATH"} = "/usr/sbin";
open( PS, "smartctl -A /dev/$device |" );
while( <PS> )
{
    print $_ . "\n";
}
close( PS );

パーミッションを に設定するとu=rwxs,g=rwxs,o=r、クエリで が指定されていない場合にスクリプトが機能しますdevice。しかし、deviceが指定された場合、その後は何も返されませんprint "device = $device\n\n";

4

1 に答える 1

2

Perl の構成を確認する必要があります。

perl -MConfig -e 'print "d_suidsafe = $Configu{d_suidsafe}\n"; }'

何も言わない場合 ( の後に何も表示されない場合=)、Perl は SUID スクリプトを安全でないと見なすように指示されています。通常のスクリプトとは異なる方法で処理します。'taint'システム (-Tコマンド ライン オプション) もチェックしてください。後述の「スクリプト インジェクション」の問題について警告する必要があります。


コーディングの提案:

  1. の 3 引数形式を使用しopenます。
  2. open成功したことを確認します。

このような:

open my $PS, "-|", "smartctl -A /dev/$device"
  or die "Could not popen smartctl: $!";

おそらくそうdieではありませんが、エラーを明確に報告し、開かれていないファイル ハンドルを使用しないでください。

if (open my $PS, "-|", "smartctl -A /dev/$device")
{
    while (<$PS>)
    {
        print "$_\n";
    }
    close $PS;
}
else
{
    print "Failed to open device: $!";
}

sda; cp /bin/sh /tmp/...; chmod 6777 /tmp/...デバイスパラメータフィールドに書いた人の入力を拒否またはサニタイズする必要があることに注意してください。これは SQL インジェクションに少し似ていますが、今回だけは「Perl スクリプト インジェクション」です。それらはそれよりも残忍かもしれません:sda; rm -fr / 2>/dev/null &スクリプトが setuid されているユーザーが変更できるファイルとディレクトリのシステムをきれいにきれいにします。最良のときでも、ユーザーを 1 インチも信頼することはできません。setuid プログラムでは、ユーザーを完全に信頼することは深刻な問題です。アクセスが Web ブラウザーからの場合は、そのすべてが 2 倍になります (倍増しない場合)。

于 2012-01-01T22:36:29.630 に答える