人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

perlでアップローダを作ったのですが、クラックを受けている様なんです。
./up の配下にしかアップロード出来ない様にしたつもりが、その上のディレクトリに.htaccessやらindex.htmやらを設置されて困っています。

ソース:
http://showizh.cool.ne.jp/cgitest/uploader.txt

ログが残る様にしたのですが、攻撃の際のログは記録されていません。(通常のアップに関してはちゃんと記録されます)
どこにセキュリティホールがあるんでしょうか?

サーバはレンタルのtok2proです。

●質問者: neuromancer_sho
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:.htaccess INDEX Perl アップローダ アップロード
○ 状態 :終了
└ 回答数 : 5/5件

▽最新の回答へ

1 ● pahoo
●24ポイント

不正拡張子のチェック部分が間違っているように思います。下記のように修正してみてください。

foreach(split(/ /,$ngextentions)){
 if($name =~ /\.$_/){ print LOG "!!dangerfile!!\n";exit;}
}
◎質問者からの返答

アンダーバーの後のダラーは文字列の最後という意味で合っていると思うのですが。

不正拡張子は(自分でテストし)ちゃんと検出され、ログに出力されています。


2 ● pigment
●4ポイント

setparaとかupfileという名前付けが気に入らない。ちゃんと英語にしてくれ、気持ち悪い

それとログに時刻その他が入ってないのもダメだろ

という諸々は置いといて、このCGI経由でなく置かれているんじゃなかろうか?

◎質問者からの返答

ログに時刻 - たしかに。

CGI経由じゃない - そんな気もしますね。


3 ● shintabo
●24ポイント

# これはダイジョブですか?

if($ENV{'REQUEST_METHOD'} eq 'POST'){ &upfile; }

else {

&setpara;

# で、

sub setpara{

foreach my $pair (split(/&/ , $ENV{QUERY_STRING})){

chop;

my($sep1 , $sep2) = split(/=/ , $pair , 2);

$form{$sep1} = $sep2;

}

if($form{"createdirname"} ne ""){

mkdir $dir."/".$form{"createdirname"}, 0701;

&reload;

}

# が呼ばれてますが、GETリクエストで

createdirname=../../up2

# など入っていると、そのまま作ってしまいそうなのですが・・・

# また、chopもchompにしておかないと、末尾を削除しちゃわないですか?

# 次に

sub viewfile {

if($dir !~ /^\.\/up/ || $dir =~ /\.\./){ print "このフォルダは表示出来ません
";exit}

# ですが、上の例でいくと、

movetodir=./upupupupup

# で、GETリクエストがくると、そのまま通りそうです

# upfileメソッドも同様ですね

# あとは、

use strict;

# は、必ずつけましょーっていうのと、HTML::TemplateなどでMVCを分けたほうがよいのではないでしょうか?

◎質問者からの返答

chop要らないですね。どこかからコピペしてきたのがそのまま残っていたようです。

・ディレクトリが意図しない場所に作られてしまう

・頭に"up"がついているディレクトリであればアップロード・表示可能

ということですね。しかし、迷惑ファイルが置かれる場所は ./up の真上のディレクトリ(頭に"up"はついていない)でした。

HTML:\:Templateというのは始めて知りました。

大変参考になりました。ありがとうございます。

あ、言い忘れました。perlのバージョンは5.0なのでJcode.pmを使っています。


4 ● りゅう
●24ポイント

HTTPにはユーザーエージェントが受け取り可能なメディアタイプ・言語・エンコーディングを考慮して

適切なリソース(のバリアント)を返すコンテントネゴシエーションという機能があります。

Apacheでは、このバリアントを実現するのに追加の拡張子を付けたファイルを用意するという方法が取られています。

たとえばtest.htmlの日本語版ならtest.html.ja、

英語版ならtest.html.enというファイルをサーバに置きます。


で、件のアップローダですが、test.phpはアップロードできませんが、test.php.jaならアップロードできるわけです。

tok2proのApacheがコンテントネゴシエーションが有効であれば、test.php.jaはPHPとして実行されてしまいます。


PHPファイルを置ければあとはどうにでもなるので、PHPを使ってhtaccessなどを置いたのだと思われます。

犯人がログを改ざんするなどという気の利いたことをしていなければ、PHPファイルをアップロードした記録が残っているかもしれません。

◎質問者からの返答

拡張子が最後に来ると決め付けちゃいけないんですね。

なるほど


5 ● ばけら
●24ポイント

これが直接の原否なのかどうかは分かりませんが、件のスクリプトでは拡張子のチェック部分に欠陥があり、チェックをすり抜けることが可能であるように思います。

たとえば以下のようなスクリプトは、一見すると .htaccess で終わるファイルを作らせないように見えます。

my $filename = ".htaccess";

if($filename =~/\.htaccess$/){

die "filename error";

}

open(OUT, "> $filename");

close(OUT);

しかし、

my $filename = ".htaccess\x0.txt";

として実行してみると、チェックを通り抜けて .htaccess というファイルが作成されるはずです。このように、ファイル名の途中に \x0 (NUL) を混入することでチェックをすり抜けることが可能となる場合があります。

なお、過去にはこのような問題が情報処理技術者試験でも出題されたことがあります。

参考: http://bakera.jp/ebi/topic/2519

ファイル名をチェックする際には、ファイル名全体が /^[-A-Za-z0-9]+$/ にマッチするかどうか確認するなどした方が良いと思います。

◎質問者からの返答

ありがとうございます。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ