今回はハッキングを行うための舞台であるLinuxOSについての概要を解説します。
世界のPCの95%はWindowsが占めるといわれている現在、どうしてLinuxの使い方について学ぶのでしょうか。これには明確な理由があります。Windowsが大多数のシェアを占めるのはPCでの話であって、メインフレームやサーバコンピュータではほとんどのOSはLinuxあるいはUNIXが占めています。通常のハッカーの攻撃対象となるコンピュータは個人のPCよりも企業のサーバである場合がほとんどです。私たちがまず知るべきOSはLinuxであるといえます。
Linuxは1991年にフィンランドのヘルシンキ大学の学生であったリーナス=トーバルズがUNIXを元に開発したOSです。開発当時はアセンブリ言語でプログラミングされていましたが、後にC言語で書き直されています。
LinuxはオープンソースのUNIXライクな(UNIXに似た)OSで、メインフレームから携帯電話、サーバなど非常に多くの分野で利用されています。Linuxとは本来、OSのカーネル(中核)部分のことを指しますが、カーネルはプロセス管理や記憶管理などを行うだけで、文章を書いたりWebサイトをみたりすることはできません。つまりカーネルだけでは我々がOSに求める機能を実現することはできません。ですので、OSにはカーネルのほかにワープロソフトやWebブラウザ、メールソフトなどが付属しています。
Linuxと一口にいっても、Red HatやDebian、SUSE Linuxなど様々な種類があります。これらの違いは、カーネルに付属するソフトウェアの種類の違いや、開発理念の違いなどです。例えばSUSE Linuxはグラフィカルなデスクトップに特化しており、Red HatはRPMというパッケージ管理ソフトが付属しています。それぞれ
に特化しているものや理念の違いなどがあり、こういったLinuxの種類のことをデストリビューションと言います。このレポートではDebianというデストリビューションのDebian GNU/Linux 3.1r1(Sarge)を用いて解説します。インストール時のパッケージコレクションは「デスクトップ環境」でインストールしていますが、他のパッケージコレクションでも問題はないでしょう。Debianのインストールについては他のドキュメントを参照するか、書店でDebian関係の雑誌や書物をお買い求めください。
まずはLinuxをインストールしましょう。LinuxはDebian GNU/Linux 3.1r1(Sarge)が望ましいですKnoppixやFedora Coreではうまく実験が進められない可能性がありますので、少なくともDebianを利用するようにしてください。Linux用のコンピュータを別に用意するのは簡単ではありませんので、他のOSをインストールしているHDDの空き領域にLinuxをデュアルインストールするとよいでしょう。注意点はWindowsとデュアルインストールする場合に先にWindowsからインストールすることと、インストール時に「全てのパーテーションを削除」のような項目を選択しないことです。インストールの方法は他のドキュメントを参照していただくこととして割愛させていただきます。
Debianがインストールできましたら、このレポートで主な操作画面となるシェル(ターミナル、コンソールとも呼ばれます)を使ってみましょう。シェル(Shell)とはOSの一部で、ユーザからの命令を受け付けてカーネルが理解できる命令に変換し、カーネルに引渡してプログラムの起動やファイルの削除などを行う役割を持ちます。また、カーネルからの出力を人が理解しやすい形に変換して表示する役割も持っています。通常シェルは文字によって入出力を行うCUIですが、WindowsやX Window SystemのようなGUIはグラフィカル・シェルとも呼ばれます。シェルという名前はOSの中核であるカーネルを貝殻のように囲って命令を受付け、それをカーネルに渡すためです。
+---------------------------------------+ | Shell | +--------+ | +------------------+ | | |---------[input]---------->|====[convert]====>| | | | User | | | Kernel | | | |<--------[output]----------|<====[convert]====| | | +--------+ | +------------------+ | | | +---------------------------------------+
シェルを起動してみましょう。Linuxの場合シェルはプログラムとして実装されていますので、他のプログラムと同様にメニューなどから起動させます。正確にはグラフィカルなインターフェースの裏側ではOS起動時に起動された根源となるシェルが動いています。私たちがシェルを起動させる時は、その根源シェルに新たにプログラムであるシェルを起動する命令を送り、それを根源シェルが解釈して新しくシェルを立ち上げます。そのためシェルを複数起動させたり、プログラムの中から別のプログラムを起動するようにシェルを起動させることが可能です。
デスクトップにタスクバーがあると思います。この中にコンピュータの形をしたアイコンがありますので、クリックしてください(図1)。アイコンが見つからない場合はタスクバー左端の[アプリケーション]→[Debianメニュー]→[アプリケーション]→[シェル]→[Bash]で起動できます(図2)。
(図1)http://ruffnex.oc.to/defolos/text1/figure/wb30_f00.jpg
(図2)http://ruffnex.oc.to/defolos/text1/figure/wb30_f01.jpg
シェルが起動するとウィンドウが開き、文字が表示されます(図3)。文字や背景の色は環境によって異なる可能性があります。また、グラフィカル・シェル(X Window)を導入していない場合はログイン画面から根源シェルが表示されますが、この場合白い文字に黒い背景になっていると思います。
(図3)http://ruffnex.oc.to/defolos/text1/figure/wb30_f02.jpg
シェルにはbashやcsh、tcshなどいくつかの種類があり、bashはcshや他のシェルを参考に機能拡張されたシェルです。Linuxの標準ではbashが使われます。シェルの操作は文字だけで行い、決められたコマンドを入力することでファイルの移動やフォルダの表示などを行います。シェルに「pwd」と入力してください。次のように何か表示されたと思います。
defolos@glazheim:~$ pwd
/home/defolos
pwdコマンドはカレントディレクトリを表示するコマンドです。ディレクトリとはファイルを格納した入れ物のようなもので、Windowsではフォルダと呼ばれます。カレントディレクトリとは「現在ユーザが作業を行っているディレクトリ」という意味です。
このようにコマンドで様々な操作を行っていきます。必要最低限のコマンドは後述します。ここではLinuxが起動できてシェルがどういった感じのものなのか感覚的に理解していただければ結構です。
通常のOSには権限という概念が存在します。権限とは操作を許可する範囲と考えてもらえれば良いです。例えばファイルに対して書き込みを行うという操作はそのファイルへの書き込み権限が必要です。コンピュータの管理を行う場合、アクセスできないファイルや実行できない操作があると管理ができませんので、ありとあらゆる権限を持った管理者権限というアカウントが存在します。これはLinuxではrootと呼ばれるアカウントです。Windowsの場合はAdministratorという特別なアカウントが管理者権限アカウントに該当します。
Linuxでは同じコンピュータに複数のユーザが同時にログインし作業を行うマルチユーザという考え方が強く、ログインするユーザは数多くいるユーザのうちの一人としてログインします。各ユーザーには専用のデスクトップやディレクトリが用意されますが、他のユーザのデスクトップなどに移動することも可能です。コンピュータを起動してログインすると一般ユーザ権限でログインすることになります。一般ユーザ権限は管理者権限とは違い、操作に多くの制限があります。例えば一部のファイルなどは読むことができませんし、サーバプログラムなどのように実行できないプログラムもあります。
実際の例を見てみましょう。シェルに次のようにコマンドを入力してください。
defolos@glazheim:~$ cat /etc/shadow
cat: /etc/shadow: 許可がありません
catコマンドはファイルの内容を表示するコマンドです。shadowファイルとはログインパスワードが暗号化されて保存されているファイルで、読み込みの許可はrootにしかありません。そのため、一般ユーザ権限から表示しようとすると、許可がないというエラーが返されます。
ファイルへのアクセス権限には「読み込み(r)」、「書き込み(w)」、「実行(x)」の3つの種類があり、これらの権限は「ユーザ」、「グループ」、「その他」の3つのフィールドにそれぞれ設定することができます。「ユーザ」はそのファイルの所有者(作成者)が許可される権限を設定します。「グループ」はファイルの所有グループに属するユーザに許可される権限を設定し、「その他」ではそれ以外のユーザに対しての権限を設定します。ファイルに設定されている権限を確認するにはlsコマンドを用います。
defolos@glazheim:~$ ls -l /etc/shadow
-rw-r----- 1 root shadow 793 2006-11-11 09:54 /etc/shadow
lsコマンドはディレクトリに含まれる下位ディレクトリやファイルを表示するコマンドですが、-lオプションを指定することで設定されている権限を確認することができます。ユーザ、グループ、その他の順にフィールドがあり、そのフィールドにr、w、xが設定されます。この例では先ほどのshadowファイルに設定されたアクセス許可を確認しています。「-rw-r-----」の部分がそれぞれ順番にユーザ、グループ、その他のフィールドであり、一番最初の「-」はファイルの種類(-ならファイル、dならディレクトリ)を表しているため無視して考えます。するとファイルの所有者は読み込みと書き込みの許可があり、グループには読み込みの許可があることがわかります。それ以外のユーザに対しては一切の許可がありません。rootと書かれた部分はこのファイルの所有者の名前です。shadowファイルはrootが所有者でありユーザdefolosはrootではありませんので、shadowファイルは表示できないことがわかります。
それでは自分がどの権限でログインしているのかを確認しましょう。Linuxの場合はシェルを開いたとき、プロンプトの前の記号が「$」のときは一般ユーザ権限で、「#」のときは管理者権限であるのが通常です。
しかし、これらの記号は管理者が自由に変更できるため、もしかすると一般ユーザ権限でも「#」の記号がついているかもしれません。ですので、より正確に自分の権限を知りたい場合はwhoamiコマンドを利用します。シェルを開き、whoamiと入力します。
defolos@glazheim:~$ whoami
defolos
ユーザ名が返ってきたときは一般ユーザ権限です。
glazheim:/home/defolos# whoami
root
rootと返ってきた場合には管理者権限です。管理者権限はそのコンピュータ上で神のように振舞えます。例えばユーザを削除したり、パスワードが保存されているファイルを閲覧することさえできます。この神の権利を奪うことが今回のレポートの目的です。
rootというのは特別なアカウントですが、suコマンドを用いることで一般ユーザ権限からrootアカウントにログインすることが可能です。次のようにコマンドを入力してください。Password:にはrootのパスワードを入力します。覗き見防止のため、パスワードの入力は表示されないようになっています。
defolos@glazheim:~$ su
Password:
glazheim:/home/defolos#
これで権限が管理者になりました。rootアカウントはコンピュータ起動時のログイン画面からログインすることはできず、このように一般ユーザ権限からsuコマンドでログインします。わずらわしいように感じられますが、rootはありとあらゆる権限を持っているため、システムの維持に必要なファイルでも間違えて消してしまう可能性があります。必要なときにだけrootになり必要性がなくなったら一般ユーザ権限に戻ることで必要なファイルを消してしまう危険性を抑えています。このような使い方をするため、起動時のログイン画面からはrootでログインできないようになっています。rootから抜けるにはexitコマンドを使います。
アクセス権限がなければプログラムの実行やファイルの読み書きが行えないことはわかりました。しかし、ただ権限にしたがって制限するだけではコンピュータをうまく管理することはできません。例えばパスワードの変更を考えてみましょう。
それぞれのユーザのログインパスワードを変更する際、Linuxではpasswdというプログラムを使ってshadowファイルを書き換えます。これは/etc/passwdのパスワードファイルとは違い、実行形式のプログラムです。shadowファイルはrootにしか書き込み権限がないことは確認できていますが、パスワードはそれぞれのユーザが自由に変更できなければなりません。もしrootだけがパスワードを変更できるようですと、それぞれのユーザはパスワードを変更したいときには毎回rootに頼んで変更してもらわなければならなくなります。これでは大変非効率なので、passwdはある仕組みを用いてこれを解決しています。passwdをlsコマンドで見てみましょう。
defolos@glazheim:~$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 26840 2006-08-12 08:24 /usr/bin/passwd
ユーザフィールドの実行権限の部分が「s」になっています。これはSUID(Set User ID)がセットされた状態であることを表しています。SUID権限がセットされたプログラムを実行すると、誰がプログラムを実行したかに関わらず、実行ユーザIDがファイルの所有者のユーザIDに変更されてプログラムが実行されます。プログラムが終了すれば実行ユーザIDは元に戻ります。
パスワード変更の例に戻りますと、パスワードを変更したいユーザはpasswdプログラムを実行します。passwdはすべてのユーザが実行できますが、passwdによって変更されるshadowファイルはroot以外書き込みできないため、そのままではエラーが発生します。そこでpasswdを実行する際、実効ユーザIDをrootに変更することで、あたかもrootがpasswdを実行したかのようにshadowファイルを書き換えることができます。所有者がrootでSUID権限が設定されているプログラムは、特にSUID rootプログラムと呼ばれます。SUID rootプログラムは言い換えるなら、プログラムが実行されている間rootの権限を持つプログラムだといえます。これは非常に重要な脆弱性に繋がる危険性があります。
前述したように、プログラムからシェルを起動することが可能です。もしSUID rootプログラムが正常に終了せずに、途中でシェルを起動してしまったとしたらどうなるでしょう。SUID rootプログラムは起動している間root権限を持つため、そこから呼ばれたシェルはroot権限で実行されたことになります。
次に本当にシェルからシェルを呼び出せるのか、プログラム内からシェルを呼び出せるのか、SUIDをセットした場合の挙動のテストを行います。
シェルからシェルを呼び出せるかどうかは次のようにして確認できます。ここではbinディレクトリにあるshというシェルを起動しています。bashも同じディレクトリ内にありますがbashはすでに起動していますので、bashを起動させても表示が変わらず分かりにくいためshを起動させています。
defolos@glazheim:~$ /bin/sh
sh-2.05b$
次にプログラム内からシェルを呼び出してみます。次のような非常にシンプルなソースから作ったプログラムを実行してみます。
#include <stdio.h>
int main (void){
execl("/bin/sh", "sh", 0, 0);
return 0;
}
5行目のexecle関数で/bin/shを呼び出しています。このソースコードをshtest.exeという名前でコンパイルし、実行すると次のような結果が得られます。コンパイルとは人が読みやすいように書かれたソースコードをコンピュータが理解できる命令に変換することです。詳しくは次回解説します。
defolos@glazheim:~$ ./shtest.exe
sh-2.05b$
シェルから呼び出したときと同じように、シェルを起動することができました。シェルが呼び出されるときのシェルやプログラムの実行はdefolosという一般ユーザ権限によって行われたため、新たに起動したシェルも一般ユーザ権限で起動しています。ここでshtest.exeをSUID rootプログラムにした場合にどのような挙動になるか確認してみましょう。SUID rootプログラムにするには対象のプログラムの所有者をrootに変更し、SUIDをセットする必要があります。この作業はrootでなければできないので、一度suコマンドでrootになります。その後、次のようにコマンドを入力します。
glazheim:/home/defolos# chown root shtest.exe
glazheim:/home/defolos# chmod +s shtest.exe
chownコマンドは対象ファイルの所有者を変更するコマンドです。shtest.exeの所有者をrootに変更しました。次のchmodコマンドは対象ファイルのアクセス権限を変更するコマンドです。shtest.exeにSUID権限を追加しています。この2つの作業でshtest.exeがどのように変更されたのか確認しましょう。
glazheim:/home/defolos# ls -l shtest.exe
-rwsr-sr-x 1 root defolos 11532 2006-11-13 01:40 shtest.exe
所有者がrootに変更され、SUIDがセットされています。この状態でshtest.exeが実行されれば、誰が実行したかに関わらず所有者であるrootの権限で実行されます。そして5行目のexecle関数で、権限がrootのままシェルが起動します。一般ユーザ権限に戻ってshtest.exeを実行してみましょう。
defolos@glazheim:~$ ./shtest.exe
sh-2.05b#
シェルの記号は変更されていますが、本当にrootなのか確かめる意味でwhoamiコマンドを使用します。
sh-2.05b# whoami
root
rootであることが確認できました。これは最も単純なバックドアの例であり、一般ユーザ権限からプログラムひとつを実行するだけでrootになることができます。このようにSUID rootプログラムは誰がプログラムを実行したかに関わらずroot権限でプログラムが実行されます。
残る問題は、どのようにSUDI rootプログラムの流れを変えて途中でシェルを起動するかです。
Linuxは近年ではWindowsのようにグラフィカルなシェル(X Window System)を備えており、マウスでファイルを移動したりアイコンをクリックしてプログラムを起動したりといったGUIの操作もできるようになっています。しかしGUIはあくまでCUIシェルに画像をくっつけたようなものですので、GUIでは行えない操作は多くあります。このレポートでもCUIでしか行えない操作を必要としますので、ここでLinuxを操作するために最低限必要なコマンドを挙げます。書式はcommand [option] argvとなっており、[]でかこった部分は省略可能です。
コマンドの使い方を表示します。使いたいコマンドの名前がわかっている場合はnameで直接指定し、名前がわかっていない場合は-kオプションを指定して検索したいキーワードを入力することでコマンドの検索ができます。
ディレクトリ内のファイルや下位ディレクトリを表示します。Windowsではフォルダアイコンをクリックし、ウィンドウを開いてフォルダ内のファイルや下位ファイルを表示しますが、これと同じことを行っています。ディレクトリとフォルダは同じ概念のものです。Windowsではディレクトリのことをフォルダといいます。なお、カレントディレクトリは「.」で、上位ディレクトリは「..」で表されます。
カレントディレクトリを[directory]に変更します。移動したいディレクトリを引数で指定すると、そのディレクトリに移動します。引数なしで実行するとホームディレクトリに移動します。
ファイルのコピーを行います。[source]にコピー元ファイルを指定し、[destination]にコピーしたあとのファイル名を指定します。
ファイルの削除を行います。
ファイルやディレクトリの所有者を[owner]に変更します。-Rオプションを選択すると指定したディレクトリ内の全てのファイルの所有者を[owner]に変更します。このコマンドはプログラムをSUID rootプログラムへ変更する場合に使用します。rootだけが実行できるコマンドです。
ファイルやディレクトリのアクセス許可を変更します。-Rオプションを選択すると指定したディレクトリ内のすべてのファイルの許可をtypeに変更します。ファイルあるいはディレクトリの所有者しかアクセス許可を変更できません。指定方法には絶対方式と相対方式があり、絶対方式は8進数の数字によって指定します。
今回は前提知識の確認として、ハッキングに必要なLinuxについての知識について解説いたしました。
次回はC言語とアセンブリ言語についての基礎知識を解説したいと思います。しばらくは前提知識の確認が続きます。これらの知識はハッキングと密接に結びついており、必ず必要となる知識です。基礎がしっかりしていれば後の理解も早いと思いますので、ゆっくりと前提知識の確認を行いたいと思います。