連載
» 2003年02月22日 00時00分 UPDATE

不正侵入の手口と対策(6):アクセスログの改ざんと検出方法 (1/2)

[木村靖,三井物産セキュアディレクション株式会社]
※ご注意
他社および他組織のWebサイトなどへのポートスキャンおよびデータの取得などの行為で得た情報を侵入などに悪用するか、または同じ目的を持つ第三者に提供した時点で違法となります。ご注意ください。
本稿の内容を検証する場合は、必ず影響を及ぼさない限られた環境下で行って下さい。
また、本稿を利用した行為による問題に関しましては、筆者および株式会社アットマーク・アイティは一切責任を負いかねます。ご了承ください。

 前回「第5回 バックドアの検出と対処」はバックドアの検出と対処方法について説明した。最終回の今回は、攻撃者が侵入後に行うアクセスログの改ざんとその検出方法、さらにはログの調査方法について説明する。

ログの重要性

 実際にサーバを運用管理する者なら、OSや各種ソフトウェアが出力するログの重要性は身に染みて分かっていることだろう。なぜなら、ログからはサーバを運用管理するうえで必要となるさまざまな情報が得られるからだ。

 例えば、ほとんどのソフトウェアは、何らかの異常を検知した場合にその症状をログに出力する。サーバ管理者は出力されたエラーログを参照することで、症状に応じた対処を迅速かつ的確に行える。また、アクセス状況のログなどを調査することで、前回紹介した不正アクセスを許した際の原因究明にも役立つ。

ログの種類と用途

 通常、UNIXのシステムログは、表1に示すとおり、出力されるメッセージの内容や用途に応じて、別々のファイルに記録される。そして、これらのログの大半は、syslogと呼ばれるログシステムによって制御・出力されている。

ファイル名 ログの用途 主な格納先 格納タイプ
utmp 現在のユーザー情報を記録 /var/run バイナリ
wtmp ログインの履歴を記録 /var/log バイナリ
lastlog ユーザーの最終ログイン時を記録 /var/log バイナリ
cron cronの実行結果を保存 /var/log テキスト
maillog メール関連 /var/log テキスト
messages システムメッセージ、各種ソフト /var/log テキスト
secure セキュリティ関連 /var/log テキスト
xferlog ftp関連 /var/log テキスト
表1 UNIXにおける主要なログ

 UNIX上の多くのソフトウェアは、ログの出力をこのsyslogにまかせているが、中にはApacheのように自分自身で出力する場合もある。

ログの改ざんと検出

 攻撃者が対象サーバ上のログから自身の痕跡を消すためには、ログファイルそのものを削除するか、あるいは一部を改ざんすることになる。前者の場合はサーバ管理者に気付かれる可能性が高くなるので、通常は後者の攻撃者自身に関する痕跡のみ改ざんするだろう。

 攻撃者がよく改ざんするログとしては、以下のアクセスログとコマンド実行ログが挙げられる。

  • アクセスログ(utmp、wtmp、lastlogなど)の改ざん
  • コマンド実行履歴(.history、.sh_history、.bash_historyなど)の改ざん

アクセスログの改ざん

 攻撃者がアクセスした痕跡は、先述のlastlog、utmp、wtmpを筆頭に、そのほか各種ログにも残される。それらのアクセス履歴を改ざんする場合は、コマンドやテキストエディタやを使うか、改ざん専用ツールを使うことになる。ここでは、grep、sedコマンドと専用ツールのZapを用いた改ざん手法について説明する。

 なお、grepおよびsedは、GNU grep 2.5.1とsed 3.02を使用した。種類やバージョンによるオプションの違いは、manコマンドで確認するとよい。

  • grep、sedコマンドを用いた例

 この手法は非常にシンプルで、grepコマンドで指定した特定文字列(正規表現)にマッチした行をログファイルから削除するというものだ。例えば、ログファイルの/var/log/messagesからkimuの文字列にマッチする行をすべて削除するには、以下のとおり実行すればよい。

# grep -v kimu /var/log/messages > /tmp/messages
# mv /tmp/messages /var/log/messages
# chmod 600 /var/log/messages

 grepの-vオプションは、パターンにマッチした以外の行を出力する。すなわち、上記は文字列kimuが含まれない行のみを/tmp/messagesに出力している。そして、mvコマンドでログを改ざん後のものにし、chmodコマンドで元のアクセス権限に戻している。

 grepで行ったことを、sed(ストリームエディタ)でも同様に行える。

# sed -e '/kimu/d' /var/log/messages > /tmp/messages

 後はgrepと同様に、mvとchmodで元のファイルと置き換えればよい。また、行を削除するのではなく、文字列をkimuからrootに置換したい場合は、以下のとおりに行う。

# sed -e 's/kimu/root/g' /var/log/messages > /tmp/messages

  • Zapを用いた例

 いくつかあるログ改ざんツールの中でも有名なのがZapだ。このツールはlastlog、utmp、wtmpから特定ユーザーの痕跡を消してくれる。

(1)パスの変更

 C言語で書かれたZapのソースコード(zap2.c)を入手し、テキストエディタを用いて以下のとおり各ログファイルへのパスを変更する。

変更前:

#define WTMP_NAME "/usr/adm/wtmp"
#define UTMP_NAME "/etc/utmp"
#define LASTLOG_NAME "/usr/adm/lastlog"

変更後:

#define WTMP_NAME "/var/log/wtmp"
#define UTMP_NAME "/var/run/utmp"
#define LASTLOG_NAME "/var/log/lastlog"

(2)Zapのコンパイル

 GNU Cコンパイラのgccを使い、zap2.cから実行形式のファイル(ここではzap)を生成する。

# gcc -o zap zap2.c

(3)zapを使う

 生成したzapを使うには、root権限で以下の形式で実行するだけだ。

# ./zap ユーザー名

 実際に実行する前に、まずログイン履歴を見ておく。以下はlastとlastlogコマンドの実行結果だ。

# last
root pts/2 192.168.0.142 Sun Feb 16 20:21 still logged in
kimu pts/2 172.16.0.10 Sun Feb 16 20:21 - 20:21 (00:00)
y-kimura pts/1 192.168.0.142 Sun Feb 16 20:18 - 20:20 (00:02)


・・・・・・ 省略 ……


# lastlog
…… 省略 ……


kimu pts/2 172.16.0.10 Sun Feb 16 20:21:28 +0900 2003

 このうち、ユーザーkimuのアクセス履歴の消去を行う。

# ./zap kimu
Zap2!

 消去完了。もう一度last、lastlogコマンドを実行して確認してみる。

# last
root pts/2 192.168.0.142 Sun Feb 16 20:21 still logged in
y-kimura pts/1 192.168.0.142 Sun Feb 16 20:18 - 20:20 (00:02)


# lastlog
kimu **Never logged in**

 ユーザーkimuのログインの履歴が消去された(lastlogの場合、「**Never loggedin**」を表示)。

コマンド実行履歴の改ざん

 UNIXシステムのインタプリタであるシェルの中には、ユーザーが実行したコマンドを記録するという、ヒストリ機能がある。このヒストリ機能を使うことで、ユーザーは一度実行したコマンドを再び呼び出して使うことができる。

 これは、通常のユーザーが使う場合は便利な機能だが、攻撃者からすると自分が実行した不正なコマンドが記録されるわけだから、あまりうれしくない機能だ。そのため、多くの攻撃者は、もしヒストリ機能が使われていた場合は、消去するか改ざんするなどの処置を取るだろう。

 ヒストリ機能の保存時のファイル名は、以下のとおり使うシェルによって多少異なるが、格納先は各ユーザーのホームディレクトリ直下にテキストファイルとして保存される。

  • csh、tcshの場合: .history
  • bashの場合: .bash_history
  • kshの場合: .sh_history

 各ヒストリファイルは、以下に示すような単なるテキストファイルとして保存されているので、内容を改ざんする場合は、viなどのテキストエディタを使うことになる。

.bash_historyの出力例:

# cat $HOME/.bash_history
gcc -o zap zap2.c
./zap
last
lastlog

ログ改ざんの検出

 ログファイルの改ざんを検出するのは非常に困難だが、一部のアクセスログに関しては、前回紹介したchkrootkitにも含まれているchklastlogやchkwtmpを使うことで検出できる場合もある。以下はchkwtmpを使用して、/var/log/wtmpの改ざんを検出した様子だ。

# ./chkwtmp
1 deletion(s) between Sun Feb 16 20:20:54 2003 and Sun Feb 16 20:21:32 2003

 上記の出力結果は、2003年2月16日20時20分54秒から20時21分32秒の間に1行改ざんされたことを示している(先述のZapの改ざんを検出)。

 以上のとおり、ログは比較的簡単に改ざん可能であることが分かる。もし、対象サーバ上のログを消されたり、改ざんされたくないのであれば、別のサーバ(ログ収集専用サーバが望ましい)に転送することを検討してみてはどうだろうか。もちろんのこと、ログサーバ自身のセキュリティは十分に確保されている必要がある。

手動によるログ調査

 冒頭でも述べたが、ログはサーバを運用管理する上で非常に重要な情報源となり得る。そのため、サーバ管理者としては、緊急時の対処を迅速かつ的確に行えるように、普段からログの調査に慣れておくことをお勧めする。

アクセスログの調査

(1) wコマンド (現在ログイン中のユーザー情報を表示)

 wコマンドで現在ログイン中のユーザー情報を表示することできる。類似コマンドとしてwhoコマンドが挙げられる。なお、このwコマンドは、utmpから情報を得ている。

% w
2:42am up 18 days, 7:29, 3 users, load average: 0.00, 0.00, 0.00
kimu pts/0 172.16.0.10 2:42am 3.00s 1.16s 1.05s emacs -nw
y-kimura pts/1 192.168.0.142 2:56pm 0.00s 0.67s 0.03s w
root pts/2 192.168.0.142 8:21pm 1:44m 0.62s 0.62s -bash

 現在ログイン中のユーザーkimu、y-kimura、rootのそれぞれの状況が分かる。

(2)lastコマンド (ログイン履歴)

 lastコマンドで過去にログインしたユーザーやOS再起動の履歴が分かる。なお、lastコマンドは、wtmpから情報を得ている。

例:すべてのログイン履歴を表示

% last
root pts/2 192.168.0.142 Sun Feb 16 20:21 still logged in
kimu pts/2 172.16.0.10 Sun Feb 16 20:21 - 20:21 (00:00)
y-kimura pts/1 192.168.0.142 Sun Feb 16 20:18 - 20:20 (00:02)
y-kimura pts/0 192.168.0.142 Sun Feb 16 10:45 - 02:42 (15:56)
y-kimura pts/0 192.168.0.142 Thu Feb 13 01:23 - 03:56 (02:32)
…… 省略 ……

例:最後にログインしたユーザーから3行分のみを表示

% last -3
root pts/2 192.168.0.142 Sun Feb 16 20:21 still logged in
kimu pts/2 172.16.0.10 Sun Feb 16 20:21 - 20:21 (00:00)
y-kimura pts/1 192.168.0.142 Sun Feb 16 20:18 - 20:20 (00:02)

例:ユーザーkimuのログイン履歴を調べる。

% last kimu
kimu pts/0 172.16.0.10 Mon Feb 17 02:42 still logged in
kimu pts/2 172.16.0.10 Sun Feb 16 20:21 - 20:21 (00:00)

(3)lastlog (各ユーザーの最終ログイン日時を表示)

 lastlog(lastlogin)コマンドで、各ユーザーの最終ログイン日時を表示する。

例:全ユーザーの情報を表示

% lastlog
Username Port From Latest
root pts/2 192.168.30.142 Sun Feb 16 20:21:45 +0900 2003
bin **Never logged in**
…… 途中省略 ……
y-kimura pts/3 192.168.30.142 Mon Feb 17 03:12:37 +0900 2003
kimu pts/2 192.168.30.142 Sun Feb 16 20:21:28 +0900 2003

例:ユーザーkimuの情報のみ表示

% lastlog -u kimu
Username Port From Latest
kimu pts/2 192.168.30.142 Sun Feb 16 20:21:28 +0900 2003

例:過去1日にアクセスしたユーザーのみ表示

% lastlog -t 1
Username Port From Latest
root pts/2 192.168.30.142 Sun Feb 16 20:21:45 +0900 2003
y-kimura pts/3 192.168.30.142 Mon Feb 17 03:12:37 +0900 2003
kimu pts/2 192.168.30.142 Sun Feb 16 20:21:28 +0900 2003

そのほかのログの調査 (syslog)

 UNIX上のシステムログや多くのソフトウェアが出力するログは、そのほとんどがsyslogを経由している。そして、それらのログの出力形式は、以下のようなテキストファイルとして出力される。

syslogの出力形式
月 日 時:分:秒 ホスト名 プロセス名[プロセスID]:メッセージ

syslogの出力例:

Jan 26 11:17:31 www named[689]: shutting down

 こういったテキスト形式のログファイルを調査する場合は、less、tail、grepといった既存のコマンドを用いるとよいだろう。

(1)cat、more、less (ファイルの内容表示)

 ログファイルの内容を先頭から順に読みたい場合は、cat、more、lessといったコマンドを使えばよい。特にmoreやlessは、文字の検索機能やページ単位で表示可能なためとても重宝する。

# less /var/log/messages
Feb 16 04:02:19 www syslogd 1.4.1: restart.
Feb 16 10:45:50 www sshd(pam_unix)[23922]: session opened for user y-kimura by (uid=0)

…… 省略 ……

(2)tail (ログファイルの随時参照)

 tailはファイルの最後の部分を表示するコマンドで、ログの出力をターミナルなどに随時表示させることも可能だ。

例:/var/log/messagesの最後から3行を表示

# tail -3 /var/log/messages
Feb 16 14:56:10 www sshd(pam_unix)[24799]: session closed for user y-kimura
Feb 16 14:56:15 www sshd(pam_unix)[24807]: session opened for user y-kimura by (uid=0)
Feb 16 16:26:33 www su(pam_unix)[24954]: session opened for user root by y-kimura(uid=500)

例:/var/log/messagesに出力される内容を随時表示(-fオプション)

# tail -f /var/log/messages
Feb 16 10:45:50 www sshd(pam_unix)[23922]: session closed for user y-kimura
Feb 16 10:45:56 www sshd(pam_unix)[23930]: session opened for user y-kimura by (uid=0)
Feb 16 14:56:09 www sshd(pam_unix)[24799]: session opened for user y-kimura by (uid=0)
Feb 16 14:56:10 www sshd(pam_unix)[24799]: session closed for user y-kimura
Feb 16 14:56:15 www sshd(pam_unix)[24807]: session opened for user y-kimura by (uid=0)
Feb 16 16:26:33 www su(pam_unix)[24954]: session opened for user root by y-kimura(uid=500)

 コマンド実行後、/var/log/messagesに出力された内容が、ターミナルに随時出力される。なお、ここでは紹介しないがtailコマンドとは逆にファイルの最初の部分を表示するコマンドとしてhead(ファイルの先頭部分を表示)が挙げられる。

(3)grep (文字列にマッチした行を表示)

 先述のとおり、grepは指定した文字列(正規表現)にマッチした行を表示させるためのコマンドだ。このgrepを使うことで、膨大なログファイルから、特定文字が含まれる行のみを取り出すことができる。

例:/var/log/messagesよりnamedという文字列が含まれる行を表示

# grep named /var/log/messages
Jan 26 11:17:31 www named[689]: shutting down
Jan 26 11:17:31 www named[689]: stopping command channel on 127.0.0.1#953
Jan 26 11:17:31 www named[689]: no longer listening on 127.0.0.1#53

 次ページでは、ログの改ざんを監視するツールを紹介する。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

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

メールマガジン登録

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