連載
» 2006年05月27日 00時00分 公開

公開中のHTMLファイルがごっそり消失!?星野君のWebアプリほのぼの改造計画(7)(2/3 ページ)

[杉山俊春, Illustrated by はるぷ,三井物産セキュアディレクション株式会社]

うっかりログインしてしまうと、犯行の痕跡が消える!?

 安直に元に戻すのも気が引けたのだが、ただ単にデータが消えてしまっただけなのか、何か不正なアクセスを受けて故意に消されてしまったのかがいまの段階では分からないので、「原状復帰優先!」といわれても特に反論はできなかった。本来であればネットワークから切り離して時間をかけて解析をしたいところだ。

 そんなやりとりを隣の席で聞いていた赤坂さんが、星野君に話し掛けてきた。

赤坂さん 「なんかあったの?ファイルが消えたとか聞こえたけど」

星野君 「Webサーバ内のファイルがいつの間にかごっそり消えちゃったんですよ。特にファイルが消えるような作業はしてないんですけどねー」

赤坂さん 「なんか面白そう♪それ、私も手伝っていい?」

星野君 「あ、もちろんお願いします」

 星野君は、「あんまり面白い状況じゃないんだけどなぁ……」と内心思いながらも、せっかく赤坂さんが手伝ってくれるということなので、どういう現象になっているのかを説明した。

赤坂さん 「もうログインしちゃったみたいだから証拠とか消えちゃってるかもね」

星野君 「え。ログインするだけで消えちゃうものなんですか??」

赤坂さん 「うん。もし不正アクセスを受けてたとしたら、ログインしたら証拠が消えるようにわなが張ってあるかもしれないからね」

星野君 「そういうのもあるんですね……」

 赤坂さんと話をしていると、平野部長が何やら物言いたげな表情で星野君の方を見ていた。脆弱なWebアプリケーションが原因でファイルが消されてしまったという可能性も考えられたので、星野君は自分がちゃんと把握できている部分のみの復元を応急処置として行った。

OSコマンドインジェクションで消されたファイル

 ひとまず平野部長に部分的な復旧を終えたことを報告し、星野君は原因の究明作業に入った。星野君が復旧作業を行っている間に、赤坂さんが原因究明作業を始めてくれていたので、2人で分担をして作業を進めた。

星野君 「あ……」

赤坂さん 「ん?何か見つけた?」

星野君 「これ、怪しくないですか??」

 星野君が調べていたのは、apacheのログファイルだ。そのログファイルの中には、以下のようなエントリーが記載されていた。

192.168.42.80 - - [15/Mar/2006:02:59:39 +0900] "GET /web-cgi/aProposalSubmit.cgi?mode=c&template=./tmpl/cSubmit.tmpl|rm%20-rf%20/%26| HTTP/1.1" 200 1363 "blockedReferrer" "Malicious Attacker/4.0"

 このログでは、aProposalSubmit.cgiというWebアプリケーションに渡す変数のtemplateの値に、「|rm%20-rf%20/%26|」という値を挿入している。PerlのWebアプリケーションでopen()関数を利用している場合に、「|(パイプ)」を挿入することでOSコマンドが動作してしまう場合がある(OSコマンドインジェクション)。

#!/usr/bin/perl
use CGI;
$query=CGI->new();
print $query->header();
open(IN, $query->param(' template')); #パラメータ「template」の値をそのまま入力
print <IN>;
close(IN);
OSコマンドインジェクションに対して脆弱なWebアプリケーション例(ファイルを読み込んで表示するアプリケーション)

 上記のようなWebアプリケーションでは、ユーザーからの入力をチェックすることなくopen()関数に挿入しているため、任意のOSコマンドを動作させることができてしまう。

 このようなWebアプリケーションに対して、「|rm%20-rf%20/%26|」(%20はURLデコードすると半角スペースに、%26は&になる)のようなコマンドを挿入されると、Webサーバの権限(今回の場合はapache権限)において「rm -rf /」というファイルを消すコマンドが実行されてしまうことになる。

 Perlのopen()関数以外にも同様な動作を引き起こす関数がある。例えば、直接外部コマンドを実行するexec()関数やsystem()関数などにユーザーからの入力をそのまま挿入してしまうような作りになっている場合、OSコマンドインジェクションに対して脆弱になってしまう(下記の表を参照のこと)。

 これらの関数などを利用する際には、基本的にユーザーからの入力が関数にそのまま挿入されないようにすることが好ましいが、ユーザーからの入力を利用する場合には、コマンドが実行されないように厳格な入力チェックおよびエスケープなどの無害化を行うことが必要になる。

Perl exec()
system()
'command'
PHP exec()
system()
shell_exec()
passthru()
popen()
'command'
Java java.lang.Runtime.exec()
C exec()
system()
各プログラム言語の外部コマンドの実行方法

赤坂さん 「うーん。これかなり怪しいね。このaProposalSubmit.cgiってファイルのソース見られる?」

 早速、ログに残っていた問題のありそうなファイルのソースを見てみると、案の定、ユーザーから受け取ったファイル名をそのままPerlのopen()関数に渡していた。そのため、apacheの権限になっていたWebのルートディレクトリ以下のファイルがごっそり消されてしまったのだ。

赤坂さん 「これで原因が分かったね。やっぱり不正アクセスを受けてたみたい」

星野君 「このファイル自体はとっとと除去するとして、この送信元IPアドレス、海外みたいなんですけどどうしましょう……?」

赤坂さん 「まあ、その辺は情報だけ渡して上の人に任せたら?」

星野君 「そうですね」

 星野君は原因を平野部長に報告し、今後の対応については任せることにした。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。