不正アクセス

 不正アクセスとは、本来アクセス権限を持たない者が、サーバや情報システムの内部に侵入する行為です。

 ここでは、本来の意味での不正アクセスに加えて、不正アクセスを行う準備段階としてアクセス権限を奪うための攻撃方法、またシステムの脆弱性をついて、本来ならば権限がないとできないことと同等なことを不正に行う行為などを含めて説明しています。

 方法としては、事前準備としてのポートスキャン、スニッフィング、ソーシャルエンジニアリング、不正アクセス行為としての、メモリバッファオーバーフロー、バックドア、スプーフィング、インジェクション、クロスサイトリクエストフォージェリ、セションフィクセーション、フィッシング、パスワードリスト攻撃などがあります。更に、スプーフィングとしては、代表的なものとして、IPアドレススプーフィング、ARPスプーフィング、経路スプーフィング、DNSスプーフィング(DNSキャッシュポイズニング)、TCPコネクションスプーフィング(TCPセションハイジャッキング)、Webセションスプーフィング(Webセションハイジャッキング)、メールスプーフィングなどの攻撃手法があります。インジェクションの手法としては、代表的なものとしてスクリプトインジェクション(更にスクリプトインジェクションの特殊な場合としてクロスサイトスクリプティング)、SQLインジェクション、HTTPヘッダインジェクション、メールヘッダインジェクション、OSコマンドインジェクションなどがあります。

 不正アクセスの結果として、管理者権限を奪われる、システムやデータを破壊される、機密情報や個人情報を盗まれる、メールを覗かれる、オンラインショッピングサイトで勝手に買い物をされる、他システム攻撃の踏み台とされる、ホームページを改ざんされるなどの被害を被ることになります。





1 事前準備

 攻撃者は攻撃をする場合に何をするでしょうか。相手はサーバでしょうか?それともクライアントマシンでしょうか?インターネットのサービスは基本的にクライアントサーバ方式を採用しているので、攻撃の対象はサーバとなるでしょう。ここでのサーバとはサーバ(サービス提供を行うアプリケーション)がインストールされているマシンという意味です。クライアントマシンにはサーバ(サービス)がインストールされていないので、外部から侵入することは難しくなります。

 標的がサーバマシンだとすると、具体的なサーバマシンはどのように選ぶのでしょうか?最初から、侵入する相手先が明確な場合もあるでしょう。しかし、弱そうな相手を物色して、そこに侵入するという場合もあります。OSは何が入っているのでしょうか?サーバはどんなサーバが動いているのでしょうか?サーバはポートによって相手を受け入れますので、そのポートが開いているかを調べなくてはなりません。幾つかのマシンを調べて、有名な脆弱性を抱えているサーバが動いているマシンはないか、見つけようとします。ファイアウォールがセットされている場合は、何とかしてファイアウォールを通り抜けなくてはなりません。IDSが動いているときは、IDSに気づかれないように侵入していかなくてはなりません。



1.1 DNSの情報を調べる

 DNS情報を調べるには dig、host、nslookup などの方法があります。

※従来はnslookupが一般的でしたが、UNIX、Linuxなどでは現在非推奨となっていて、より高機能なdigの利用が推奨されています。digはWindowsでも動きますが、標準ではインストールされていませんので、利用する場合は個別にインストールしなくてはなりません。

 digやnslookupを使うと、特定のドメインのA、MX、NS、PTRなどの情報を得ることができます。MXはメールエクスチェンジャつまり、メールサーバです。NSはネームサーバ、つまりDNSサーバです。Aはドメイン名にどんなIPアドレスが対応しているか、PTRはIPアドレスにどんなドメイン名が対応しているかの情報です。

 ネームサーバが分かれば、そのネームサーバがゾーン転送をしているかどうかを調べます(問い合わせにはパラメータとしてaxfrを使います)。すると、CNAME(サーバに別名がついているかどうかの情報)などから、Webサーバの名前が分かるかも知れません(CNAMEで、Webサーバの名前を"www"などに設定しているのが一般的です)。それと同時に、Webサーバのポートが分かります。80番ポートを使っているのか、それとも443ポート(https)あるいは、独自のポート番号(例えば8080など)を使っているかなどです。



1.2 ポートスキャン

 IPアドレスが分かったらポートスキャンをしてみるというのが一般的です。ポートスキャンはターゲットとなるコンピュータのTCPまたはUDPのポートに試験的に接続を試み、どのようなサービスが稼働している(Listen状態)かを調査する行為です。機能停止や侵入などの攻撃に使えそうなポートが開いていないかを網羅的に調べ上げるソフトウェアをポートスキャナーといいます。



1.2.1 ポートスキャンの種類

 ポートスキャンはその目的や手法によって、いくつかの種類に分けることができます。代表的なものをいくつか挙げてみます。

■ TCPスキャン
 普通にターゲットマシンにTCP接続を試み、接続が可能かどうかを調べる手法です。完全な3ウェイハンドシェークを行いますので、ポートスキャンの痕跡がサーバ上に残ります。

■ TCP SYNスキャン
 TCP SYNスキャンはサーバのログにスキャンの痕跡を残さないための工夫です。TCP接続を確立するためには3ウェイハンドシェークを行わなくてはなりませんが、TCP SYNスキャンでは、3ウェイハンドシェークを途中でやめて、接続が完成しないようにします。接続が完了しませんので、ログに痕跡が残りません。

 クライアントからサーバにSYNビットをセットしたパケットを送り、サーバ側からSYNとACKがセットされたパケットが返れば、サーバは生きていることになります。サーバがサービスを提供していない場合は、サーバ側のTCPはRSTビットをセットしたパケットを返してきます。このように3ウェイハンドシェークの最初のパケットを送っただけで、後はその答えを分析すれば、サーバがサービスを提供中であるかどうかが分かります。

■ ステルススキャン
 TCPスキャンや、TCP SYNスキャンはいつでもできるというわけにはいきません。このようなスキャンはよく管理されたファイアウォールを通過できないことが多いからです。

 ファイアウォールは内部ネットワークから外のインターネットにTCP接続することは許可するが、外のインターネットから内部ネットワークにTCP接続することは拒否するという方針で運用しているのが普通です。この方針の裏をかくとすれば、次のようなスキャンが成り立ちます。

 外からSYNパケットが来たら拒否しますが、外からSYN、ACKパケットが来たら通過させます。なぜでしょうか?これは内から外への通信の返事だと判断されます。しかも内から外への通信は許可されているのですから、返事も当然通過させなくてはなりません。でもいきなり、SYN、ACKパケットというのは3ウェイハンドシェークのルールに反しています。このルール違反のパケットに対してRSTフラグをセットしたパケットが返ってくるかどうかがポイントです。サーバが動いていない場合はRSTフラグをセットしたパケットが返ります。ポートが生きている場合は、エラーデータとして無視されます。

 ステルススキャンには、TCP FINスキャン、ACKスキャン、SYN/ACKスキャン、XMASスキャン、NULLスキャンなどの方法があります。
 TCP FINスキャンは最初にFINビットをセットしたパケットを送信する手法です。TCP ACKスキャンは、最初にACKビットをセットしたパケットを送信する手法です。SYN/ACKスキャンは最初に、SYNとACKビットをセットしたパケットを送信する手法です。XMASスキャンは、TCP Christmas Tree Scanとも言います。TCP XMASスキャンではTCPセグメントヘッダの制御フィールドの6つのビット(URG、ACK、PSH、RST、SYN、FIN)全てをセットします。TCP NULLスキャンは、XMASと逆で制御フィールドの6つのビットを全部OFFにして送信します。何れも3ウェイハンドシェークのルールに反していますので、サービス稼働中であれば無視され、サービス停止中なら、TCPがRSTパケットを返してきます。

■ UDPスキャン
 UDPの場合は、特定のポートにUDPデータグラムを送信すると、サービス提供中でない場合は、ICMPポート不到達(ICMP PORT_UNREACHABLE)メッセージが返ってきますが、サービス提供中は無視されますので、判断が可能です。



1.2.2 ポートスキャンはどのように行われるか

 ポートスキャンで有名なのが、Nmapというツールです。ただし、あまりにも有名なツールですので、標的サイトの管理者もNmapが動いていればすぐに気が付くと思います。

 IDSも最近のものはNmapを検知します。IDSはNmapを検出するとアラートを出しますので、それを見逃さないことです。

 用心深い攻撃者はNmapなどの有名なスキャンツールは使わないようです。Telnetを使うと手軽にスキャンができます。Telnetはリモートサーバにログインするためのツールとして有名ですが、これはTelnetのデフォルトポートである23番を使った場合のことです。Telnetはパラメータとして任意のポート番号を指定できますので、脆弱性が指摘されているポートにアクセスして、Listen状態のポートを見つけるために利用することができます。

 Telnetを使って、SSH(22番)、DNS(25番)、ゾーン転送(53番)、HTTPS(443番)などが開いているかどうかを調べていきます。

※ゾーン転送はDNSサーバ同士の情報交換です(DNSプライマリーサーバと、セカンダリサーバ間のデータの同期)。
※Telnetで確立したコネクションを抜けるには、"^]"でエスケープモードに移り、"quit"を実行してください。
※ファイアウォールでブロックされているポートにアクセスしてしまった場合は、タイムアウトするまで制御が戻ってきませんので、そのような場合は"Ctrl+c"で強制終了します。

 更にTelnetやdigが出すバナー情報に着目します。digを使って22番ポートにアクセスすれば、SSHのソフトウェアが分かります(例えばOpenSSHのversion?)。25番をスキャンすれば、メールサーバが何か分かります(例えば、Sendmailのversion?)。もしかしたら有名な脆弱性を持っているかも知れません。53番をスキャンすると、DNSのソフトウェアが分かります。BINDを使っていれば、BINDのバージョンが分かる場合があります(version4.9.5以上)。80番ポートをスキャンすると、HTTPサーバの種類とバージョンが分かるかも知れません(例えば、Apacheのバージョンがいくつで、SSLは何を使っているか。DAV、PHP、Perlなどのバージョンも分かるかも知れません)。

※TelnetでHTTPコネクションを確立することができれば、HTTPのメソッドを使うことができます。例えば、"HEAD /HTTP/1.0"で、[ENTER][ENTER]を2回実行します。

 バナー情報によって得た情報を元にすれば、使えるコマンドの幅も広がります。例えば、443番ポートを調べてOpenSSLが使用されていることが分かれば、OpenSSL付属のコマンドを使うことができます。

 161番がListen状態なら、net-snmpに付属するsnmpwalkコマンドを使って、SNMP MIB情報を入手します。MIBには対象サーバのシステム情報など様々な情報が含まれています。



1.2.3 ポートスキャン対策

 ポートスキャンを検出するポートスキャンディテクタとして有名なのが「PortSentry」です。
http://pocketstudio.jp/linux/?PortSentry

 ポートスキャンディテクタ以外ではファイアウォールも有効です。ファイアウォールは製品によってはステルススキャンの検出ができるものもありますので、導入する際にはよく調査してください。ポートスキャン対策を行うと大量のログが発生しますので、かえってDoS攻撃の餌食になりやすいという面もありますので、注意してください。

 ポートスキャン対策としては、不要なポートを閉じておくということも重要です。UNIX系の場合は、特に111番のrpcサービスは管理者権限を奪われる可能性がありますので、注意が必要です。79番のfingerもサーバのユーザ情報を抜き取られる脆弱性を持っています。Windows OSでは、137番と139番のNetBIOSが重要です。このポートが開いていると、サーバ名やIIS情報、稼働中のサービス、ドメイン等、ほとんどのサーバ情報を閲覧される危険性があります。



1.3 スニッフィング

 スニッフィング(sniffing)とはネットワークを流れるデータをキャプチャして解釈することです。スニッフィングを行うツールをスニファ(sniffer)といいます。スニファは、元々はネットワークのトラブルをデバッグするために開発されたツールです。スニファを使うとネットワーク上で何が起こっているかを知ることができます。管理者にとって重要なツールであるスニファは攻撃者にとっても便利なツールです。

※スニファはネットワークアナライザと呼ばれることもあります。

 攻撃者は攻撃を始める前に十分な情報を得ようとします。その方法の1つがスニッフィングです。



1.3.1 スニファの原理

 共通回線を利用するLANでは、データは全てのホスト(のインターフェース)のインターフェース(NIC)に物理的には流れていきます。しかし、通常の場合、ネットワークインターフェースは、自分自身を宛名(MACアドレス)とするデータ、あるいはブロードキャストアドレスのデータだけを保持し、それ以外のデータはたとえ物理的に受信したとしても破棄してしまいます。しかし、これではスニッフィングができません。スニッフィングを行うためには、宛先MACアドレスが自分宛でないときにもそれを保持しなくてななりません。

 自分のMACアドレス宛あるいはブロードキャストアドレス宛以外のデータ(フレーム)でもそれを保持するモードを無差別モード(promiscuous mode)といいます。このモードを利用するとスニファができます。
 スニファを利用すると、ネットワーク上を流れるデータのヘッダを分析したり、データの中身を見ることが可能です。ネットワークでデータをスニッフィングされると、コンピュータネットワークの安全上、機密にしておくべき多くの情報が漏えいする可能性があります。ネットワーク上を流れるデータの中には、MACアドレス、IPアドレス、IPルーティング情報、TCPコネクションを維持するためのシーケンス番号、認証情報(パスワード等)などが含まれるからです。



1.3.2 よく利用されるスニファ

 スニファには様々なものがあります。よく利用されているものには次のようなものがあります。

tcpdump
WinDump
Ethereal
Wireshark
Tshark
Ettercap
dSniff
Omnipeek
PRTG
Ngrep
Xplico
Narus
NetVCR
ClearSight
Colasoft Capsa
Sniffer Portable Professional
Sniffer Adaptive Application Analyzer

 tcpdumpはUNIX系のOSでよく利用されるスニファで、コマンドライン上で利用します。tcpdumpをWindows上で動くようにしたものがWinDumpです。同様のものをGUIで動くようにしたのがWiresharkです。Wiresharkの元になったのがEtherealで、Wiresharkのコマンドラインインタフェース(CLI)版がTsharkです。



1.3.3 スニッフィング対策

 スニッフィングによる情報漏えいを防ぐ最も効果的な方法はネットワークのセグメントを小さくすることです。ネットワーク機器をハブからスイッチに変更してください。スイッチは学習機能を備えていて、宛先の存在しないポートからフレームをフラッディングすることはありません(ブロードキャストは除く)。

 スニファが動作しているシステムはネットワークインタフェース(NIC)が無差別モードになっていますので、ifconfig(UNIXコマンド)などを使って確認してください。スニファはプロセスリストにも表示されますので、psコマンドで確認できます。ただし、スニファの名前を変えていると思いますので、プロセス名で気づくかどうかは分かりません。スニファは時間の経過とともに大きなログファイルを作りますので、ファイルの大きさにも注意してください。ただし、隠しディレクトリにログファイルを残している場合には気が付きにくいと思います。



1.4 ソーシャルエンジニアリング

 ソーシャルエンジニアリング(「社会工学」)といっても学問の一分野というわけではありません。元々はクラッカー用語で、情報技術を使わずにパスワードなどの重要情報を盗み出す方法です。その多くは人間の心理的な隙や行動のミスにつけ込むものです。代表的なものは電話でパスワードを聞いたり、肩ごしにパスワード入力を盗み見たり(ショルダーハッキング)、ごみ箱漁り(トラッキング)をするなどです。

 電話による方法がよく利用されます。何らかの方法で、ユーザ名を入手したら、そのユーザの振りをして、管理者に対してパスワードの再設定の依頼をしたり、あるいは逆に管理者を装ってユーザのパスワードを聞き出そうとしたりします。電話によるパスワード変更依頼は、受け付けないように、社内規則、学内規則を決めておく方がいいでしょう。例えば、パスワード変更には、必ず本人が職員証、学生証を持参のうえ、対面で直接依頼しなくてなならないとセキュリティポリシーの実施基準等で定めておきます。

 ショルダーハッキングは、パスワードなどの重要な情報を入力しているところを後ろから近付いてのぞき見する方法です。肩ごしに覗くところからショルダーハッキングなどと呼ばれます。たとえオフィス内であっても、パスワードやクレジットカードの番号などを入力するときは周りに人がいないか注意してください。長いパスワードは覗かれたとしても、簡単には記憶できませんので、12桁位のパスワードを使ってはどうでしょうか。

 トラッキングはごみ箱に捨てられた資料(紙や記憶媒体)から、サーバやルータなどの設定情報や、ネットワーク構成図、IPアドレスの一覧表、ユーザ名やパスワードなどの情報を探し出す方法です。紙や記憶媒体を廃棄する際にはシュレッダーにかけたり、溶解するなどの方法をとることが重要になります。



1.5 エラーメッセージからの情報入手

 エラーメッセージから情報を入手できる場合もあります。サーバに対して理解不能なコマンドを実行すると、何らかのエラーメッセージが返ってくることがあります。

 WebサーバのIPアドレスが分かっている場合は、そのWebサーバが持っていないと思われるファイルを要求します。その場合にはエラーメッセージが返されて、そこにWebサーバの種類、バージョンを示すシグネチャがついていることがあります。

 メールサーバのIPアドレスが分かっている場合には、そのメールサーバ上の、存在しないと思われるメールアカウント宛にメールを送信します。すると、エラーメッセージが返ってきて、メールヘッダのReceivedフィールドの情報から、メールサーバが使用しているソフトウェアやバージョン、更にどのような経路でメールが配送されたかも特定することができます。



1.6 おしゃべりなサーバを黙らせる

 余りにも情報を与えすぎるサーバは危険ですので、外部に余り情報を与えないように設定してください。ただし、OpenSSLのように変更できないものもあります。

 Appacheの場合はhttpd.confでServer TokensとServerSignatureを変更してください。ServerSignatureはoffに設定します。デフォルトでは、Server Tokensの項目はありませんので、ServerSignatureの次あたりに"Server Tokens ProductOnly"を追加します。

 BINDでもversion情報をしゃべらないように設定します。named.confのoptionsで、「version "unknown"」と設定してください。

 ゾーン転送はスレーブ(セカンダリ)ネームサーバにだけ許可すればいいので、それ以外からのゾーン転送要求は拒否するように設定してください。デフォルトでゾーン転送を全面的に禁止し、特定のスレーブにだけ許可するように設定すればいいでしょう。

 メールでは「Received:」ヘッダフィールドでバージョン情報を表示しないように、それからhelpコマンドでバージョンを表示しないように設定してください。





2 メモリバッファオーバーフロー攻撃

 事前調査でどんなOSが使われているか、Webサーバは何で、バージョンはいくつでとか、メールサーバは何でとか、いろいろのことが分かったはずです。これらの情報から、どこに脆弱性があるかを見極めます。
 
 CERT Advisoryを見れば、どこに脆弱性があるか分かります。情報を総合して、メモリバッファオーバーフローの脆弱性があると判断したら、そこを攻めていきます。



2.1 メモリバッファオーバーフローとは

 メモリバッファオーバーフローはノイマン型アーキテクチャのコンピュータに開発当時からついて回る脆弱性です。最初にインターネット上に出現した「モリスワーム」(1988年のRobert Morris worm事件)というウィルスもメモリバッファーオーバーフローを用いています。
 メモリバッファとはプログラムの実行中に一時的に確保される、コンピュータメモリ上のある領域です。メモリ中に確保されるバッファは、通常、論理的に連続したメモリの中で、他の領域と隣接して存在しています。この領域にデータを格納しようとする場合、CPUは基本的に、そのバッファの大きさと、収めようとするデータの大きさを比較して、そこに収めるかどうかの判断をするというようなことはしていません。そのため、時として入力データが大きすぎて、当該バッファに入りきらず、隣接(アドレスが大きくなる方向)のバッファにまであふれてしまうことがあります。これが、メモリバッファオーバーフローという現象です。



2.1.1 メモリの配置

 メモリの配置はOSなどの処理系によって異なりますが、大体次のように配置されています。スタック領域はプログラム本体よりも後ろ(アドレスの上位)に確保されています。


 外部変数や局所変数は静的メモリ割り当てといって、変数を宣言する時点でまだ変数に値が入っていなくてもメモリの一定範囲を確保します。外部変数が一定の範囲を確保するのがデータ領域で、局所変数が確保するのがスタック領域です。関数の引数もスタック領域に確保されます。いずれもコンパイル時にその大きさが決定されるので、プログラムを実行している最中にサイズを変更することはできません。従って、予め決まったサイズ以上にデータを書き込めば、他のデータを破壊して、最悪の場合はプログラムは暴走します。

 プログラムの作成時には大きさがなかなかはっきりしないデータもあります。こういう場合は思いっきり大きな領域を確保しておくという手もあります。最近では、10G程度のメモリを搭載しているパソコンも珍しくありませんので、こういう場合は余り気にしなくてもいいのかも知れません。しかし、使用できるメモリが少ない環境では、プログラムを実行することができない可能性もあります。このような場合は、プログラムの実行中に必要なサイズが判明した時点で、その大きさのメモリをどこかから確保してくるという方法がとられます。この方法を「動的メモリ割り当て」といい、この時に利用されるのがヒープ領域です。メモリの自動割当は、C言語ではmalloc、callocや、reallocなどの関数を使います。mallocとcalllocは新しくメモリを割り当てる場合に使用し、reallocはサイズを変更する場合に利用します。callocはメモリ領域を確保するときに、領域を"0"に初期化しますが、mallocは領域の中身は不定です。

 使い終わったメモリは解放しないと、その部分は使えません。開放するにはfreeという関数を使います。ただし、殆どの処理系では、プログラムの終了時にはプログラムで使ったメモリを解放するようになっていますので、freeで解放する必要はありません。



2.1.2 スタック領域

 スタックは、通常アドレス「0xffffffff」からアドレスの小さいほうに伸びていくメモリ上のアドレス領域です。通常のコンピュータアーキテクチャでは、関数が呼び出され、それがプロセスになりますが、プロセスに必要なローカル変数や引数を保存するための枠がスタック領域に作成されます。このプロセス(関数)毎に作成される枠を「スタックフレーム」といいます。このスタックのトップはスタックポインタとして、レジスタに保存されます。スタックポインタはスタックフレームを積む毎にアドレスの小さいほうに向かって進み(push)、取り出すときはアドレスの大きな方向に向かって移動します(pop)。つまり、スタックはメモリ上のアドレスの大きな領域に確保される後入れ先出し(LIFO)のバッファということになります。


 C言語のプログラムを例にとって考えてみます。C言語のプログラムでは初めにmainという関数が呼び出されます。このmain関数がプロセスとなります。プロセスとなると、スタック領域にmain関数用のスタックフレームが確保されます。スタックフレームは確保されても最初は空っぽで、スタックフレームの底を示すベースポインタ(CPUのレジスタであるebpの値)とスタックフレームの一番上を示すスタックポインタ(CPUレジスタのespの値)が決まります。プログラムが動き出すと、スタックフレーム内にデータが書き込まれていきます。

 main関数が最初に呼ばれます。関数を呼ぶときはcallという命令が使われます。この命令は指定された関数を呼び出すと同時に、呼び出し元に戻るための情報(関数呼び出し命令の次の行に戻ります)をスタック領域に格納します。main関数が呼ばれると、main関数用のバッファ領域が確保され、底の部分がbsp(ベースポインタ)、先頭の部分がesp(スタックポインタ)によって指し示されます。


 次にmain関数が別の関数を呼び出します。関数を呼び出す場合はcall命令が実行されます。call命令が関数を呼び出すときは、関数に渡す引数がスタックに積まれ、次に戻り番地(リターンアドレス)が積まれます(戻り番地は、関数を呼び出した行の次の行)。


 呼び出されたサブ関数Aの処理が始まると、関数A用のバッファ領域が確保され、ローカル変数の領域が確保されます。




2.1.3 バッファオーバフローとは

 メモリバッファオーバーフローは、どのメモリで発生するかで、2つに大きく分類されます。1つはスタックバッファオーバーフローと、もう一つはヒープバッファオーバーフローです。

 スタック領域はローカル変数、関数の引数、戻り値、戻りアドレス(リターンアドレス)等、プログラム処理中に一時的に使用するデータを格納するメモリ領域です。スタックバッファオーバーフローは、バッファーオーバーフローを利用してリターンアドレスを書き換えてしまうものです。

 説明を簡単にするためにA関数用のバッファ領域にローカル変数a用のバッファと、ローカル変数b用のバッファを用意するものとします。aのサイズが15バイトでbのサイズが2バイトだとします。ここで、サイズをsizeof(a)と指定して、変数aを変数bにコピーするとします。CPUは変数b用のバッファのサイズがいくつか知りませんので、命令されるままに、変数aのサイズ分のデータをバッファbにコピーしてしまいます。すると、変数bのバッファ領域を超えて、値がコピーされてしまいます。この時、「ebp」と戻り番地まで値が上書きされてしまうかもしれません。これがスタックバッファオーバーフローという現象です。


 戻り番地に例えば、ARACという値が書き込まれてしまうと、ASCIIコードでA=0x41、R=0x52、A=0x41、C=0x43ですから、Intelのプロセッサでは戻りアドレスは0x43415241となり、ここに悪意のプログラムを埋め込むことができれば、システムを思い通りに操作することができます。

 ヒープ領域はプログラムが永続的に利用するメモリを動的に確保する際に利用される領域です。ここで発生するバッファオーバーフローはヒープバッファオーバフローと呼ばれます。スタック領域のデータは、それを使用する関数が終了した時点で消えてしまいますが、ヒープ領域は特定の関数とは関係なく永続的に確保される領域ですので、関数が終了したからといって解放されません。malloc()や、calloc()で確保したメモリはfree()で解放しない限り、そのまま残ってしまいますので、オーバーフローしてしまう可能性があります。ヒープバッファをオーバーフローさせることを利用して不正なコードを実行することは、スタックバッファオーバーフローに比較すると、困難であるとされていますが、不可能ではありません。ヒープ領域のメモリ管理方法を巧みに利用して、任意のメモリ領域に任意のコードを書き込み、不正なコードに制御を移すという攻撃方法が知られています。



2.2 メモリバッファオーバーフロー攻撃

 ヒープ領域のバッファオーバーフローを利用することで攻撃をする手法も不可能ではありませんが、一般的にはスタック領域の戻りアドレスを書き換えることで攻撃する手法が一般的ですので、ここではスタックバッファオーバーフロー攻撃について説明します。

 前の節で、戻り番地が格納されたメモリ領域が「0x43415241」と上書きされて、もし「0x43415241」に悪意のプログラムを埋め込むことができれば、制御を奪うことができますと書きました。確かにその通りです。ただ、それは言うは易く行うは難しです。


 攻撃者が試行錯誤を繰り返しながらという条件が付けば、少し簡単になります。例えば、メモリバッファオーバフロー用プログラムのある部分に攻撃用のattack-onという名前の関数を置き、そのattack-on関数が何処に配置されているかを調査してから、戻り番地をそのアドレスになるように、書き換えてしまえば、攻撃はうまくいくかもしれません。

 とりあえず、attack-on関数がメモリ上のどこに配置されたかを調べます。戻り番地はでたらめなままで構いません。戻り番地がでたらめなら、そこでプログラムは止まります。止まる直前に、attack-on関数が配置されたアドレスを表示するように設定すれば、attack-on関数のアドレスを知ることができます。attack-on関数のアドレスが分かれば、(メモリバッファオーバフローを利用して)戻り番地をそのアドレスに書き換えて、今度は本当の攻撃を実行することができます。



2.3 メモリバッファオーバフロー型のウィルス

 今までは、攻撃者がリモートのホストから標的ホストを攻撃する、自由に制御するなどを中心にして説明してきましたが、ここではメモリバッファオーバーフローの脆弱性を利用したウィルスについて考えてみたいと思います。

 先ほどまでの攻撃プログラムでは、攻撃用のコードを記述した関数のアドレスを調べました。この攻撃用のコードがどこに配置されるかは環境によって様々な値になるはずですので、いちいち調べなくてはなりません。調べたことを元にしてソースコードを書き直し、戻り番地が攻撃コードが置かれたアドレスを指すようにします。しかし、このように何度も試行錯誤を繰り返しながら攻撃するということでは、ウィルスはできません。ウィルスの場合は攻め始めたら休まずに攻め続け一気呵成にコンピュータを乗っ取ってしまわなくてはならないからです。

 ウィルスはCPUやOSに備わっている例外処理のルーチンを利用して攻撃を行います。次に説明するのはWindows98の場合の例です。

 戻り番地に戻ったら、そこに実行可能なコードがないという場合、エラーメッセージを表示します。しかし、この後どうしたらいいか分かりません。Intelのプロセッサなら、割り込み処理をします。プロセッサーは予めOSによって登録された処理に制御を移しますが、割り込みが発生したときに開始されるプログラムは「割り込みハンドラ」といいます。割り込みにはいくつかの種類があるのですが、どうにもこうにも動きが取れなくなってしまった時には「例外」という処理をします。例外が発生したときに動作するハンドラは「例外ハンドラ」と呼ばれています。

 例外ハンドラが起動すると、Windows OSはエラーメッセージを表示することが多いです。例えば「不正な処理が行われたので、強制終了します。」などと表示します。UNIX系の場合はcoreダンプというデバッグ用のファイルを出力して、アプリケーションを強制終了します。

 実はメッセージの表示だけでなく、いろいろことをしているようです。割り込み発生時のアプリケーションソフトウェアの様々な情報を取得する処理もしていますし、デバッガーの起動も行っています。例外ハンドラが起動するプログラムはアプリケーションソフトウエアによって決まっています。何を起動するかという情報はスタック領域に格納されています。Windowsの場合はスタック領域の底(というかアドレス的には一番上位;0XFF FF FF FF)にあります。ここにメッセージを表示するプログラムの場所を示すアドレス情報が格納されています。ここで示すアドレスを書き換えてしまうと、書き換えたアドレスに制御が移るはずですが、ここに実行可能なコードがないと、また例外処理が始まり、スタックの底の部分を参照に行き、ここでまた実行可能なコードがないということで、例外処理が始まるということになります。このループに入ってしまうとどうなるでしょうか?例外ハンドラも普通のプログラムですので、メモリを消費します。正常終了している場合は、使ったメモリは動作終了時に解放するのですが、異常終了しているので獲得したメモリ領域は解放されず、そのままの状態で残りますので、しばらくするとスタック領域はなくなってしまいます。ここで、「スタック領域がなくなった」という特別の例外処理が始まります。Windows 98ではこの時、CPUのレジスタのEBXが「メッセージを表示するプログラムの場所」情報の4バイト手前を指すという特徴を持っています。従って、その4バイト手前に悪意のプログラムを置けば、メモリーバッファオーバーフローのエラーのしばらく後にその悪意のコードが動き出すということになります。

※メモリを4バイトずつ1行で表示すると、4バイト手前ということは、1行手前ということになります。

 以上に説明した部分は非常に有名で、Microsoft社も当然そのことに気づいていますので、Windows XPでは例外ハンドラの動きを一部変更しています。



2.4 シェルコード

 バッファオーバーフロー攻撃の際は、シェルコードと呼ばれる不正コードをターゲットのコンピュータに送ります。シェルはご存知の通りユーザとOSの間のやり取りを仲介してくれるソフトウェアで、Windows系ならDOSプロンプトやpowershell、UNIX系ならBourne Shellなどがあります。シェルコード(Shellcode)とはシェルを起動するためのプログラムのことで、通常マシン語を使って書かなくてはなりません。CPUが直接実行するマシン語の形態をとっているためターゲットのCPUやOSに依存します。つまり、CPUやマシン語毎に作る必要があります。また、作る場合は、かなりのスキルを必要とします。ただ、主要なOSのシェルコードはインターネット上にフリーのものが数多く出回っていて、攻撃者はそれらの中から用途に合わせて選択するだけです。用途に合わせてシェルコードを自動生成してくれるツールも出回っています。

 シェルコードを送り込まれたときに怖いのが、SetUIDをセットされたファイルで、root権限を奪われるということです。UNIXをご存知の方は直ぐに分かると思いますが、UNIXについて知らないという方には、説明が必要になります。



2.4.1 UNIXファイルとプロセスの所有権

 以下、しばらくUNIXについてご存じないという人のために入門レベルの説明をしますので、UNIXについて知っている方は飛ばしてください。

 UNIXはマルチユーザシステムを採用しています。マルチユーザシステムでは、複数のユーザがネットワーク等を介して同時に操作することがあります。このような時に、異なるユーザが互いに干渉しあわない仕組みが必要となります。

 コンピュータの利用者にとってファイルは貴重な財産ですが、マルチユーザシステムでは、このファイルを他の利用者の不正な(あるいは誤った)操作から守る必要があります。そのため、UNIXではファイルに所有権を付与し、アクセス権を設定しています。ファイルの所有者を識別するのが、ユーザIDとグループIDです。プログラムもファイルの形式で保存されますので、当然所有権がついています。このプログラムを実行すると、プロセスとなります。プロセスはプログラムがメモリ上にある状態です。あるプログラムの所有者がアリスだとします。アリス所有のプログラムを実行して、プロセスが発生すると、そのプロセスの所有者もアリスとなります。そのプロセスがファイルを生成した場合は、そのファイルの所有者もアリスです。

 では、ボブの所有するプログラムを、アリスが実行した場合、発生したプロセスは誰のものでしょうか。普通の考え方は、アリスが実行したのだから、発生したプロセスはアリスのものだというものです。アリスは自分のファイルを処理するために、ボブのプログラムを使ったら、プロセスもボブのものになり、処理したファイルもボブのものに変わってしまうということになると、自分のプログラム以外使えないことになります。様々なプログラムを個々のユーザ用に用意しなくてはなりません。これは事実上は無理です。
 もう一つの考え方は、ちょっと特殊ですが、ボブのプログラムなのだから、プロセスはボブのものだとする考え方です。UNIXはこちらの考え方も採用しました。何でこんな考え方が必要なのでしょうか。

 ユーザが自分のパスワードを変えたいという場合を考えてみましょう。パスワードを変更するプログラムは/bin/passwdです。このファイルの所有者はrootです。それから、パスワードファイルは/etc/passwdです。これも所有者はrootです。

 アリスが自分のパスワードを変更したいという場合、他人(root)のファイル(/bin/passwd)を使わなくてはなりません。これを使って、パスワードファイル(/etc/passwd)を変更したら、このパスワードは、アリスのものになってしまうというのでは困ります。/etc/passwdの所有権がアリスのものとなると、アリスは他人のパスワードも勝手に変更できてしまいます。



2.4.2 SetUIDとroot権限

  ここで、UNIXはうまい方法を導入しました。それは、アリスがroot所有のファイルである/bin/passwdを実行したときに発生するプロセスはroot所有のプロセスとなり、そのプロセスは自分所有のファイルである/etc/passwdの中身を修正できるという手法です。ただし、この手法はどんな場合にも認めると危険ですので、必要な場合にだけ認めています。この方法を認めるために、導入されたのがSetUIDという考え方です。SetUIDがセットされているファイルを利用したときには、プロセスの所有者は、そのSetUIDのセットされているファイルの所有者になります。つまり、/bin/passwdファイルの所有者はrootですので、アリスが/bin/passwdを実行しても、プロセスはroot所有(権限)となりますので、/etc/passwdを書き換えることができるというわけです(もちろん、アリスは自分のパスワードしか修正できません)。また、/etc/passwdはroot所有のファイルですので、アリスには閲覧できません。

※1つ1つのファイルにはファイルの所有者や、アクセス権を示すためにモードやユーザID、グループIDなどがついています。モードは、読み取り(read)、書き込み(write)、実行(execute)などのアクセス権を設定するためのもので、ファイルの所有者(owner)、グループ構成員(group)、その他の全てのユーザ(others)に対して、それぞれ読み取り権(r)、書き込み権(w)、実行権(x)を並べて記述した形式になっています。従って、"-rwxr-xr-x"のようになります。これは所有者の権限は、読み取り、書き込み、実行を全て認め、グループとその他のユーザに対しては、読み込みと、実行権だけを認め、書き込み権は認めないという場合の例です。先頭のブロックはディレクトリを表す部分で、ディレクトリの場合は"D"をセットし、ファイルの場合は、ハイフォンとなっています。SetUIDを設定すると、所有者のブロックの"x"の部分が"s"になります。従って、"-rwsr-xr-x"となります。この場合の"s"はSUIDビットと言います。

 SetUIDを使うと通常root(スーパーユーザ)でないとできないことを、一般ユーザに認めることができます。一般ユーザにいつでも、root権限を与えてしまうと非常に危険ですが、SetUIDを使うと、そのコマンドを使うときに限ってrootの権限を行使することができます。

 メールボックスへの書き込みなども同様です。あなたが、アリスにメールを出すとします。あなたは、アリスのメールサーバの/var/spool/mail/aliceに書き込みをしなくてはなりませんが、多分このファイルはrootしか触れないようにセットされています。このような場合には、メールのプログラムにSetUIDを設定します。メールの所有者はrootですので、あなたがメールプログラムを使うときは、root権限を使って、アリスのメールボックスに書き込みをすることができます。

 シェルコードを仕込んだ攻撃用のファイルをroot所有にして、SetUIDを設定したうえで、メモリバッファオーバーフローの脆弱性を悪用すると、root権限でシェルを起動することができます。ローカルログオンした一般ユーザがバッファオーバーフローの脆弱性を利用して、root権限を奪い、不正なコードを実行させることは十分に考えられます。root権限でシェルを起動したとしても、これをリモートから制御できるかどうかはさらに難しい関門があります。バックドアなどを開けて、更に攻撃をし易い形にしてしまおうとするかもしれません。



2.5 メモリバッファオーバーフローの対策

2.5.1 利用者側の注意

<対策1> セキュリティパッチを適用する
 バッファーオーバーフローはプログラミング上のミス(バグ)ですので、通常はソフトウェア開発者(Windowsで言えば、Microsoft社)から、バグを修正したパッチが提供されますので、それを適用します。

<対策2> 不要なネットワークアクセスを制限する
 バッファオーバーフロー攻撃は、ネットワーク経由でウィルスを侵入させたり、不正侵入したりという場合がありますので、ファイアウォール等を利用して、不要なネットワークアクセスは制限するようにしてください。

<対策3> 不要なサービスプログラムを停止する
 ネットワークサービスを提供しているシステム(例えばWeb)がバッファオーバーフローの脆弱性を持っている場合は、ネットワーク経由で、コンピュータ上で不正コードを実行される可能性があります。Windows NT/2000/XPには「メッセンジャ」というサービスがデフォルトで起動していました。これはWindows マシン同士でメッセージを交換するためのツールですが、このサービスにメモリバッファオーバーフローの脆弱性が発見されたことがあります。多くのOSで、標準に数多くのサービスが起動していますが、本当に必要なものかよく検討して、必要のないものは起動しないようにしてください。



2.5.2 開発者側の心得

 開発者はバッファにデータを書き込む場合には、その領域を超えて書き込みをしないように注意しなくてはなりません。

<対策1> ループを回しているときに、バッファ溢れを起こさないように注意
 ループを回すときは、1回回るごとにバッファ境界をチェックし、バッファ溢れになる前にループを抜けるようにしてください。

<対策2> 書き込み先のバッファサイズを指定する
 標準Cライブラリに古くからある関数には書き込む先のバッファの境界を無視したものがありますが、これらの関数はバッファーオーバーフロー問題を引き起こします。この反省の下に、現在の標準Cライブラリ関数には書き込みバイト数制限機能の付いたものが、代替関数として用意されていますので、それを利用してください。

 危ない関数の代表がstrcpyですが、書式は次のようになります。

char *strcpy(char *dest, const char *src)
 
 strcpyはsrcが示す文字列を、destが示す配列にコピーする関数です。代替関数として用意されているのはstrncpyです。strncpyはコピーする文字数を指定することができます。書式は次の通りです。第3引数として、コピーする文字数を指定します。

char *strncpy(char *dest, const char *src, size_t n)
 
代替関数の多くは、文字のバイト数の上限nを指定できるという意味で、"n"という文字がついています。代替関数の例としては次のようなものがあります。get() ⇒ fgets()、sprintf() ⇒ snprintf()、strcat() ⇒ strncat()、strcpy() ⇒ strncpy()、vsprintf() ⇒ vsnprintf()

<対策3> 上限サイズのバッファを用意する
 バッファへの書き込みバイト数の上限を指定できない関数も存在します。このような場合でも、関数に与える引数に上限がある場合があります。このような場合は、その上限のサイズのバッファを用意すると、オーバーフローを防ぐことができます。

<対策4> 安全を補完するツールの使用
 バッファオーバーフローの対策を施されたライブラリやツールがいくつかありますので、紹介します。

■ StackGuard
 StackGuardは、OSやライブラリの入れ替えではなく、コンパイラを入れ替えることでバッファオーバーフローを防ぐ方法です。StackGuard付きでコンパイルすると、実行時にリターンアドレスの後ろに「カナリア」と呼ばれる確認用のコードが入れます。もし、関数が戻された場合にこのコードが変更されたら、バッファオーバーフローが発生したと判断し、プログラムを停止させます。StackGuardはGNU C Compiler(gcc)の拡張版です。gccの拡張版としては、他に「StackShield」があります。

 StackGuardはバッファオーバフローを検知した場合に、プログラムを緊急停止させてしまいますので、サーバプログラム等の安定稼働が必要な環境には向いていないと批判されることもあります。

■ カーネルの変更
 プログラムはOS上で動作しますので、OSレベルでバッファオーバーフローを制御するという考え方があります。カーネルを入れ替えてしまいますので、対応のものが見つかるかという問題もあります。

 Openwallという方法はLinuxのカーネルを入れ替える方法です。この方法は戻り番地の書き換えそのものを防止するわけではありませんが、戻り値の値がスタック領域内の場合はプログラムの実行を一律に禁止します。

※<CPU、OSレベルの対策>NXビット(No eXecute bit)の利用が考えられます。NXビットは「データの誤実行」を防止するための仕組みです。メモリをコード領域とデータ領域に分け、データを配置した領域には予め特別な印をつけておき、そこでプログラムの実行をできないようにしておきます。この方法を使うとCPUとOSの協調によりスタック領域でコードが実行されるのを防止することができます。

※NXビット自体は汎用機やワークステーションなどの分野では以前から使われていましたが、パソコンの分野ではAMD64で初めて搭載されています。AMDがこれをNXビットといったためにこの名前が一般化しています。Intelはこの機能をXD(eXecute Disable)といっていますが、機能は全く同じです。

※汎用機はメインフレームと呼ばれた大型コンピュータで、以前は企業等の基幹業務(給与計算等)でよく利用されていました。ワークステーションは科学技術計算や、CAD、グラフィックデザイン、組版、事務処理などに特化した高機能な計算機を指すことが多かったのですが、現在はパソコンのうちで特に高性能なものを指すことが多くなっています。

 Solaris 2.6以降のSPARC版では、カーネルのオプションを変更することで、バッファオーバーフローをある程度防止することができます。


■ Cライブラリの入れ替え
 Cライブラリをそっくり入れ替えてしまう方法ですので、OSに対応したライブラリを見つけなくてはなりません。

ⅰ) Windows用
 Windows用のライブラリとしては、「ISO/IEC 9899:2011 Annex k」というライブラリがあり、Microsoft Visual Studio 2005以降で利用できます。出力バッファのサイズを引数に渡す等のセキュリティ対策がとられています。
https://msdn.microsoft.com/ja-jp/library/wd3wzwts(VS.80).aspx

ⅱ) GNU/Linux用
 Linux用としては、Managed Stringライブラリや、libsafeなどがあります。libsafeにはRPMも用意されていますので、便利です。
https://www.securecoding.cert.org/confluence/display/c/Managed+String+Library
http://directory.fsf.org/wiki/Libsafe

ⅲ) UNIX、Win32対応
 UNIX、Win32に対応できるライブラリとしては、safestrがあります。
https://buildsecurityin.us-cert.gov/articles/knowledge/coding-practices/safestr

 バッファオーバーフロー対策のライブラリやツールを利用すると多くのバッファオーバーフローを防止できますが、全てを防止できるわけではありません。ライブラリそのものを入れ替えてしまう方法はかなり強力ですが、これもスタック領域のオーバフローには対応できても、ヒープ領域のオーバーフローには対応できないようです。更に、スタック領域のオーバーフローにしても100%大丈夫というわけにはいかないようです。これらのソフトウエアそのものにセキュリティホールが見つかったこともありました。全てツールに頼り切ってしまうのではなく、ソースコードそのものに安全対策を施したうえで、あくまでも補完策としてツールを利用するようにしてください。

参考資料
https://www.ipa.go.jp/security/awareness/vendor/programmingv1/b06_01.html
http://www.st.rim.or.jp/~shio/csm/winbof/
http://itpro.nikkeibp.co.jp/members/ITPro/SEC_CHECK/20020920/1/
http://hack.ninja-web.net/academy003-056.htm
http://www.atmarkit.co.jp/ait/articles/0803/21/news151.html




3 バックドア

 バックドアは直訳すると「裏口」あるいは「勝手口」のことです。コンピュータセキュリティでは、本来IDやパスワードを使って利用権を確認して(認証システム)、認証の得られたユーザにだけ、アクセスを認めるところを、認証システムを回避して(アクセス制御の迂回)、無許可でシステムにアクセスするために設けられた秘密の入り口のことを指します。

 一度システムに侵入した攻撃者は、後日システムに侵入したいと思うかもしれません。しかし、その時利用した侵入口が次回の侵入の際も開いているとは限りません。管理者は侵入路に気づけばそこを閉じてしまうからです。そこで、一度侵入に成功した攻撃者は、次回の侵入に備えて別の入り口を用意しておきます。これがバックドアです。

 バックドアには設計・開発段階で盛り込まれるものや、稼働中のコンピュータに存在するセキュリティホールを使って送り込まれたソフトウェア(トロイの木馬等)によって作成されるものなどがあります。




3.1 開発段階で盛り込まれるバックドア

3.1.1 開発段階で利用されるバックドア

 バックドアはアプリケーションのプログラマが開発中のコードをデバッグしたり監視するために利用することがあります。アプリケーションの認証手続きが長々と面倒だったり、設定に時間がかかったり、また実行させる場合に様々な値を入力しなくてはならない場合に、プログラマはそれを避ける方法を考えます。また、認証手続きが間違った場合でも、その場合に備えたプログラムを予め用意しておく必要があります。

 顧客のオフィスで開発中のシステムに、リモートからアクセスする場合などに使われます。開発中のコードをデバッグしたり、監視したりするためにいちいち顧客のオフィスまで出向いていくことは大変ですので、よくバックドアが利用されます。

 ルータやファイアウォールなどは製品開発の段階では、ネットワーク経由でいろいろの設定を操作し、製品の機能のテストをするのが一般的ですが、そのような場合にはいちいちIDパスワードを入力するのが大変ですので、バックドアを利用するのが普通です。

 このような場合に、開発が終了したのにバックドアをそのままにしてしまったり、あるいはバックドアを残したまま製品を市場に出荷してしまうこともあります。



3.1.2 開発者が後で利用することを意図して作り込むバックドア

 倫理的に問題を持つ開発者の中には、依頼者との契約によって製造するプログラムの中に、バックドアを潜ませて、依頼者がそのプログラムを使用している最中に、このバックドアを利用して、何らかの不正を働こうとする者がいます。



3.1.3 政治活動によるバックドア

 アメリカ合衆国では以前から通信を傍受していたと噂されています。エシュロン(Echelon)はアナログ通信を対象とした盗聴技術で、世界各地においた通信傍受施設によって電波を傍受し、電話や電子メールなどを盗聴していたようです。参加しているのはアメリカ合衆国、イギリス、カナダ、オーストラリア、ニュージーランド(通称Five Eyes)です。ギリシャ、スペイン、ドイツ、日本なども参加は認められていないにしても施設は置かれていたといわれています。スノーデン文書が明らかにした情報手段はデジタル通信に対応しているようです。そこで利用されている技術はエシュロンではなく、プリズム(PRISM)だといわれています。

※スノーデン文書:NSAで諜報活動に携わっていたエドワード・スノーデンがリークした大量の機密情報


 プリズムはNSA(National Security Agency;米国家保安省)が運営しているシステムで、メール、写真、音声、動画、文書、接続記録など、ネットでやり取りされるデータなら、好きなものを何でも覗き見られるようです。対象となるのは、マイクロソフト、ヤフー、グーグル、フェイスブック、アップル、スカイプ、TouTube、AOL、PalTalkなどです。ただし、これについては米政府は否定し、IT企業各社もバックドアを開けていることを否定していました。

※NSAは米国防総省の諜報機関です。中央情報局(CIA)がスパイなど人間を使った諜報活動を担当しているのに対して、NSAは電子機器を使った情報活動と、その分析、集積、報告を担当しています。扱う情報は高度の機密性のゆえに大統領にもアクセスができないともいわれています。以前は組織の存在そのものが国民に対して秘密であり、NSAは「Never Say Anything(何も喋るな)」あるいは「No Such Agency(そんな部署はない)」の略だなどというジョークがあったようです。職員数は3万人に及び、年間予算は日本円で1兆円を超えるとされています。

 2001年の同時多発テロを防げなかったことを教訓にNSAは情報収集の方針を変えているようです。2001年の同時多発テロを目の当たりにして、NSAではテロを防ぐには世界中の全ての通信情報を監視する必要があると考えたのですが、世界中で飛び交っているデータは、数千テラバイトでそれをどのように集め、分析し、その中から必要な情報を整理して、選び出すかが課題となりました。

 そこでNSAが目を付けたのがメタデータです。電話の中身ではなく、何時、どこから、どの番号に電話したかが分かるだけで十分だということです。電子メールでも同じです。時刻、相手のアドレスなどを収集します。メータデータを集積することで、被疑者の行動範囲、連絡を取った相手が浮き彫りになり、テロ組織の発見につながります。

 中身が大切だという考え方を取ると、データが大きくなり、膨大な解析時間が必要となります。また、中身を解析するには人間の介在が必要となります。メタデータなら数字とアルファベットだけで、しかもコンピュータが解釈しやすい形で存在しています。

 米国にはCALEA(Communications Assistance for Law Enforcement Act;カレア、法執行のための通信傍受法)がありますが、この法律は従来、米国における固定電話会社や移動体通信業者などの従来型の通信会社にしか適用していませんでしたが、現在はインターネットアクセスにも拡大されており、アメリカ国内で使用されている通信機器にバックドアが設けられています。このバックドアを使用した通信傍受には法的手続きが必要ですが、運用方法は不透明で、個人情報が容易に取得されてしまう可能性があると指摘されています。スノーデン文書はNSAが広範に監視活動を行い、逮捕状無しで市民の通信記録を大量に収集していることをリークしました。アメリカの電話会社やインターネット関連会社がNSAの求めに応じてデータを提供していたことも発覚してしまいました。

 スノーデン文書が明らかになると、米政府も認めざるを得なくなってきています。IT企業等でも公式にバックドアを開けていることを認めるところが出てきています(Cisco、Windows、APPLE)。

 米国司法省(の警察機関であるFBI)とアップルの間で繰り広げられている「iPhoneロック解除をめぐる争い」で、アップルのティム・クックCEOは「これまで何度もFBIからiPhoneロック解除の要請を受け、その都度応じてきた」と述べています。ただし、今回はFBIがほぼ自動的にロック解除可能なツールを作れという要請だったので、頑なに協力を拒否しているということのようです。FBIの要求はCALEA法に基づいていますが、クックCEOは「これではバックドア・ツールを作れと言っているに等しいといって、拒否することを表明しています。

 フランスでは、通信傍受監視プログラムを強化し、新しい法によりフランス全市民の一般電話、携帯電話、Eメールの通信内容を傍受分析できることになりました。

 ドイツでも、海外からの脅威を事前に察知する目的で、電話の盗聴やWebの通信の傍受を行っています。許されているのはドイツ国内および国外からの全Webトラフィックの最大20%までです。傍受した情報を保存することは許されず、即座に対応するか破棄しなくてはなりません。
 
 米下院委員会は「中国通信大手の機器」にバックドアが設けられていると主張しています。調査の結果、バックドアのアクセス元のIPアドレスで明らかになった建物が、中国人民軍の所有する建物だったことが分かりました(調査に当たったセキュリティ会社が、CNNのインタビューで回答)。

 2001年の9.11を経てテロ対策の名のもとに通信傍受に対する社会的な要求が高まり、国によってはそれを成文化して、企業等に順守を求めるところが多くなっています。社会的にもそれを仕方のないものとして受け入れる傾向にありますが、政治的な理由で開けているバックドアが、何らかの機会に反社会勢力の手に入ってしまったときにどう対処すべきかなど難しい問題があります。また、法の運用が不透明な場合は、容易に個人情報が取得されてしまうという懸念もあります。

参考資料
https://www.gnu.org/proprietary/malware-microsoft.ja.html
http://www.glocom.ac.jp/column/2001/11/post_257.html
https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%83%E3%82%AF%E3%83%89%E3%82%A2
http://kaleido11.blog.fc2.com/blog-entry-3768.html
https://www.infoq.com/news/2016/02/apple-rejects-backdoor
http://www.heise.de/tp/artikel/5/5263/1.html

http://www.glocom.ac.jp/project/chijo/2001_11/2001_11_14.html
http://internetcom.jp/busnews/20050809/11.html
http://wired.jp/2013/06/20/german-spy-power-increase/



3.1.4 意図せずに作られた開発段階のバックドア

 開発段階にバグや設計ミスで、意図せずにバックドアが作られてしまうこともあります。



3.2 外部から送り込まれるバックドア

 いったん侵入に成功した攻撃者が、後日侵入に利用した脆弱性が修正されたり、アカウント情報などが失われた場合でも、侵入が可能なようにバックドアを仕掛けていくことがあります。このような場合は、既にrootの権限を奪っていることが多いでしょう。また、開発で使用したバックドアが悪用され、さらに高度な機能の操作が可能なバックドアが外部から取り付けられてしまうこともあります。

 コンピュータウィルスが感染する際に、外部からの操作を受け入れるための窓口としてバックドアを設置することもあります。セキュリティホールなどの欠陥がない場合でも、利用者が自らバックドアと知らずにインストールしてしまうこともあります(トロイの木馬型ウィルス)。



3.3 バックドアにはどんなものがあるか

 バックドアには、ローカルバックドアとリモートバックドアがあります。ローカルバックドアは一般ユーザが勝手にroot権限を取得できるプログラムです。/bin/loginや/usr/bin/passwdなど、rootのSUIDビットが設定されているコマンドを改変してしまいます。ログイン時に初期化されるログインシェルのファイルがよく狙われます。シェルの変更時(Change login shell)に実行されるコマンドなども狙われます。

 ローカルバックドアは、ローカルバックドア機能を仕込んだコマンドを正規のコマンドと置き換えてしまうこともあれば、バックドア機能以外は全て本来のコマンドに丸投げしてしまうプログラムの場合もあります。後者の場合は、ユーザが確認できる処理は本来のコマンドによって処理されているので、その挙動によってバックドアが仕組まれているかは判断が難しくなります。

 リモートバックドアはリモートから直接rootとしてログインできるようにしたプログラムです。デーモンプログラムとして動作し、一般的には、TCPポートで攻撃者のアクセスを待ち受けますが、UDPやICMPを使うものもあります。リモートバックドアはtcpdや、inetd、sshdといった既存のデーモンを改変したものもありますが、独自のデーモンプログラムを作成した場合もあります。

 バックドアには、様々なものがあります。次にあげるのはほんの一例です。

● ユーザアカウント
 何の変哲もないユーザIDに対してroot権限、管理者(administrator)を与えるというのが一番ありそうなことですので、最近root権限、管理者権限を与えられたアカウントがないか注意してください。

● 通信機器
 通信機器にはデフォルトでバックドアが用意されています。これらの機器を備えるときは、デフォルトのアカウントを削除するか、パスワードを変更すべきです。また、メーカによっては、パスワードシステムにかなり安易な暗号アルゴリズムを使用しているところがありますので、注意してください。

● スタートアップファイル
 システムのスタートアップメカニズムにバックドアを仕掛けるのが、攻撃者のよくやる手口です。そんなこととは知らないユーザがシステムをスタートアップする度に、攻撃者の仕掛けた仕組みが作動することになります。
 多くのプログラムは、ユーザ用のオプションや変数を自動的に初期化してから値を設定します。このような仕組みは、攻撃者が自分のプログラムを自動起動するのにピッタリです。

 UNIXのユーザログイン時の初期化ファイルには次のようなものがあります。

シェル 初期化ファイル
Bourneシェル .profile
Cシェル .schrと.login
Kornシェル .profileと環境変数ENVで指定したファイル(通常は.kshrc)
bash .bash, .login, .bashrc, .profile
tcsh .loginと.cshrc(あるいは.tcshrc)

 攻撃者はこれらのファイルに手を入れて、ユーザがログインする度に指定したコマンドが実行されるようにします。Bourneシェル、Kornシェル、bashなどのシェルでは、ユーザのデフォルトの初期化ファイルとして/etc/profileを使用しますが、.profileに次のような細工をするとどうなるでしょうか。

/bin/cp /bin/sh /tmp/.secret
/bin/chown root /tmp/.secret
/bin/chmod 4555 /tmp/.secre

1行目で/bin/shを/tmp/.secretにコピーしています。2行目は、/tmp/.secretをroot所有にしています。3行目で/tmp/.secretにSUIDビットをセットしていますので、/tmp/.secretを実行すると、ルート権限でBourneシェルを実行できることになります。

※特殊モード(SetUID、SetGID、Stickyビット)に関しては、オクテット指定でSetUIDは4000、SetGIDは2000、Stickyは1000となります。なお、Stickyビットは、全てのユーザが書き込めるものの、所有者だけしか削除できないというアクセス権になります。

 .cshrcや.kshrcのようにログイン時だけでなく新しいシェルに変更するときにも実行されるものがあります。

 GNU.emacs
 GNU.emacsはGNU emacsエディタを起動するときに読み込まれ、実行されます。任意のコマンドをEmacs LISPのコードで記述し、.emacsファイルに埋め込むことが可能です。

 .exrc
 .exrcはEXエディタ、viエディタを起動する際に読みだされるファイルです。これもログインシェルと同様に操作されることがあります。

 at、crontab
 UNIXのほとんどのシステムがatやcronという名前のプログラムを備えています。atデーモンやcronデーモンは通常、システム起動時にrcスクリプトなどから起動されます。atデーモンは、コマンドやスクリプトを特定の時間に発行することができますし、cronデーモンは定期的にタスクを実行するcrontabデーモンを起動することができます。攻撃者は、このような将来の特定の時間に実行されるプログラムや、定期実行されるプログラムにバックドアを仕込みます。ここで、仕掛けられるものもログインシェルで仕掛けられるものと同じようになるでしょう。例えば次のようになります。

cp /bin/csh /tmp/.secret; chmod 4755 /tmp/.secret

 システムの初期化ファイルもバックドアを仕掛けるには絶好の場所です。UNIXの初期化ファイルには/etc/rc*、/etc/initd/*、/etc/rc?.dなどがあります。管理者は自分の管理するシステムがどのように起動するか具体的に把握していなくてはなりません。

● inetdのバックドア
 inetdはインターネットスーパーデーモンなどと呼ばれます。あるいはスーパーサーバなどという言い方もあります。クライアントからのアクセス要求が多いサービスはhttpd(Webサーバ)とかsendmaild(電子メールサーバ)などのようなデーモン(daemon)プログラムを起動して、それぞれ特定のポートでクライアントからの接続を待っています(いわゆるListen状態)。しかし、これはメインメモリ上に常駐させるということを意味しますので、あまりクライアントからの要求がなさそうなものは代理人に任せます。インターネットサービスの待ち受け作業を請け負って、他のサービスのためにListenしているのがinetdです。inetdの設定ファイルとして利用されているのが、/etc/inetd.confです。inetdはこの設定ファイルで設定されたインターネットサービスへの接続要求を見張っていて、接続要求のあったインターネットサービスを立ち上げます。その時にどんなオプションで立ち上げるかもinetd.confに記述されます。inetd.confを改ざんして、サービスを別の攻撃用のサービスに取り換えてしまったり、現在あるサービスを都合の良いように改変してしまうということがあります。

 次は、攻撃者がhackというバックドアプログラムを仕掛ける場合です。攻撃者は最初に/etc/servicesに

hack 723/tcp

のような設定を忍ばせます。次に、inetd.confに次の設定を追加します。

hack stream tcp nowait root /bin/csh csh -i

 これで、inetdがポート番号723番で、hackの代わりにListenしてくれ、クライアントからの接続要求があったら、hackに連絡してくれます。これで、攻撃者が723番ポートにtelnet接続すれば、ルート権限でcshを使用することができます。

 inetd.confが改ざんされていないかは、常に注意してください。inetd.confは全く変えられていなくても、inetd.confから呼ばれているサービスがそっくり別のものに取り換えられている場合もありますので注意が必要です。

● SSHへのバックドア
 SSHではパスワード認証と公開鍵認証の2つの方法が使えます。パスワード認証の場合は、新たにアカウントを追加してパスワードを設定する方法があります。しかし、新たに追加されたアカウントは管理者に簡単に気づかれます。では、既存のアカウントのパスワードを変更する方法はどうでしょうか。この場合も本人が直ぐに気づいてしまいます。(ほとんど使われていないアカウントを利用するという方法がありますが、都合よくそのようなアカウントが見つかるかは分かりません)。

※長い間使われないアカウントを放置するのは非常に危険です。パスワードを改ざんされても、本人が気が付かないからです。退職社員、卒業、退学の学生のアカウントは定期的に確認して、その都度削除するようにしてください(ネットワークの管理部門は、人事部、学生部等から退職社員、卒業・退学学生の情報をもらえる様にしておいてください)。

 公開鍵を使った認証方式はユーザアカウントのパスワードを知らなくてもログインできますので、バックドアなどでは狙われやすいといっていいかもしれません。

 SSHにはバージョンが2つあり、SSHver1はRSA、SSHver2はDSAを使いますが、OpenSSHはSSH1ではRSAのみ、SSH2はDSAとRSAの両方を使えるようにしています。

 OpenSSHで公開鍵認証を使う場合はssh-keygenコマンドを使います。オプションに"-t dsa"を使うと、DSA認証鍵が生成され、"-t rsa"を指定するとRSA認証鍵が生成されます。認証鍵の生成の際にはパスフレーズに入力を求められますので、入力して、それを覚えておきます。秘密鍵のファイルは、/home/hoge/.ssh/id_dsa(id_rsa)、公開鍵のファイルは/home/hoge/.ssh/id_dsa.pub(id_rsa.pub)です。

 生成した公開鍵ファイルは攻撃対象サーバのrootのホームディレクトリ/rootの.sshディレクトリ内にauthorized_keysというファイル名で置きます。これで、攻撃者の環境からsshコマンドを使い対象サーバにログインできます(秘密のパスワードを聞かれます)。これでroot権限でログインできます。

● HTTP、HTTPSへのバックドア
 Apache等のWebサーバでは、ほとんどCGIプログラムを認めています。CGIはターゲットとなるWebサーバ上でプログラムを実行し、その結果をクライアントに返すことを目的とした仕組みです。
 例えば、ターゲットとなるWebサーバ上でEmacsを実行しその画面を攻撃者のX Window上に表示させるプログラムを作成します。このCGIをSetUIDにして、所有者をrootに設定して、ターゲットサーバにインストールすれば、攻撃者はroot権限で、Emacsを使用することができます。

● ルートキット
 rootkitは特定のツールを指す言葉ではなく、いろいろのツールの総称で、一般的には、ローカルバックドア機能、リモートバックドア機能、ネットワークスニファ機能、隠ぺい機能、その他侵入者にとっての有益な機能を持つプログラムが含まれています。「lrk(Linux RootKit)」や「t0mkit」などの有名なrootキットパッケージもありますが、これら以外にも様々なものがあります。既存のツールに自作コマンドを追加したもの、複数のキットを組み合わせたもの、自作のものなど様々です。



3.4 バックドア対策

 バックドアの方法は様々ですのでその対策も様々です。ここでは、代表的なものをあげておきます。

3.4.1 バックアップとシステム再構築の準備

 バックドアを作成する方法は無数にありますので、バックドアを発見した場合は、その他のバックドアも全部探してシステムを元通りにしようとすることはあきらめた方がいいかもしれません。もし、発見できずにそのまま放置されたバックドアが1つでも残っていると、大変なことになります。バックドアを見つけたら、OSをオリジナルのメディアからリストアし、「無菌であることを保証されている」バックアップストレージからデータファイルを書き戻してください。もし、システムが独自の構成になっている場合は、できるだけ詳細なドキュメントを作成し、日ごろから迅速な復旧ができるように備えておく必要があります。

 サーバ上のデータの変更を検知するツールとして有名なのがTripwireです。商用版とオープンソース版があります。商用版はUNIX/Linuxの多くのディストリビューション、Windowsに対応していますが、オープンソース版はLinuxのRed Hatにしか対応していないのが残念なところです。商用版は日本語化されていますが、オープンソース版は英語バージョンだけです。
 Tripwireはフォルダ/ディレクトリの変更を監視し、いつどのように変更されたかを知ることができ、不正に改ざんされたり意図せずに破損してしまったような場合には元に戻すこともできます。ただし、Tripwireは元の状態に戻すことができるだけですので、正常に稼働していた時の状態を保存しておく必要があります。システムを稼働させる時に同時にTripwireも稼働させなくてはなりません。バックドアを仕掛けられたかもしれないと心配になって、Tripwireを使うというわけにはいきません。



3.4.2 バックドアの設置を未然に防ぐために

 バックドアに対する総合的な対策としては、システムを定期的に、しかも徹底的に監査することです。管理者はシステムに存在する全てのファイルを把握し、特にスタートアップファイルは常に監視し、変更がなされたときは直ぐにそのことに気づかなくてはなりません。ファイルとディレクトリの完全なリストを定期的に作成し、前回作成した資料と比較してください。UNIXの場合は、ls -laコマンドおよびその他のコマンドを駆使して、全てのファイル名とサイズ、タイムスタンプなどを記録して比較するスクリプトを作成してください。

 OSのセキュリティホールなどが公表された場合は、パッチが出たらすぐにインストールしてください。

 新しいソフトウェアをインストールする場合は、信用できるところからインストールしてください。確実ではないと思えるソフトウェアはできれば、ソースコードを入手してください。ソースコードをよく読んで、確認してください。SUIDビットのセットされているプログラムは絶対にインストールしてはいけません。

 ネットサーフィンをしていて気ままに新しいソフトをインストールするようなことは絶対に避けてください。TwitterやFacebookなどにあるURLはクリックしないで下さい。

 開発環境以外のホストからはソースコードを削除してください。UNIX/Linuxの場合は、ソースコードごと配布されていますので、通常UNIX/Linuxが稼働しているホストにはソースコードが存在しています。攻撃者にとってはこれはとてもありがたいことです。ソースコードがあれば攻撃者は自分用のバックドアやデータ収集ルーチンを作ることができます。また、コンパイラがあれば、攻撃者は自分のソースコードを持ち込んでシステムに合わせてコンパイルすることもできます。ソフトウェア開発用ではないホストには、開発環境を備えておくべきではありません。

 公開サーバにはセキュリティツールも置いておくべきでありません。セキュリティツールの中にはファイルパーミッションを検査するツールもあります。そのようなツールが放置されていると、攻撃者にとっては絶好のツールとなります。攻撃者はこのようなツールを使ってファイルパーミッションの不十分なファイルを探すことができます。システム管理者にとって便利なツールは攻撃者にとっても便利なツールであることが多いので、このようなツールは使った後は必ずアンインストールしておくことを忘れないでください。



3.4.3 バックドアの検出・原因の究明

 バックドアの検出・原因究明に使うコマンドが改ざんされていた場合には正しい結果を得ることはできません。このような場合を考慮して、予めスタティックバイナリ形式の安全なコマンド群をCD-ROMなどのメディアに格納しておき、原因究明の際に対象サーバ上でマウントして使用できるようにしておいて下さい。実行するコマンドは、確実にそのメディアのものが使えるように、絶対パス指定をしてください。

 調査する場合は調査用のパソコンを1台用意します。調査は対象サーバにリモートログインして進めます。調査は慎重に進めてください。攻撃者がシステムに侵入中ということもあり得ます。侵入中かどうかはっきりしない段階でも、攻撃者が侵入しているものと仮定して調査を進めてください。攻撃者が侵入中だと分かったら対象サーバをネットワークから切り離した方がいいでしょう。

 調査作業は一般ユーザの権限で行ってください。管理者権限で調査すると万が一の操作ミスが取り返しのつかないよう大きな影響を与えてしまうかもしれません。管理者権限はどうしても必要な時にだけ使って下さい。

<ステップ1>:コマンド実行の結果を保存
 原因究明のために実行したコマンドとその結果をscriptコマンドを使って、ログとして保存します。コマンドの実行例は次の通りです。
%script /tmp/exam.log

これ以降ターミナルで実行した結果は全て/tmp/exam.logファイルに保存されます。

<ステップ2>:ログイン履歴のチェック
 w、lastコマンドを使って、何時、誰が、どこからログインし、何をしたかを調査します。リモートからroot権限でアクセスしているような記録は怪しいと思って下さい。

<ステップ3>:実行プロセスのチェック
 psコマンドを使って、不審なプロセスがないか確認します。リモートからログインして、Emacsを使っているような記録があれば、怪しいと思ってください。

<ステップ4>:通信のチェック
 接続中のサービスや、Listen中のポートの割り出しを行います。内部から調べる場合は、netstatやlsofなどのコマンドを使います。外部からの調査にはnmapを使います。

<ステップ5>:全ファイルのタイムスタンプ
 現時点での全ファイルのタイムスタンプを取っておきます。コマンドは、ls(オプションは-l、-ul、cl)、あるいはstatを使います。

<ステップ6>:不審なファイルのチェック
 findを使って、setuid(setgid)されたファイルの中に不審なものがないかチェックしてください。stringsコマンドを使って不審なバイナリファイルをチェックしてください。Emacsコマンドを実行し、特定の外部アドレスに出力を試みているCGIプログラムなどがあれば、怪しいと思ってください。

<ステップ7>:バックドア検出ツール
 バックドア検出用のツールがありますので、これで検査します。UNIX用にはchkrootkitなどがあります。

<ステップ8>:ログと調査結果の収集
 後でじっくりと調査するため、ログやシステムファイルをバックアップし、調査用のパソコンに転送してください。調査結果も同様に、調査用のパソコンに転送します。

参考資料
http://www.atmarkit.co.jp/ait/articles/0210/11/news001.html







4 スプーフィング攻撃

 スプーフィングは、TCP/IPのメカニズムを逆手に取った非常に危険なクラッキング方法です。スプーフィングとは、ネットワーク上のあるマシンが別のマシンに成りすますことです。具体的には、IPアドレスを偽る方法、MACアドレスを偽る方法、ホスト名を偽る方法、ルートを偽る方法、TCPコネクションを偽る方法、電子メールの送信元を偽る方法などがあります。

4.1 IPアドレススプーフィング

 スプーフィングの代表的な例がIPアドレススプーフィングです。ファイアウオールなどのアクセス制御システムは、基本的にはIPアドレスを基準にして、アクセスを許可するかどうかを決めています。IPアドレスだけを基準にしてアクセス制御をしているネットワークは、IPアドレスを偽れば簡単にアクセスができます。IPアドレスを偽ることでアクセス制御システムを潜り抜ける方法をIPアドレススプーフィングといいます。



4.1.1 どのように擬装するのか

 UNIX系のOSではr系コマンドと呼ばれる、rsh、rlogin、rcpというコマンドが使えますが、このコマンドが非常に危険で、これらが使用するポートは開けないという方法が推奨されています。

 r系のコマンドが危険なのは、相手のIPアドレスによって信頼できると判断してしまう点です。そして、相手が信頼できる場合は認証を緩めてしまいます。

 r系コマンドでは、/etc/hosts.equiv(あるいは/etc/hosts.allowという場合もあります)、.rhostsなどのファイルが利用されます。これらのファイルに記述されたホストは信頼され、このホストにアカウントを持つユーザも信頼されるということになります。

■ /etc/hosts.equiv
 /etc/hosts.equivファイルに記述されたホストは信頼できるので、そのホスト上にアカウントを持つユーザは全て信頼するということになります。aliceがホストAとホストBにアカウントを持っている場合、ホストAでホストBを信頼すると記述されていれば、aliceはホストBからパスワード無しで、ホストAにリモートログイン(rlogin)することができます。/etc/hosts.equivはこのホストにアカウントを持つ全てのユーザに適用されますので、両方のホストにアカウントを持っていれば、Charlesでも、DickでもEveでも、ホストBからホストAへパスワード無しでリモートログインが可能です。

■ ~alice/.rhosts
 aliceがホストAとホストBの両方にアカウントを持っていて、ホストAのaliceのホームディレクトリにある~alice/.rhostsというファイルにホストBを信頼すると記述されていれば、ホストBにログイン中のaliceはパスワード無しでホストAにリモートログインすることができます。

■ トラステッドユーザ
 トラステッドユーザという概念は設定をした人が、設定ファイルで指定された人を信頼して、自分のアカウントを使わせるという意味になります。例えば、ホストAでaliceが~alice/.rhostsファイルに、ホストB上のbobを信頼すると書けば、ホストB上のbobはパスワード無しで、ホスト上のaliceのアカウントを使用できるということになります。

ホストB bob

と/etc/hosts.equivファイルに書くと怖いことになります。この場合は、ホストAがホストB上のbobを信頼することになりますので、ホストB上のbobはホストAのどんなアカウントでもパスワード無しにログインできてしまうことになります。更に危険なことに、ホスト名やユーザ名にワイルドカードを使用することができるという点です。

ホストB +

と書くと、ホストBからアクセスするユーザなら誰でも信頼するという意味になります。また、

+ bob

なら、bobというアカウントの人ならインターネット上のどこから来た人でも信頼するということになってしまいます。



4.1.2 トラステッドホスト、トラステッドユーザの危険性

  一度コンピュータシステムへの侵入に成功した攻撃者は、再度の侵入が簡単に済むように/etc/hosts.equivや~/.rhostに自分のユーザ名を残しておきます。/etc/hosts.equivを変更すると気づかれやすいので、~/.rhostsファイルを書き換えることになるでしょう。

 どのホストをトラステッドホストとして設定しているか知られてしまうと大変です。この場合は、システムに侵入されなくても簡単に認証システムを迂回されてしまいます。トラステッドホストとして設定されているホストをネットワークから外して、攻撃者が持ち込んだホストを代わりに接続して、IPアドレスを同じものに設定されると困ったことになります。後は、ターゲットとなるサーバ上でどんなアカウントが使われているか分かれば、簡単にパスワード無しで侵入されてしまうことになります。

 rコマンドについてはその危険性が知れ渡り徐々に使われなくなっていますが、この際rコマンドは一切利用できなくすべきです。代わりにSSHなどを利用してみてはいかがでしょうか。



4.2 ARPスプーフィング

 ARPスプーフィングはIP通信で使用されているARP(Address Resolution Protocol)を悪用した攻撃です。通常、LANではイーサーネットを物理ネットワークとして利用し、その上でTCP/IPを使ってIP通信を実現しています。TCP/IPを使った通信ではパケットを使います。パケットでは、アドレスとしてIPアドレスを使います。イーサーネットの通信ではフレームが使われます。フレームで使われるアドレスはMACアドレスです。パケットは、フレームでカプセル化されます。パケットを送信するユーザ、あるいはソフトウェアは宛先をIPアドレス(あるいはドメイン名)で識別しますが、宛先のMACアドレスは知りません(知らないのが普通です)。そこで使われるのがARPです。

 ARPではネットワークに対してIPアドレスを示して、MACアドレスを聞きます。これを、ARP要求(リクエスト)といいます。これに対する回答がARP応答(リプライ)です。通信の度にARPを繰り返すのは大変ですので、ARPで聞き出した回答は一定時間記録されます。これをARPキャッシュといいます。このARPの仕組みを悪用すると盗聴が可能となります。



4.2.1 ARPスプーフィングの仕組み

 次のようなネットワークで考えてみましょう。


 盗聴者のパソコンを"C"だとします。CからAに対して、PC BのIPアドレスと、MACアドレスの組を192.168.1.2、12:34:56:CC:CC:CC、CからBに対して、AのIPアドレスとMACアドレスの組を192.168.1.1、12:34:56:CC:CC:CCと教えると、AからBに向けたフレームはCに、BからAに向けられたフレームもCに送信されることになります。この時、フレームを外してみると、宛先IPアドレスは、それぞれAあるいはBということになりますので、ここでこのパケットを自分宛のものとして、コピーしたのち、パケットに書かれた宛先IPアドレスに転送するという仕組みを作っておけば、CはAとBのやり取りを盗聴することができます。

 あるいは、ゲートウェイとして機能いている"E"の振りをして、A、Bに対して、IPアドレスとMACの組を192.168.1.254、12:34:56:CC:CC:CCと教えれば、A、Bの外部インターネットとの通信を全て盗聴することができます。

 ARPスプーフィングでは、本来の宛先に届く前にいったん攻撃者のパソコンを経由します。この時盗聴されるだけでなく、攻撃コードなどを埋め込まれる危険性もあります。



4.2.2 ARPスプーフィング対策

 ARPの問題点はARP応答をあまりに簡単に信じてしまうことです。誰からの応答であるかも確認せずに安易にARPテーブルに書き込んでしまいます。ただし、今のところARPに認証を取り入れようという動きはないようです。

 対策としてはIPアドレスとMACアドレスの関係を固定してしまうことです。OSによっては、ARPキャッシュ内の項目を「静的に」設定することができます。この方法だと、ネットワークを再編して、ホストのIPアドレスを変更するときなどには、その都度アドレスマッピング情報を書き換える必要があります(大きなネットワークではとても大変な作業となります)。



4.3 経路スプーフィング

 小さなネットワークではルーティングプロトコルとしてまだRIPが使われているところが多いのではないでしょうか。RIPにはver1とver2があり、RIPver1は認証に対応していません。従って、不正なルーティングテーブルでも疑わずに受け入れてしまいます。悪意のPCが特定ルートのネクストホップを自分とするエントリをルーティングテーブルに追加し、RIPver1ルータに送ったらどうなるでしょうか。エントリには宛先ネットワークと、ネクストホップなどの情報が書かれています。たとえば、宛先ネットワークが200.10.23.0でネクストホップがクラッカーのパソコンのIPアドレスになっている場合は、だまされたルータに転送された宛先200.100.23.0のパケットは全部クラッカーのパソコンに転送されてしまいます。

 経路スプーフィングに対策するためには、ルーティングプロトコルをRIPver2、OSPFなどに置き換えるべきです。RIPver2ややOSPFは認証を取り入れていますので、悪意のPCには簡単に騙されません。



4.4 DNSスプーフィング(DNSキャッシュポイズニング)

 DNSサーバはクライアントからの問い合わせに直接回答できない場合は、委任関係を辿って最終的には権威サーバから回答を得て、答えをクライアントに返します。この処理の際に得た名前情報は、再度の問い合わせに備えて、ローカルに保存します。これをキャッシュといいます。キャッシュする時間は権威サーバがTTLで指定します。このキャッシュという仕組みによって、他のサーバへの問い合わせ回数が減少し、DNSの負荷やネットワークの帯域が軽減する、その結果問い合わせにかかる時間が軽減するなどの効果が期待できます。クライアントからの依頼を受けるネームサーバは、キャッシュ機能を実装していることが多いため、キャッシュサーバなどと呼ばれています。

 このキャッシングの仕組みを悪用して偽のDNS情報をキャッシュとして蓄積させる方法が、DNSスープーフィングです。一般にはDNSキャッシュポイズニングと呼ばれています。DNSキャッシュに偽のDNS情報を載せられると、このDNSサーバを利用するユーザには次のような悪影響があります。

ⅰ) ホスト名とIPアドレスの対応を変更され有害サイトへ誘導される
ⅱ) Webの内容を改ざんされる、メールを盗聴される
ⅲ) DoS攻撃の際の送信元偽造に利用される
ⅳ) スパムメールの送信に利用される

 キャッシュサーバは権威サーバへの問い合わせの際に、16ビットの識別子(ID)を使います(DNSメッセージに格納)。権威サーバは応答にこのIDを使用します。そして、キャッシュサーバはIDが同じならば、自分の問い合わせに対する応答であると判断し、違っていれば不正なDNSメッセージとして廃棄します。

 DNSの問い合わせと回答は、主としてUDPを使用しますので、IPアドレス、ポート番号、IDを細工することで比較的簡単にメッセージを偽造することができます。ただし、このIDはあてずっぽうで指定するしかありませんが、プログラムで連続的に問い合わせを送信できるならある程度は可能性があるかも知れません。ただし、これを行えるのはTTL時間が切れたタイミングで、しかもキャッシュサーバからの問い合わせに対して、権威サーバよりも素早く回答しなくてはなりません。従って、TTL時間を長くしておけばある程度は防げると思われていました。

 しかし、2008年8月、セキュリティ研究者のカミンスキー(Dan Kaminsky)により、危険なDNSキャッシュポイズニングの手法が発表されました。従来はTTL時間が切れるタイミングが偽のDNS情報を送り込まれる危険のある時間帯だと思われていましたが、カミンスキーの方法によれば、常時偽のDNS情報を送り込まれる危険があります。カミンスキーの方法では、キャッシュにないドメイン名を尋ねます。存在しないドメイン名なら、キャッシュに残っていないはずなので、必ず権威サーバに聞きに行くはずです。カミンスキーの方法は、実際に存在しないドメイン名を尋ねますが、ドメイン自体は存在しなくてはなりません。ドメインが存在しないと、尋ねるべき権威サーバが見つからないからです。

 カミンスキーの方法(Kaminsky attack)は次の通りです。

① 攻撃者は標的とするキャッシュサーバに対して偽のドメイン名の問い合わせをします。ただし、ドメイン自体は存在していていなくてはなりません。例えばwww.example.comを乗っ取りたい場合は、123445thy.example.comを問い合わせます。
② キャッシュサーバはキャッシュにないので、example.comを管理している権威サーバに問い合わせをします。
③ 攻撃者は権威サーバが回答するよりも早く偽の回答を送ります。回答は具体的なもの、あるいは参照先ということになります。参照先は攻撃者が用意した偽のDNSサーバということになるでしょう。

 この方法では、ランダムなドメイン名をキャッシュサーバに問い合わせることで強制的に外部への問い合わせを行わせることができます。IDが不一致の場合はドメイン名を変えて何度でも再チャレンジがが可能です。この方法を使うと従来知られていたDNSポイズニングの方法に比較してはるかに効率的に攻撃を行うことができます。

 DNSポイズニングによる危険は正当でないサーバ(権威サーバのふりをしたサーバ)から送られてくる偽装の回答が原因です。根本的な解決策は、DNSキャッシュサーバと権威サーバの応答に認証を導入することです。この認証に電子署名の仕組みを使っているのがDNSSECという方法です。ただし、DNSSECを利用するにはキャッシュサーバ、権威サーバをDNSSEC対応に変える必要があるとともに、電子署名に必要な鍵の管理方法や配布方法を確立するなどの課題があり、簡単ではありません。

 現在は偽造されているかどうかの判断をIDに委ねていますが、このIDが16ビットで短すぎます。もっと長いIDにするという考えもあり得ますが、そうするとプロトコルそのものの変更になりますので、簡単なことではありません。

 実現可能な方法としてはキャッシュサーバから権威サーバに問い合わせるときに使うポート番号を広範囲からランダムに選択して決めることです(Source Port Randomization)。現在は固定、あるいは狭い範囲から使用されていますが、広範囲からランダムにポート番号を選択することで、偽造は難しくなります。このsource port randomizationについてはDNSの各ベンダからパッチがリリースされています。

 DNSキャッシュポイズニングは、そもそもキャッシュサーバに対するクライアントからの問い合わせが発端ですので、キャッシュサーバに対する問い合わせができるクライアントをフィルター等で限定する方法も考えられます。

※DNSレコードを保有して、通常のDNSの問い合わせに回答するサーバは、「DNSコンテンツサーバ」と呼ばれています。一般的には1台のDNSサーバがコンテンツサーバとキャッシュサーバの役割を兼ね備えているのですが、セキュリティのためには、2つの機能をそれぞれ独立したマシンで行わせるべきだとされています。

 DNSキャッシュポイズニングの攻撃方法はキャッシュサーバから権威サーバへの問い合わせのタイミングで、IDをいろいろに変えた偽の回答を送るというものです。このタイミングで大量の偽応答があるはずですので、この大量の回答を検知して、キャッシュサーバを保護するという方法も可能です。

参考資料
https://www.nic.ad.jp/ja/newsletter/No40/0800.html




4.5 TCPコネクションスプーフィング(ハイジャッキング)

 TCPコネクションスプーフィングは、偽のパケットを送信してコネクションを奪取する方法です。このコネクションをセションと捉えてセションスプーフィングという言い方をすることもあります。あるいはセションのハイジャッキングという言い方をされることもあります。

 セッション(session)とは、「会議」「会合」「複数の人間で行う活動」などを意味する言葉ですが、コンピュータやネットワーク通信の用語として使う場合は、一連の動作のことを言います。ただ、ネットワーク通信といっても、トランスポート層レベルでのセッションと、アプリケーション層のセッションではだいぶ考え方が違います。

 トランスポート層のTCPの場合は3ウェイハンドシェークをして「通信が開始」され、「実際のデータの交換」が行われ、FINを送信することで、「通信が終了」します。この手順でコネクションが管理されますので、これがセッションということになります。Webの場合は、Webページにアクセスしたユーザが、そのページ内で行う一連の動作をセションと呼んでいます。例えばユーザ名を入力して認証を行いログインし、ログアウトして、そのWebページを退出するまでが1セションということになります。

 セションという概念を使う場合は、このセッションを識別する何かを使うことが一般的です。これを通常セションIDと言ったりします。このセッションIDを奪って、セッションを横取りするのがセションハイジャッキングです。

 セションハイジャッキングという項目を立てて、その中でTCPセションハイジャッキングと、Webセションハイジャッキングというように細分化してもよいのですが、TCPとWebではセションの考え方が少し違っていますので、分けて説明することにします。

 TCPコネクションにおいてセションIDに該当するのはIPアドレスとシーケンス番号です。IPアドレスの詐称と、TCPシーケンス番号の予測攻撃を組み合わせることで、確立済みのTCPセションを奪い不正データを送信することが可能です。ただし、この点に関しては過去何度も脆弱性の指摘がなされ、その都度対策がなされていますので、現在は沈静化されています。



4.6 Webセションスプーフィング(ハイジャッキング)

 HTTPはもともと「双方向」の単発(1往復)という性質を持つ通信です。クライアントからの要求に対して、サーバは要求されたドキュメントを送り、それでサービスを終了するというものです。HTTPはステートレスプロトコルと呼ばれています。これはクライアントとサーバの間のセッションの状態を保持していないという意味です。Webサーバにログインし、商品を選んで、それを購入するという場面を考えてみましょう。あるWebサイトでアリスがAという本を選択したとします(例えば買い物かごに入れた)。これを1つのセッションとします。そして、次のセッションでさっきのセッションで選択したAという本の購入手続きをしようとしても、システムは先ほどのセッションでアリスがAという本を選択したということを覚えていません。仕方なく、もう一度Aという本を選択して、次のセッションで購入手続きをしようとしても、次のセションではやはり、前のセションでアリスがAという本を選択したことを忘れています。何度やっても同じです。これではWebをビジネスで使用することはできません。そこでWebのログインから、商品閲覧、商品選択、注文の確定などの動作を一連の動きをセションとして把握するための導入されたのがCookieです。



4.6.1 Cookie

 Cookie(クッキー)は、WebブラウザとWebサーバ間の情報交換に、状態保持機能を持たせる手法です。Cookieを使うことで、Web通信をステートレスから、ステートフルに変えることができます。Cookieを使うかどうかはサーバ運営者が決めます。Cookieを使うと、ログイン時に入力されたユーザ情報や、ユーザのWebサーバ訪問時の行動などを記録し、ユーザのWebブラウザを介して、ユーザのコンピュータに保存することができます。
 ユーザが、前回訪問したWebサイトに再度訪問する際は、WebリクエストのメッセージにCookie情報が付加されますので、Webサーバは訪問者が誰で、今までにそのサイトでどのような行動をとってきたかを全部把握することができます。ユーザが再度Webサイトに訪問すると、「こんにちは、○○さん」などとあいさつしてくれたり、的確な情報を提示してくれたりするのは、WebサーバがCookieによって閲覧者を特定しているためです。
 
 Cookieは米のネットスケープコミュニケーションズ社によって考案されたものですが、その後RFC2109、RFC2965と規格化がすすめられ、現在ではほとんどのWebブラウザに採用されています。

 Cookie情報は暗号化されていないので、奪われて悪用される可能性があります。



4.6.2 Cookieの使い方

 Cookie管理の手順は次の通りです。

ステップ1> クライアントAがサーバBにリクエストします。クライアントAはCookie受け入れ可能ならば、リクエストヘッダでCookieが使えることを宣言します。
ステップ2> サーバBは要求されたページと一緒にCookieを返します。Cookieは単なるファイルあるいは文字列です。サーバBはレスポンスの中で、Set-Cookieを使って値をセットします。
ステップ3> ユーザがCookieを無効にしていない場合は、ブラウザは提供されたCookie文字列を解釈せずに、メモリに格納します。ブラウザの終了後はハードディスクに格納します。
ステップ4> ブラウザAはサーバBへの次のリクエスト時に、リクエストヘッダにCookieを入れて送信します。

HTMLを使ってCookie値を書き込む方法は次の通りです。

<meta http-equiv="Set-Cookie" content "~">

~の部分は次のような文字列を指定します。

NAME=値; expires=値; domain=値; path=値; secure

上のうちNAMEだけが必須パラメータで、その他は省略可能です。NAMEは自由に決めることができます。ServiceID=16072400014、CustomerID=123456789、NAME=takahashi、passswd=himitsuなどと使います。<ステップ2>でサーバBが送り返すCookieでdomain値と、path値を指定すれば、<ステップ4>でブラウザAがCookieを送り返すかどうかは、domain値とpath値によって決定します。



4.6.3 Webセションハイジャッキング

 Cookieを使ってセション管理を行う場合、このCookieを盗まれれば、成りすましの被害にあう可能性があります。

 Webをビジネスなどに使う場合は次のような通信の手順を踏むのが一般的です。
① トップページでユーザIDとパスワードの入力を求める。
② 認証に成功するとサーバはセションIDを割り当て、それをCookieとしてクライアントに通知する。
③ クライアントはこれ以降の要求にセションIDとしてCookieを付加する。サーバは対応するセション情報にアクセスし、どのユーザであるか確認する。以降の応答にはCookieを一緒に返す。
 
 第三者がCookieを知ると、そのセッションが有効な間だけとはいえ①、②を飛ばしていきなり③から開始することができます。これはID、パスワードを知らなくてもなりすましができるということを意味します。

■ Cookieの漏えい
 Cookieの漏えいで最も危惧されるのが、盗聴です。盗聴を防ぐ手段として期待されれるのがTLS(SSL)ですが、SSLだから安心というわけにはいきません。全てのWeb通信がSSLというわけではありません。CookieはSSLを使っているときだけ付加されるわけではなく、一連のセションの中で常に付加されています。SSLを使ったhttpsのサイトと、普通のhttpのサイトの間を行ったり来たりしていると、httpのサイトを閲覧しているときにCookieが漏えいしてしまう可能性は大いにあります。
 クロスサイトスクリプティングもCookieを不正に奪取する手段としてよく利用されています。



4.6.4 Cookie対策

 Cookieは便利ですので、使うか使わないかは個人の考え方次第です。Cookieが漏えいすることが心配なら拒否することもできます。 全部のCookieを拒否することもできますし、サードパーティのCookieだけブロックすることもできます。IEの場合は「インターネットオプション」から設定できます。Edgeの場合は、「・・・」(詳細)から「設定」⇒「詳細設定」の「プライバシーとサービス」の「Cookie」から設定してください。



4.7 メールスプーフィング

 メールスプーフィングはメールを送信する際に送信者の情報を偽り架空のあるいは実在の第三者になりすますことです。メールの送信者を偽ることで受信者に不信を抱かせずに電子メールを開かせやすくすることを狙った攻撃です。

 一番単純なのはメールヘッダのFromフィールドを書き換える方法です。この方法は簡単で、見破るのもそう難しくはありません。メールサーバが記録するログ情報と、電子メールのヘッダに記録される送受信記録を確認すれば、多くの場合は見破ることができます。

 SPAMメールも送信者を誤る形で送信されます。SPAMメールは量が大変で、ネットワークを圧迫したり、サーバを過負荷状態に陥れることもあります。また、添付ファイルにウィルスを入れる形で送信されるなど、他の攻撃手法の手段として使われることが多いので問題となっています。






4.8 クリックジャッキング

 クリックジャッキング(クリックジャック攻撃)は透明表示機能などによって見えないページを用意し、ユーザにそのページ上にあるボタンをクリックさせることによって、損害を与える攻撃のことです。

 「ユーザから見ると普通のサイト」の上に、「透明のサイト」が張り付けてあります。上に張り付けた透明なサイトのボタンの位置などは、下の「見えるサイト」とぴったりと合わせて作ってあります。

 あるサイトの上に、別のサイトを貼り付けるには、iframeというタグを使います。iframeは「inline frame」という意味で、HTML文書の中に、もう一つ別のHTML文書ファイルを組み込むということです。

<iframe src="example.html" allowtransparency="true">~ </iframe>

元のファイル(見えているサイト)に<iframe>タグを書き足して、別に透明ファイルとしてexample.htmlを用意します。インラインフレーム内に読み込まれる文書内のbody要素に次の記述が必要になります。

<body style="background-color: transparent;">

allowtransparency属性は、この設定内容を有効にするかどうかの指定になります。



■対策
●ブラウザで閲覧する利用者側の対策
1)ブラウザでJavaScriptやFlashなどを無効にする。
2)ブラウザやOSのセキュリティアップデートを利用する。



●サーバ側の対策
・プログラムのセキュリティアップデートを利用する。



●X-FRAME-OPTIONS
 X-FRAME-OPTIONSはMicrosoft社によって提唱されたものですが、現在は一般的に受け入れられています。X-FRAME-OPTIONSが有効に機能するにはWebサーバとWebクライアント(ブラウザ)の双方で実施しなくてはなりませんが、現在主要なブラウザでは対策が終了しています。

Webサイト設置者側の対策は次の通りです。

 HTTPレスポンスヘッダにX-FRAME-OPTIONSを付けることですが、サーバ側(Apache)で対応する場合は、httpd.confに次の記述を追加します。


・フレーム内のページ表示を全ドメインに対して禁止したい場合
Header always append X-Frame-Options DENY

・フレーム内のページ表示を同一ドメイン内のみ許可したい場合
Header always append X-Frame-Options SAMEORIGIN

・フレーム内のページ表示を指定されたドメインに限り許可したい場合
Header always append X-Frame-Options ALLOW-FROM http://example.jp
 

 PHPやJavaなどのプログラムで対応する場合は記述が若干違います。PHPで対応する場合は、header()でレスポンスヘッダに出力できます。例えば) header('X-Frame-Options: DENY')のようになります。Javaの場合は respons.addheader("X-Frame-Options", "DENY")のようになります。



4.9 フィッシング

 フィッシングは、金融機関などの正規サイト、あるいは正規のメールなどを装い、暗証番号やクレジットカードなどを詐取する行為です。

 フィッシングの手口には様々なものがあります。代表的な例としては、金融機関を騙ったメールが送られてきます。このメールはたぶんスパムで無差別に送られてきます。このメールは何とかして特定のサイトに誘導しようとする内容になっています。例えば、金融機関の例では、「このたびシステムをセキュアなものに変更しました。つきましては、ユーザの皆様には1度システムにログオンしていただく必要があります。」というような感じで、ログインを促します。そして、「このリンクをクリックしていただければ、ログインページにアクセスできます。」となっています。

 リンクをクリックすると、本物によく似た偽のサイトに誘導されることがあります。ここで、IDとパスワードの入力を求められます。あるいは、サイトは本物のことがあります。サイトは本物ですが、偽物の個人情報入力用のポップアップウィンドウが表示されます。サイトは本物で、ポップアップが偽物ということになると、なかなか気が付きにくいかもしれません。

 対策としては次のような点に注意してください。
① メールの送信者欄を信用しない。メールの送信欄は簡単に偽造できます。
② フォームの送信にSSLが利用されていることを確認。SSLを使うには認証局に登録してサーバ証明書を出してもらう必要がありますので、SSLを使っていればある程度信頼できると思ってよいかもしれません。
③ メールに示された連絡先(リンクなど)以外に、正規のものと確認できている電話番号、URLなどから案内が本物かどうかを確認すべきです。会社案内や名刺等から電話番号を調べて電話を掛けて確認するとか、ブラウザのアドレスバーに自分でURLを入力して確認することです。



4.10 ファーミング

 ファーミング(Pharming)は大手のWebサイトそっくりに作った偽サイトにターゲットを誘導して、パスワードや、クレジットカード情報、個人情報などを盗む行為です。ファーミングは「フィッシング」の手口をさらに発展させたものとされています。

 フィッシングは、個人に狙いを付けてスパムメールを送り付け、偽サイトに誘導して情報を盗み出すという手法ですので、個人に狙いを付けて、釣り上げるという一本釣りです。ファーミングは農業(farming)のイメージです。農業ですから、漁業のようにただ収穫するというだけではありません。畑を耕して、肥料を加え、土を最良の状態にしてから、種をまいて、管理して、実りの秋に収穫をする、というのが農業です。ファーミングでは、より多くの収穫(立場を変えると被害ですが)を狙って、地道に準備を整えているということでしょうか。例えば、DNSサーバの情報を改ざんしてターゲットを誘導するとか、あるいは偽のDNSサーバを立ち上げた上で、ターゲットのDNS設定ファイルを書き換えて、偽のDNSサーバに誘導するなどが考えられます。あるいは有名サイトと一文字違いのドメイン名を用意して引っかかるのを待つなどの方法が採用されます。



4.10.1 攻撃の仕組み

■DNSサーバの内部アドレスの書き換え
 DNSサーバのデータベース(ゾーンファイル)では、ドメイン名とIPアドレスの対応関係が記述されていますが、ここを書き換えられると、意図しないサイトにつながってしまいます。amazon.comのIPアドレスは2017/9/20現在で「54.239.25.200」(nslookupで確認すると他に5つほど見つかりました)となっていますが、ここを書き換えられると、amazon.comにアクセスするつもりでも、他のサイトに誘導されてしまいます。

※DNSサーバを書き換える手法についてはDNSスプーフィング(キャッシュポイズニング)で詳しく説明しました。



■ブロードバンドルータのDNSの書き換え
 自宅からインターネットを利用する場合は、ブロードバンドルータを使っていることが多いと思いますが、ここにDNSサーバが動いています。このサーバはキャッシュサーバのような感じで、一旦使った名前とIPアドレスの関係をしばらく覚えています。名前はDNSリカーシブサーバと呼ぶことが多いようです。

 OSの設定でDNSサーバを自動で見つける設定にしていれば、DNSリカーシブサーバに聞きに行き、キャッシュになければ、上位サーバ(ISPのDNSサーバなど)に聞きに行きにいく設定になっています。ウィルスなどで、この設定を書き換えられて、DNSリカーシブサーバにない時に、クラッカーが立てた偽DNSサーバに聞きに行くように設定されると、クラッカーの思いのままになってしまいます。



■偽画面での個人情報の入力
 クラッカーが用意した不正サーバに導かれると、被害者には偽画面とは気づきにくいかも知れません。例えば、VISAカードの本物のサイトのコピーが偽画面として張り付けられているような場合は、うっかりと口座番号やパスワードを入力してしまうかも知れません。



4.11 DNSリバインディング

 IPアドレスを詐称するのがIPスプーフィングですが、DNSリバインディングはその逆にドメイン名を詐称するものです。似た方法にDNSキャッシュポイズニングがありますが、こちらはキャッシュ情報を偽のものに書き換える方法です。DNSリバインディングはゾーンファイルを書き換えます。

 抽象的なことを言っても分かりにくいので、具体的に説明します。次に説明するのは、ある攻撃者がターゲットサイトに第三者を介して攻撃を仕掛ける場合です。

 攻撃者は初めに罠サイトを作成します。サイトのURLはhttp://abc.com/attackでIPアドレスは「12.34.56.78」とします。次に、「期間限定セール」などとして、メールでURLをばら撒き、このサイトに第三者をおびき寄せます。何も知らない第三者が罠サイトにアクセスしても、何も変わったことはありません。

 更に、攻撃者は罠サイトのDNS権威サーバを運用している必要があります。このDNSサーバは問い合わせに対してキャッシュ生存時間を5秒程度にして回答します。攻撃者は、このDNSサーバのゾーンファイルのデータを変更し、サイトのドメイン名に対応するIPアドレスを書き換えてしまいます。このIPアドレスは攻撃ターゲットのIPアドレス(例えば、123.45.67.89)にします。http://abc.com/attackに、5秒毎にabc.comにアクセスし直すJavaScriptが仕込まれていると、第三者のブラウザは、定期的にabc.comへのアクセスを試みますが、DNSサーバのabc.comの情報は5秒で消えてしまっていますので、権威サーバに問い合わせに行きます。しかし、権威サーバのデータはabc.com=123.45.67.89に書き換えられてしまっていますので、第三者のブラウザはターゲットマシンにアクセスに行くということになります。

 このDNSリバインディングの仕組みは、CSRF(クロスサイト・リクエスト・フォージェリ)やDoS攻撃などに悪用される恐れがあります。対策については、それぞれの項をご覧ください。



5 インジェクション攻撃

 インジェクション攻撃とは「コードや特殊文字などを挿入」(インジェクション)してWebリクエストすることで攻撃をする行為です。スクリプトインジェクション、SQLインジェクション、OSインジェクションなどの方法があります。



5.1 スクリプトインジェクション

 スクリプトインジェクションはJavaScriptインジェクションと呼ばれることもあります。Webサーバにスクリプトを含むリクエストを送信して、ページ内にスクリプトを挿入する攻撃の総称です。

※ スクリプトは簡単なプログラムです。通常のプログラムはコンパイラを使ってコンピュータが解釈できる機械語に翻訳して、必要なライブラリと結合するなどして実行可能なプログラムを生成しますが、スクリプトではこの過程をソフトウェアなどが自動で行ってくれるために、記述したコードを直ぐに実行することができます。HTMLやJavaScript、PHPなどが利用されます。

 スクリプトインジェクションにはいくつかのタイプがあります。

<タイプ1:持続型>
 1つの方法は攻撃者がスクリプトを含むリクエストを送信してサーバに保存させる方法です。保存されたスクリプトを含むページを訪れた第三者にスクリプトを実行させます。タイプ1、持続型(persistent)、Stored XSSなどと呼ばれています。

<タイプ2:反射型>
 2つ目の方法は、第三者にスクリプトを含むリクエストを送信させます。第三者が(そうとは知らずに)スクリプトを含むリクエストを、ターゲットとなるWebサイトに送信し、そのWebサイトがXSSの脆弱性を抱えていると、リクエストの応答として送られたページにそのスクリプトが差し込まれた形で第三者のパソコン上に送り込まれ、即座にそのパソコン上でスクリプトが実行されてしまうというタイプです。タイプ2、非持続型(non-persistent)、反射型(reflected)XSSなどと呼ばれています。

 タイプ2の反射型は、攻撃者が罠サイトを立ち上げ、第三者を何らかの方法でこのサイトにおびき寄せて、入力フォームに何かを入力させる、リンクをクリックさせるなどの方法で、スクリプトを脆弱性のあるサイトに送信させるという方法で実現されていました。この方法は、サイトをまたがった攻撃という意味で、クロスサイトスクリプティング(Cross Site Scripting、XSS)と呼ばれ、従来より恐れられていました。しかし、このタイプでも、HTMLメール等の本文中や、あるいはテキストメールの添付ファイル中のリンクにスクリプトを埋め込む形で、同様のことができますので、現在ではクロスサイトという呼び名は必ずしも適切ではないと思われます。あるいは、クロスサイトスクリプティングという手法はスクリプトインジェクションのタイプ2の反射型のうちのある特定の例ということになります。

<タイプ0:DOM ベース型>
 第三者にスクリプトを含むリクエストを送信させるという点では、反射型と同じですが、タイプ0では、クライアントサイドスクリプトの脆弱性が利用されている点が異なります。タイプ0、DOMベース型などと呼ばれています。

 次に、タイプ2の有名なクロスサイトスプリクティングについて具体的に見ていきましょう。



5.1.1 クロスサイトスクリプティングの仕組み

 典型的なXSS攻撃では、攻撃者は罠サイトを設けて、ユーザをそのサイトに誘い込みます。罠サイトにはターゲットとなるXSS脆弱性のあるサイトへのリンクが設定されています。このリンクには、URLのパラメータ部分にスクリプトが埋め込まれています。リンクをクリックして、XSS脆弱性のあるサイト(ターゲットサイト)を開くとページ内に自動的に悪意のあるスクリプトが埋め込まれて、即座に閲覧者のWebブラウザで実行されます。

※URLパラメータ(URLクエリパラメータ):CGIプログラムに対して引数を渡したい場合がありますが、この場合はCGIプログラムのURLの末尾に引数を記述する形で渡します。動的ページ(CGI)は通常"cgi"や"php"などの拡張子で終わっていますが、このURLの末尾に"?"を付けてその後に動的ページ(URL)に渡す引数を記述します。これを、URLクエリパラメータといいます。クエリ(query)は検索を行う場合の検索条件のことで、検索項目(パラメータ変数)=検索値(パラメータ値)の形式で指定します。引数を複数使う場合は"&"で接続します。<a href='http://脆弱サイト/abc.cgi?def=1234&ghi=5678'>ここをクリック!</a>という記述があれば、"GET /脆弱サイト/abc.cgi?def=1234&ghi=5678' HTTP/1.1"というデータがサーバに送信されます。

 スクリプトに書かれているのは、ターゲットサイトのCookieデータを攻撃者に送るとか、ターゲットサイトのページの内容を不正に改竄するとかということになります。

 例えば、攻撃者の罠サイトAに次のコードが書かれていたとするとどうなるでしょうか。簡単に図解してみましょう。

<a href='http://脆弱性サイトB/get-cookie.php?q=<script>攻撃者のPCにCookieを送信;</script>'>ここをクリック</a>


<ステップ1> ユーザを罠サイトに誘導
 攻撃者が罠サイトを作成して、そのサイトのHTMLに上の一行を加えて、被害者をおびき寄せます。おびき寄せるのは難しいと思います。ちょっとした知り合いのさらにまた一時的な知り合いというような希薄な人間関係を利用して、おびき寄せる場合もあるでしょう。あるいは、スパムメールのような手段が使われるかもしれません。兎に角、何とかして偽のサイトにおびき寄せる必要があります。

<ステップ2> ユーザのブラウザ上にページ表示
 ユーザのブラウザ上に、「ここをクリック」というリンクが表示されます。

<ステップ3> ユーザが「ここをクリック」というリンクをクリック
 ユーザのブラウザ上に表示された「ここをクリック」というリンクを何とかして、押させなくてはなりません。しかし、ユーザにクリックさせるのではなく、自動的に次のページに飛ぶような方法も可能です。「このページは移動しました。○○秒後に自動的に移動します。」というようにしておけば、時間の経過をユーザの動作に置き換えることができます。

<ステップ4> ユーザがXSS脆弱性のあるサイトにアクセス
 ユーザがXSS脆弱性のあるサイトBにアクセスすると、get-cookie.phpというスクリプトが実行されます。スクリプトは<?php get-cookie $_GET['q'];//攻撃者のPCにcookieを送信 ?>となっています。

<ステップ5> ユーザのPCがスクリプトをGET
 ユーザのPCにスクリプト'q'がGETされます。

<ステップ6> ユーザのPCでスクリプトが発効
 ユーザのPC上で「攻撃者のPCへCookieを送信」というスクリプトが即座に実行されます。

<ステップ7> Cookieが攻撃者のPCへ



5.1.2 スクリプトインジェクション対策

 アプリケーションは入力値を受け取り、それを処理し、出力するという流れの組み合わせで作られています。そこで、入力値をチェックするという方法と、処理方法をチェックするという2つのチェック方法がありえます(出力をチェックしてももう遅い)。

 タイプ1の持続型と、タイプ2の反射型は攻撃者が自分で入力を決めていて、それを自分でターゲットに送信するか、第三者に送信させるかの違いですので、入力値をチェックすることはできません。そこで、攻撃対象のアプリの開発者が処理をチェックしているかということになります。方法としては、リクエストのパラメータにスクリプトで特別な意味を持つ特殊文字が入っている場合には、それを文字参照に変更してしまうことです。この処理をサニタイジング(sanitizing、無毒化)といいます。

※HTMLやJavaScriptでよく使われる「<」「>」「&」「"」などを「<」⇒「&lt;」、「>」⇒「&gt;」、「&」⇒「&amp:」、「"」⇒「&qout;」などに置き換えることで無毒化することができます。


 タイプ0はクライアントサイドの脆弱性が狙われていますので、リクエストフォームを作る側の注意が必要です。Webサーバのコードに問題がなくても、クライアントサイドのJavaScriptに脆弱性があるために問題が発生することもあります。



5.2 SQLインジェクション

 多くのWebアプリケーションではデータベース(RDB)と連携していて、データベースを操作するためにSQLという言語を使用しています。SQL文を使って問い合わせやデータベースの操作を行うときに、ユーザがフォームから送信した検索語などのパラメータを受け取り、これをSQL文に埋め込むと、システム開発者、運用管理者が想定していないようなSQL文が出来上がってしまうことがあります。このようなプログラム上の盲点をついて、不正にデータベースを操作したり、本来アクセスできない情報を表示させてしまうようなことを、SQLインジェクションといいます。

 SQLで検索をする場合のselectは次のようになります。

select 項目名 from テーブル名 [where 検索条件] [order by ソート方法];

 これでテーブル名(表名)で指定されたテーブルから、検索条件にマッチするレコード(1行分のデータ)を選び、項目名で指定された項目を、ソート方法にしたがってソートして返します。

 select文で、キーワード「select」の後に続いて項目名(列名)を指定する部分を「select句」、fromでテーブル名を指定する部分を「from句」、whereで検索条件を指定する部分をwhere句といいます。

 [where 検索条件]を省略すると、全件検索となります。「order by ソート方法」を省略すると、レコードの並びが決まりません。

 Where句の「条件値」として、文字や日付データを指定するときは単一引用符(シングルクォーテーション)(')で囲む必要があります。

※ダブルクォーテーションはシングルクォーテーションと同等の扱いを受けますが、文字を括る場合は、シングルクォーテーションを使ったほうが良いとされています。SQLは多くのプログラミング言語と連携して使うケースが多く、例えば、PHPで書く場合は、$sql="SELECT * FROM テーブル名 WHERE userID='$ID'"と書くと、$IDは変数として処理してもらえます。しかし、$sql='SELECT * FROM テーブル名 WHERE userID="$ID"'と書くと、$IDは変数として処理してもらえません。これは、多くのプログラミング言語がシングルクォーテーションで括った場合は、変数を展開しないという規則を持っているためです。従って、SQL文では、括り文字としてはシングルクォーテーションを使った方がいいと思います。

 今、次のような構造のuserTableという名前のテーブルがあるとします。

userTable 
項目名 属性
UserID 文字項目
userName 文字項目
grade  数字項目 

ここで、次のようなSQL文を実行します。

SELECT userID,userName from userTable where userID='john';

このSELECT文では、userTableという名前のテーブルから、userIDがjohnという人を検索し、この条件に合う人のuserIDと、userNameを取得します。where以下の検索条件を変えればいろいろのデータを取り出すことができます。しかし、1回ごとのSELECT文を書き換えなくてはなりません。

 アプリケーションでは、ユーザの検索条件がどのようなものでも対応できるようにuserIDに与える検索条件を変数にして次のようなSELECT文を使います。

SELECT userID,userName from userTable where userID='$ID';

 ここで入力フォームから入力された値を変数$IDに代入することにします。ここで入力フォームに与えられた値が適切な値かどうかの判断がなされていない場合に、SQLインジェクションが発生してしまいます。$IDにjohnという文字が代入されれば問題ありません。しかし、例えばjohn' or 'A'='Aのような値が入力されたらどうでしょうか。userID='john' or 'A'='A'となってしまいました。これはwhere userID='john' or 'A'='A' となり、userIDがjohnの場合か、あるいは'A'='A'が成り立つ場合ということになり、常に成り立つことになってしまいます。つまり、全ての行のuserIDとuserNameを取り出すということになります。この結果、本来できてはいけないデータを取得することが可能となってしまいます。

 このような場合は「'」を「"」にエスケープすることで、john"or "A"="Aとなり、条件式はuserID='john"or "A"="A'となり、userIDが「john"or "A"="A」のレコードが選択されます。

 SQL文の括り文字には「'」「"」が使われます。userIDが文字項目で、変数の括り文字を「"」にしている場合は、次のようになります。

SELECT userID,userName from userTable where userID="$ID";

この場合も同様で、alice" or "A"="Aのような値を代入されると、やはりいつでも成り立ってしまいます。「"」を「""」でエスケープすれば間違いは起こりません。

 似たような検索条件のSQL文には次のようなものがあります。これらもみんな同じような問題を抱えています。

SELECT userID,userName from userTable where userID='$ID';
DELETE from userTable where userID='$ID';
UPDATE userTable grade=3 where userID='$ID';

 検索条件を曖昧にしたい場合には「=」の代わりに「LIKE」をつかい、検索条件は「%」で囲います。「LIKE %山田%」とすると、細山田や、山田錦などがマッチします。末尾が「山田」となる後方一致の場合は、%山田とします。山田*となるような前方一致は山田%となります(山田川、山田山、山田原などが一致)。従って、LIKEや%などもエスケープする必要があります。

 userIDが数字項目の場合は次のようになります。

SELECT userID,userName from userTable where userID=$num;

userIDが数字項目である場合に、userID=aliceと代入されると、数字でないものが代入されたので、エラーになります。しかし、「1 or 1=1」という文字列を代入すると、userID=1 or 1=1なり、SQL文は、SELECT userID,userName from userTable where userID=1 or 1=1;となり、「1=1」という条件が常に成り立つことになってしまいます。これは、変数への代入値が本当に数字なのかを検査しなかったために起こった不都合です。変数に入力する前に入力値が数字かどうか検査していれば、「1 or 1=1」は文字列なので入力できなかったはずです。

 他にも危険な構文があります。次は、文字項目のデータを更新(update)する場合について見ていきます。

 UPDATEのSQL文は次のような構文になります。

UPDATE テーブル名 SET 項目名=値 WHERE 更新する行を特定する条件:

 次のようなpersonnelTableで考えてみましょう。

personnelTable
項目名 属性
emp 文字項目
dept 文字項目
loc 文字項目

 
UPDATE personnelTable SET loc='$LOC' WHERE dept='account';

 変数に対する入力値に文字括りに「"」「'」などが含まれていると、設計者の予想しなかったような結果になることがあります。例えば、入力値が「hakata';--」だとすると、次のようなSQL文ができます。

UPDATE personnel SET loc='hakata';--' WHERE dept='account';

SQL文では、「--」以降はコメントとみなされるため、WHERE句がコメント化され、全件がマッチしてしまうことになります。「"」「'」だけでなく「--」もエスケープ処理する必要があることが分かります。

 最後にプロシージャ(procedure)の話をします。SQLサーバには「Transact-SQL」というプログラミング言語が用意されています。Transact-SQLで作成したプログラムは、SQLサーバ上に保存し、SQL文から呼び出すことができます。このプログラムのうち、サブルーチンとして機能するのが「ストアードプロシージャ」で、関数として機能するのが「ユーザ定義関数」です。ストアードプロシージャにはユーザが作成するものと、SQLサーバのインストール時に既に定義されているものがあります。SQLサーバのインストール時に既に定義されているプロシージャを「システム・ストアードプロシージャ」と呼びます。

 プロシージャーはcreateコマンドで作成し、変更の必要があればalterコマンドで修正します。できたプロシージャはexecuteで呼び出して実行します。executeは「exec」と略記することができます。

exec プロシージャー名 $DATA;

このプロシージャーの引数が「1; delete from personnelTable;」だとすると、次のようなSQL文となります。

exec プロシージャー名 1; delete from personnelTable;

このSQL文では、ストアードプロシージャーが実行された後で、personnelTableのレコードが全て削除されます。この場合にもプロシージャの引数として何が代入されるかをよく考えて、意図しないデータが入力されないようにチェックをする必要があります。






5.3 HTTPヘッダインジェクション

 HTTPヘッダインジェクションは、HTTPを使って通信をするシステムにおいて、動的にHTTPヘッダを生成する機能の不備を突いてヘッダ行を挿入することで不正な動作を行わせる攻撃手法です。

 HTTPヘッダインジェクションを理解するためには、HTTPの基本的な仕組みの理解が欠かせませんのです、少し復習してみましょう。

 HTTPを利用した通信はユーザがWebブラウザを使ってリクエストし、Webサーバがこれに応えて、レスポンスを返します。

 リクエストは「ステータスライン(リクエストライン)」「リクエストヘッダ」「リクエストボディ」からなります。ただし、メソッドがGET、DELETE、HEAD、OPTIONSの場合のリクエストボディはデータ種別として、「データなし」が選択されますので、HTTPリクエストボディを送信しません。従って、GETメソッドでCGIプログラムに何らかのパラメータを送信する場合には、ヘッダ行(リクエストヘッダ)で送るしかありません。

 HTTPではCGIプログラムに引数を与える場合に、クエリという方法でデータを渡します。クエリはURLの指定をするときに、URLの末尾に「?」を付けて記述します。これが、GETメッソッドで、パラメータを送信する方法です。

※リクエストラインは、ヘッダの最初の1行目の「メソッド URL/?query=abc」です。メソッドがGETの場合は、「GET /www.example.com/abc.cgi?def=1234 HTTP/1.1」のようになります。

 レスポンスは、ステータスライン(レスポンスライン)、レスポンスヘッダ、レスポンスボディとなります。

※レスポンスラインは「HTTPバージョン ステータスコード リーズンフレーズ」。応答が成功の場合は、「HTTP/1.1 200 OK」のようになります。

 例として次のサイトにアクセスすることを考えてみましょう。

http://あるサイトA/abc.cgi?redirect_url=●●●●

 このリクエストを受け取った「あるサイトA」は●●●●を、レスポンスヘッダの「Locationヘッダ」に設定して、レスポンスします。これはブラウザに、「リダイレクト」という処理を命令するもので、ブラウザはLocationヘッダを受け取ると、直ちに指定されたURLに移動します。これをリダイレクションといいます。これはHTTP認証でユーザをIDとパスワードで制限する機能やファイルをダウンロードさせる機能を実装したりする場合に普通に利用されている手法です。

※レスポンスヘッダで「Location:http://www.google.com」のように返されると、ブラウザは即座にhttp://www.google.comにリダイレクトします。この場合は、レスポンスのステータスコードは302となります。Locationヘッダは絶対パスで指定しなくてはなりません。

 これでHTTPヘッダインジェクションを理解するための準備が整いました。HTTPヘッダインジェクションで、インジェクト(inject、差し挟む)されるのは改行コード(CR+LF)です。レスポンスヘッダに改行コードが挿入されると、ヘッダ行はそこで終了し、それ以降は新たなヘッダ行と解釈されますので、レスポンスヘッダは、「レスポンスヘッダ1」(CR+LF)「レスポンスヘッダ2」のように分割されてしまいます。もし、レスポンスヘッダに改行コードが2つ挿入されてしまうと、空行が1行挟まってしまいます。ブラウザは空行以降をレスポンスボディと解釈してしまいます。

 CRはASCIIコードでは、「0x0D」、LFは「0x0A」ですから、これがHTTPヘッダに入ります。URLには非ASCII文字も入りますので、URLではパーセントエンコード(いわゆるURLエンコード)という変換方法が使われます。これは文字コードを16進で表し、「%xx」(xxは16進数)という形に変換したものです。従って、改行は「%0d%0a」ということになります。

※システムによっては、%0dだけ、あるいは%0aだけで改行コードとみなされます。

 ●●●●の中に改行コードがなければ、locationで指定されたURLにリダイレクトするだけです。●●●●の中に改行コードを挿入されてしまうと、その改行コード以降は別要素のヘッダ行と解釈されてしまいます。改行コードを2つ挿入されると(空行)、改行コード以下がレスポンスボディと解釈されてしまいます。レスポンスボディなら任意の文字列が入りますので、HTMLやJavaScriptのコードを書き入れることができます。こうなると、改行コード以下のコードがブラウザのPC上で実行されてしまう可能性があります。

 HTTPヘッダインジェクションの脅威としては、クロスサイトスプリクティング攻撃と同じ脅威、あるいは任意のCookieの発行、キャッシュサーバのキャッシュの汚染などが考えられます。

 Cookie発行の例は次の通りです。
http://example.co.jp/abc.cgi?redirect-http://example.com/345%0D%0ASet-Cookie:+SID=ABCD12$%
攻撃サイトに誘導されうっかりと上のようなURLが埋め込まれてリンクをクリックしてしまうと、example.comにリダイレクトする際にブラウザにCookieを埋め込まれてしまうかも知れません。このCookieは予め攻撃者がexample.comから得ていたものである場合、被害ユーザがこのCookieを使って、example.comにログインしていると、このサーバにとっては、ログインしているのは攻撃者ですので、攻撃者は自由にサーバにアクセスし、被害ユーザの秘密情報を盗み見ることが可能です。

 HTTPヘッダインジェクションへの対策としては、リクエストヘッダの値を、そのままレスポンスヘッダの値に設定しないこと、リクエストヘッダの値を、レスポンスヘッダの値へ設定しなくてはならない場合は、「改行コード」をエスケープすることです。



5.4 メールヘッダインジェクション

 メールヘッダインジェクションとは、問い合わせフォームなどのメールを送信する画面で、迷惑メールの送信などをされてしまう脆弱性です。メールの宛先に改行コードを挿入することで、新しいメールヘッダを追加し、本来の宛先以外にメールを送信することができます。

 メールメッセージヘッダは各フィールドが改行で区切られています。アプリケーションが外部から指定するパラメータの改行をチェックしていない場合、ヘッダや本文を追加・変更することができます。例えば、送信フォームのFROMアドレス用のボックスに、「aaa@example.jp (改行コード) Bcc: bbb@examplecjp」とすると、勝手にBccヘッダを挿入して、そこにメール送信をすることができます。添付ファイルを追加したり、ヘッダに空行(改行コードを2つ)を入れるとそれ以降は本文として扱われることになりますので、本文を改ざんすることも可能です。

 対策としては、メールの宛先、件名などのメールヘッダを固定して、メールヘッダに外部からの入力をさせないようにしてください。あるいは、外部からの入力を許す場合は、改行を含まないようにチェックしてください。



5.5 OSコマンドインジェクション

 OSコマンドとは、OSを操作するためのコマンド(命令)のことです。OSコマンドインジェクション(command injection)は、このOSコマンドを不正に挿入すること(injection)で、攻撃する方法です。

 閲覧者からデータの入力や操作を受け付けるWebサイトで(WebアプリケーションやCGIスクリプト)において、リクエストパラメータ(HTMLフォーム)にOSコマンドを含めることで、Webサーバ上でOSコマンドを実行することができます。

 OSコマンドを実行されてしまうと、Webサイトのデータ改ざん、重要情報の漏えい、削除などの被害に遭う可能性があります。最悪の場合はWebサイトが乗っ取られて他のWebサイトへの攻撃の際の踏み台にされてしまうことも考えられます。踏み台にされると攻撃された側からは、踏み台にされたWebサイトからの攻撃にしか見えませんので、攻撃者あるいは犯罪者としての濡れ衣を着せられることになり、会社としての評判・信用を大きく低下させることになってしまいます。

 Webサイトのシステム側で、命令文となる不正な文字列をはじくように設定されていない場合、文字列を適切に処理できず、不正プログラムの感染や情報漏えいなどを引き起こされる可能性があります。例えば、入力フォームからメールアドレスを入力させ、それをメールプログラムに渡すという場合は、「test@example.com; rm -rf /」と入力されると、test@example.comにメールを送信した後で、"rm -rf /"を実行してしまいます。

※rmは「remove」コマンドと呼ばれるもので、ファイルやディレクトリを削除するコマンドです。"-"に続くのはオプションで、"-rf"は、"-r"と"-f""を同時に指定したことになります。"-r"はディレクトリの中を再帰的に(recursively)削除するという意味です。したがって、指定したディレクトリの配下にディレクトリがあれば、そのディレクトリの中のファイルも、ディレクトリも全部削除しなさいという命令になります。"-f"は「警告メッセージを表示しない」というオプションで、通常であれば、削除コマンドを実行したときは「本当に削除しますがいいですか」と聞いてくるのですが、「そんなメッセージはいらないよ」と言ったことになります。"/"はルートディレクトリです。ファイルシステムは、ツリーを逆にした構造で管理されていますので、ルートディレクトリは、一番上のディレクトリになります。従って、"rm -rf /"コマンドは、ルートディレクトリ配下の全てのファイルとディレクトリを再帰的に、しかも警告メッセージなしに消してしまいなさいと命令したことになります。つまり、決してやってはいけないことを実行してしまったということです。

 特権ユーザ(superuser、root)でないと実行できないコマンドの場合は、権限レベルを上げて実行しなくてはなりません。普段一般ユーザ権限で利用している人が、特権ユーザレベルの権限を利用する場合に使われるのがsudoコマンドです。従って、"rm -rf /"は"sudo rm -rf /"となっているかも知れません。

 削除の対象を"*"や"."で指定するのも危険です。"rm -rf *"は、現在のカレントディレクトリ内のディレクトリと、ファイルを強制的に削除します。"rm -rf ."は現在のディレクトリとサブディレクトリを強制的に削除します。

※その他の危ないコマンド: 例えば、Linuxだと、"shred /dev/sda/"です。"shred"はファイルを上書きし、完全に消去するというコマンドです。/dev/sdaはOSが最初に見つけたHDDにつける名前です。2番目に見つけたHDDは/dev/sdbと名付けられます。従って、上のコマンドで、ファイルシステムがズタズタにされてしまいます。もし仮に、sdaドライブが3つのパーティションに切り分けられている場合は、sda1、sda2、sda3となります。

※その他の危ないコマンド:"ls -la > /dev/sda" は、ls -laの出力を、/dev/sdaに直接書き込んでしまいます。従って、/dev/sdaの内容が上書きされて消えてしまいます。"ls"はファイルやディレクトリの情報を表示する"コマンドです。オプションの"-a"は全部のファイル(ファイル名の先頭にピリオドがあるような特殊なファイルを含めて)を表示するという意味です。"-l"はファイルの詳細についても表示するという意味になります。かなり大量の出力があります。

 
"> [ファイル]"は何も指定せずにファイルに対して上書きを指定しています。何も指定しないで上書きだけを命令していますので、ファイルに0バイトが上書きされます。つまり、ファイルの中身が消えてしまいます。例えば、"> /etc/nsswitch.conf"を実行すると、"/etc"の配下にあるnsswitch.confという設定ファイルが消えてしまいます。


※その他の危ないコマンド:他に危ないものとしては、"mv / /dev/null"があります。"mv"はmove(移動)コマンドです。"mv A B"は"rm B;cp A B;rm A"とイコールです。/dev/nullはUNIXやLinux系のOSでは、ごみ箱のような働きをしています(/dev/nullに書き込まれたデータは全て捨てられます)。従って、"mv / /dev/null"で、ルートディレクトリが全部消えてしまうことになります。これ以外には、"mkfs.ext4 /dev/sda1"などがあります。mkfs.ext4は、"ext4"でファイルシステムを作る(フォーマットする)という意味になりますので、/dev/sda1が"ext4"でフォーマットされてしまうことになります。


※その他の危ないコマンド:"dd"はディスクに直接書き込みをするコマンドで使い方を間違えると危ないです。入出力を指定するオプションは"if=[file]"(標準入力の代わりに、ファイルfileから読み込む)と、"of=[file]"(標準出力の代わりに、ファイルfileへ書き出す)です。"dd if=/dev/random of/dev/dsa"、"dd if=/dev/urandom of/dev/dsa"で、乱数値を/dev/sdaに書き込むことになります。"/dev/random"、"/dev/urandom"は乱数を生成してくれる擬似デバイスです(randomとurandomの違いはエントロピーの違いです)。"dd if=/dev/zero of/dev/dsa"だと、/dev/sdaにゼロを書き込むことになります。

※/dev/randomと/dev/urandomの違いはエントロピーの違いです。Linuxでは、人間がkeyboardをたたくような「何だか分からない」タイミングの要素で、乱数を作っていますが、「何がどーなるか分からない」という要素(エントロピー源)が足りている場合に初めて乱数を発生させるのが/dev/randomで、/dev/urandomはエントロピーがまだ不十分な状態でもとりあえず乱数を発生してくれます(乱数として十分じゃないかもしれないが、とりあえず発生してくれるということです)。

※rmはUNIX、Linux系のコマンドです。Windowsは基本的にはコマンドラインで操作するOSではありませんので、UNIXやLinuxほど危ないコマンドはありませんが、まったくないというわけではありません。UNIX、Linux系の"rm -rf /"に該当するWindowsコマンドが"cmd /c rd /s /q c:\"です。"cmd"はコマンドの実行で、オプションの"/c"は、後続する文字列で指定されたコマンドを実行後、終了するという意味になります。"rd"はディレクトリの削除です。オプションの"/s"は、指定したディレクトリに加えて、ディレクトリ内の全てのディレクトリとファイルを削除するという意味です。"/q"は確認メッセージを表示しないというオプションです。これで、"c:\"配下の全てのファイルとディレクトリが確認メッセージなしで、削除されてしまいます・・・このコマンドはWindows Vista以降は管理者権限がないと実行できないようになっています。

※Windows系のコマンドでは、"for /L%a in (0,0,0) do start"というのもあります。"for"はコマンドの反復実行です。構文は"for %変数 in(ファイル名セット) do コマンド [コマンドパラメータ]"です。コマンドの"start"は「コマンドプロンプト」の起動です。オプション"/L"(小文字でもokですが、紛らわしいの大文字にしました)は、初期値、終了値、ステップ値を指定してコマンドを実行できます。例えば、"for /L %i in (0,2,10) do @echo %i"は変数%iの初期値を0にして、2ずつ増加しながら、終了値10になるまで、@echo %i(変数%iを出力)となります。"for /L%a in (0,0,0) do start"は、変数%aは初期値を0として、0ずつ増加して、終了値0以下の間(つまり、ずーっと)、コマンド(コマンドプロンプトの起動)を繰り返すことになります。これは、Fork爆弾と呼ばれるもので、実行すると新しいプロセスは生成できなくなります。

※LinuxでFork爆弾として有名なのが、":(){ :|: & };:"です。最初の":()"は":"という関数の定義です。引数はありません。次の{ };が、関数の本体です。自分自身を2つ起動し、パイプでつないでいます。パイプとは、標準出力をそのまま別のプロセスの標準入力に渡すことを意味します。&はそれをバックグラウンドで実行することを意味しています。最後の":"は関数名の指定で、この関数の実行を指示しています。":"は2つの子プロセスを生成する(子プロセスはfork関数で作成)ことになりますので、プロセスは鼠算式に急増します。OSはプロセステーブルでプロセスの管理をするのですが、Fork爆弾が炸裂すると、倍々式にプロセスリストが作られ、瞬くうちにテーブルが一杯になってしまいます。こうなるといずれかのプロセスを終了させない限り、新しいプロセスは生成できなくなります。たとえ、1つのプロセスを終了させて、対処のためのプロセスを生成しようとしても、Fork爆弾のプロセス群が空いたスロットをすぐさま埋めようとするので、対策のためのプロセスを立ち上げることもできません。
 Fork爆弾はプロセステーブルを埋め尽くす(新しいプロセスが起動できない)だけでなく、CPU時間やメモリを占有してしまいますので、現在稼働中のプロセスも動作が困難となります。

 Fork爆弾は悪意を持って仕掛けられることもありますが、通常のソフトウェア開発で偶然Fork爆弾が発生してしまうこともあります。


 以前より広く知られた攻撃方法で、多くの場合対策されていると思いますが、対策としては、次のようなことが推奨されます。

① OSコマンドの呼び出しをできるだけ使わない。
② シェル呼び出し機能のある関数の使用を避ける。
③ 外部から入力された文字列をコマンドラインのパラメータに渡さない。
④ OSコマンドに渡すパラメータを安全な関数によりエスケープする。
⑤ 外部プログラムを呼び出さない。
⑥ Webサイトの入力フォームにデータを入れる場合は、HTMLタグ、JavaScript、SQL文などを検出し、それらを他の文字列に置き換える。



5.6 DLLインジェクション攻撃

 DLLインジェクションはその名の通りDLLを注入すること(injection)です。DLL(Dynamic Link Library)とは、動的なリンクによって利用されるライブラリです。DLLでは、様々なアプリケーションで利用される汎用的な機能をモジュール化し、アプリケーションからリンクで読み出せるようにしてあります。動的にリンクされているので、プログラム間で重複したコードを共有化し、メモリ占有量やHDD読み込み時間などを削減することができます。

 DLLは元々はWindowsの言葉で、Windows OSは機能のほとんどをDLLの形で提供しています。UNIX系のOSでは「共有ライブラリー」と呼ばれますが、最近ではUNIX系のOSでもDLLや「ダイナミックリンクライブラリー」という言葉が使われることもあります。

 DLLインジェクションはマルウェアによる攻撃の一種として使われています。この攻撃は非常に厄介で、今後もっと扱い難いものに進化しそうな気配さえもあります。

 DLLインジェクションはアプリケーションの中に動的にリンクされて使われますので、ポート番号やプロセスなどによるアクセス制限では通り抜けてしまいます。それはどういうことでしょうか。通常のファイアウオールはポート番号などによって(つまり、通信プロトコルによって)通信を識別して許可/拒否の判断をします。例えば特定のマルウェアが特定のプロトコル番号を持っている場合は、そのプロトコル番号を拒否してしまえば済みます。HTTPと同じプロトコル番号を使っている場合は、これを拒否します。こうすると、Webも使えなくなってしまいますが、分かりやすいですね。パーソナルファイアウォールというパソコンに入れて使うタイプのファイアウォールではプロセス毎に許可/拒否をします。例えば、素直なマルウエァの場合は独立して通信をしますので、自分がプロセスとなって通信をします。このプロセスを拒否してしまえば、このマルウェアはブロックできます。しかし、DLLインジェクションで注入されたマルウェアは自分がプロセスになるわけではありません。例えばIE(Internet Explorer)に中にマルウェアがDLLとして注入されると、プロセスとしてはIEのプロセスですので、このプロセスを止めてしまうと、IE自体が使えなくなってしまいます。パーソナルファイアウォールの手法でも、IEの中の特定のDLLだけを止めることはできません。



5.7 フォーマット文字列攻撃

 フォーマット文字列攻撃(書式文字列攻撃、format string attack)は、printf()などの書式指定のある関数を使って、メモリバッファオーバーフロー攻撃と同様に動作する攻撃手法です。printf()やsyslog()などのライブラリー関数は豊富な書式編集機能を持っていますので、これを悪用されると深刻な事態になります。

 悪意のあるユーザがprintf()の%sや%xといった書式指定子(書式トークン)を使うと、スタックやその他のメモリ位置に内容をデータとして出力させることができます。また、フォーマット指定子%nを使って任意のアドレス位置に任意のデータを書き込ませたりすることができます。

 具体的には、特定のアドレスに侵害コード(機械語のコード)を書きます。そして、関数の戻りアドレスの格納場所に、侵害コードを書いたアドレスを入れると、printf()から制御が戻ったときに悪意の侵害コードが実行されてしまいます。

*** 初歩の確認 ***
 余り納得のいっていない人向けに初歩的な説明をしています。分かっている人は飛ばしてください。

 初めにprintf()の書式です。

 printf(書式文字列、可変個引数);

例)
int a=65;
printf("data = %d %x %c\n", a, a, a);
出力結果は
data = 65 41 A(復帰改行)

%で始まるのは変換指定文字(書式指定子)です。%dは10進数で出力、%xは16進数で出力、%cは文字型で出力という指定です。従って、65がそれぞれ10進数、16進数、文字型で出力されています。\nは復帰改行です。

 printf()は特殊な関数で、引数の個数が一定ではありません。書式文字列の中に変換指定文字がなければ、引数は書式文字列だけで、他の引数は必要ありません。例えば、printf("Hello World.\n");は書式文字列の中に変換指定文字がありませんので、引数は書式文字列だけです。printf("data = %d %x %c\n", a, a, a);の場合は、書式文字列の中に変換指定文字が3つありますので、引数は更に3つ必要ということになります。ただし、printf()では引数がいくつなくてはならないというようなことは配慮していません。4つ必要なのに引数が1つしかなければ、スタックの引数のあるべき場所に格納されている値を出力してしまいます。これを使うと、スタックの中を覗くことができます。これでどういう変数がどういうアドレスに格納されているかが分かります。

 printf()を使うとアドレスも表示できます。アドレスを表示させるための変換指定は%pです。「&」はアドレス演算子と言います。「&a」とすると変数aのアドレスを表します。printf("aのアドレス:%p\n", &a);とすると、変数aが格納されているメモリ上のアドレスが表示できます。

 書式指定文字(書式指定子)の%nは問題を引き起こします。「(s)printf()で書式文字列内に%nが指定されると、そこまでに出力された文字列の文字数が%nに対応する位置のポインタ変数の指す整数型変数に格納される」ということになっています。%nは、これまでの書式編集出力で何バイトのデータが書き出されたかの値を整数変数に書き戻すことを指定する書式です。

int count;
printf("%d%n", 1234567, &count);

これで変数countに値7が入ります。%nより前に行われる書式編集出力の桁数が十分に大きければ、アドレスのような値を書き込むことができます。これで、関数のリターンアドレスの格納場所、例外ハンドラーアドレスの格納場所、関数ポインターの格納場所などを自由に指定することができます。スクリプトを利用すれば、少し長めのコードを、指定したアドレスに送り込むこともできます。

 フォーマット(書式)文字列攻撃は、動作中のプログラムのメモリに機械語を送り込んで、実行させるもので、メモリバッファオーバーフロー攻撃と同様な攻撃手法です。ただ、フォーマット文字列攻撃は、printf()関数等を使うことで簡単に成功してしまいます。



■フォーマット文字列攻撃の対策

1) printf()関数の引数に外部から指定可能な文字列を渡さないこと。これを許すと、ほとんど任意のアドレスの値を読んだり、書き込んだりすることができます。
 どうしても外部からの書式文字列を受け入れざるを得ない場合は、許可する文字列パターンを明確に定め、そのパターンにマッチしているか確認してから使用を許すようにしてください。その際には決して%n書式を許可しないようにしてください。

 C11(2011年以降のC言語仕様)では、%nは廃止されています。printf系の関数でC11仕様が対策を施しているのは、ファイルに出力する関数では、printf、vprintf、fprintf、vfprintf、dprintf、vdprintf、wprintf、vwprintf、fwprintf、vfwprintfなどがあります。既存の文字列領域に出力する関数で、領域長の引数があるものとしては、snprintf、vsnprintf、swprintf、vswprintfなどがあります。既存の文字列領域に出力する関数のうち、領域長の引数がないものは使用は推奨されていません。

2)gcc 4ではフォーマット文字列攻撃脆弱性の恐れのある箇所を指摘してくれるオプションの"-Wformat=2"を使えます。

※gccはGNUのコンパイラ群(GNU Compiler Collection)です。

3)gccの"-D_FORTIFY_SOURCE=2"の指定:このオプションを使うと、ライブラリを使うときにもっと堅固な関数を使うようにメッセージを出してくれます。

4)バッファオーバーフローと共通の対策

●外部から侵害コードを入力されないように厳密にチェック
●スタックセグメントの位置のランダム化(固定アドレスの書き替えや固定アドレスへのジャンプを狙う攻撃を不成功に終わらせることができます)ができる場合それを利用
●データ領域におけるコード実行の防止ができる場合は、それを利用



6 クロスサイト攻撃

6.1 クロスサイト・リクエスト・フォージェリ

 クロスサイトリクエストフォージェリ(Cross Site Request Forgeries;CSRF、XSRF)は掲示板や問い合わせフォームなどを処理するWebアプリケーションが、本来拒否すべき他のサイトからのリクエストを受信し、処理してしまうという脆弱性です。

 攻撃者は攻撃用のWebページを用意して、第三者ユーザをおびき寄せます。攻撃者の用意したWebページにはスクリプトや自動転送(HTTPリダイレクト)などが仕込まれています。第三者であるユーザはCSRFの仕込まれたサイトにアクセスするだけで、攻撃者が用意した不正のHTTPリクエストを送信させられます。ただし、この場合はユーザは既に標的サイトにログインしている状態であるということが前提です。ユーザが標的サイトにログインした状態で、この状態を使って攻撃者は第三者ユーザの振りをして、自分のリクエストを送り込みます。送信されたHTTPリクエストによって、標的サーバでは、攻撃者の意図した攻撃が行われます。

 攻撃者は標的サーバにアクセスすることなく、標的となっているWebアプリケーションに任意の処理を行わせることができます。攻撃用サーバに誘導された一般ユーザには直接的な被害はありませんが、標的サーバに不正なリクエストを送信した攻撃者と認識される恐れがあります。

 CSRFを利用して行われる攻撃としては、いたずら的書き込み、不正サイトへの誘導、掲示板やアンケートフォームへの不正な書き込み、不正な書き込みを大量に行うDoS攻撃などがあります。

 Cookieに紐づけられて保存されているセション変数にも注意が必要です。ショッピングサイトでの「カートへの追加」「内容確認」「購入完了」のようなフローもセション変数を使って実現されています。セション変数を上書きされてしまうと、買ってもいないものを買わされてしまうことも考えられます。

 ブラウザでアクセスしただけで実行されてしまいますので、ユーザとしてはなかなか根本的対策が見つからないというのが現状ですが、Webサイトで作業をしている場合は、作業が済んでログアウトするまでは、決して他のサイトの行ってはいけないということは守っていただく必要があります。

 サーバ側の対策としては、サイト外からのリクエストの受信を拒否することです。ヘッダに含まれる情報を元にして参照元が正規のページかどうかチェックしたり、フォームの一部にランダムな数値を隠しておいてアクセスの一貫性をチェックしたり、画像として表示したチェックコードの入力をユーザに要求するなどの手法があります。



6.2 クロスサイト・クッキング

 クロスサイト・クッキング(Crosssite cooking)は、サイトを攻撃する者にブラウザ用のCookieを別のサイトサーバのクッキードメイン(Cookie Domain)にセットすることを許すブラウザ攻撃の一種です。

 うー、何のことでしょうか?という人に説明します。まず、初めにHTTPについて説明します。HTTPはステートレス・プロトコルと呼ばれています。ステートレスというのは、HTTPが非常に簡単な仕組みを利用しているので、ステートを覚えている必要がないという意味です。 元々HTTPはハイパーテキストにおいて単にファイルを転送するために開発されたもので、同じURLへのアクセスならその状況によらず同じ資源を提供しようとするものです。クライアントが以前にどんな通信を行っていたのかは全く配慮していません。

 クライアントがWebサーバにリクエストをし、Webサーバがこれに応えると、これでセションが終了してしまいます。でも、これではビジネスに使えません。Aというクライアントから、BというサイトにCという本の注文が入りました。しかし、誰からの注文だったかは分かりません。再度AからDという本の注文があっても、先ほどCという本を注文した人と同一人物かもわかりません。

 これではビジネスでは使えません。そこで、開発されたのがCookieです。Cookieを使うと、HTTPにおけるWebブラウザ(HTTPクライアント)とWebサーバ(HTTPサーバ)との間の状態(ステート)を管理することができます。Cookieはユーザの識別や、セションの管理などの目的で利用されます。

 Cookieはサーバで作られ、レスポンスの際にクライアント(ブラウザ)に送られてきます。ブラウザはこのCookieを保存し、再度このサーバにアクセスする際に、リクエストに付加して送信します。

 ブラウザは、Cookieを保存する際に、domainという属性を付加することができます。domain属性を指定すると、Cookieが送信されるサイト(あるいはdocument.cookieでCookieが読み取れるドメイン)を制御することができます。

Set-Cookie: name=value; domain=example.com

domain属性が指定されていると、そのCookieはdomain属性で指定されたドメイン自体、あるいはそのサブドメインに対して送信されます。一方、domain属性がセットされていない場合は、そのCookieを送信したホスト(サーバ)にのみ送り返されます。



 クロスサイト・クッキングはどんな場面で使われるのでしょうか?例えば、攻撃者があるサイトにクッキーを利用した攻撃に対する脆弱性があると気づいたとしましょう。この場合、攻撃者はCookieを使った攻撃を自分で実行することができればそうするでしょう。しかし、パスワードを知らないとそれができない場合には、そのパスワードを知っている通常の利用者をだましてクロスサイトクッキング攻撃を仕掛けるかも知れません。



6.3 クロスサイト・スクリプティング

 クロスサイトスクリプティングは、インジェクション攻撃の性質を持っていますので、こちらで説明しました。



7 セッションハイジャッキング関連

7.1 セッション・フィクセーション

7.1.1 Cookieの強制に注意

 セッションフィクセーションは、セションのIDをフィクセート(fixate、くっつける)することです。セションフィクセーションはセションのIDを奪うのではなく、自分のセションIDを他人に使わせて、後から他人の情報が付着したセションIDを使ってその他人になりすます行為です。攻撃者にとっては、元々自分のIDですので自由にその他人になりすますことができます。

 セションフィクセーションでは、攻撃者が予めWebサイト(exampleA.co.jp)からセションID(Cookie)を取得しておき、そのCookieを強制的に他のユーザに使わせます。他のユーザにCookieをくっつける方法としては、攻撃者が自分のWebサイト(exampleB.co.jp)を開設し、何とかしてユーザをそこにおびき寄せて、予め用意したWebサイトAのCookieをユーザのブラウザに強制的にセットしてしまいます。

 ユーザがWebサイトAにアクセスする際に、サイトAのCookieとユーザ情報が紐づけられ、攻撃者がユーザ情報と紐づけられたCookieを自由に利用できるようになってしまいます。

 ユーザは攻撃者のサイトexampleB.co.jpに行ったのに、どうしてexampleA.co.jpが発行したCookieを受け入れてしまうのでしょうか?これを拒否していれば問題は発生しないはずです。

 Cookieの仕組みを少し復習してみましょう。Webアプリケーションは、Set-Cookieコマンドを使って、NAME=value、EXPIRES=date、PATH=path、DOMAIN=ドメイン名、SECURE(HTTPSの場合にセット)などの属性をセットして、レスポンスと一緒に返します。
 ブラウザは、この値をURLと紐づけして保存し、次にアクセスするときに、保存しているCookieの中から、送信先のURLと紐づけられたCookieをリクエストに張り付けて、リクエストします。ただし、NAME以外の属性は必須ではありませんので指定されていないかもしれません。指定されていない場合は、アクセスしたURLに含まれるホスト名、パス名が使用されます。

 ブラウザはあるURLにアクセスしようとするとき、このURLと紐づけられたCookieがあるかどうか調べ、見つかったらそのCookieをセットしてアクセスします。ドメイン名が一致するかは後方一致というルールが適用されます。パスが一致するかどうかは前方一致のルールが適用されます。

 例えばdomain属性を".jp"とされて、ブラウザがこれを受け入れてしまうと、example0.jpもexample1.jpも一致してしまいます。しかし、これを受け入れてしまうと、管理の異なるサイト間でCookieが共有されてしまいますので、このよう指定はできないようになっています(と思います。※トップ・レベル・ドメインを指定したCookieは受け入れない)。では、セカンド・レベル・ドメインはどうでしょうか?これはブラウザの実装によって少し違っているようです。これを受け入れてしまうブラウザの場合、domain属性をco.jpのものをそのまま受け入れてしまうと、example1.co.jpもexample2.co.jpもマッチしてしまうことになります。

 ただし、path属性は前方一致ですので、先頭部分が一致しないとダメということになります。

 例で少し考えてみましょう。ブラウザが".co.jp"をdomain属性として受け入れてしまったという場合についてはどうでしょうか?パス名は前方一致ですので、abc.def.example.co.jpとabc.example.co.jpは一致します。abc.co.jpも一致してしまいます。

 co.jpについては、一般的なドメイン名ですので、ドメイン属性として拒否するブラウザが多いいのですが(IEは拒否、Firefoxは受け入れ)、地域型のJPドメイン名、都道府県型のJPドメイン名となると受け入れてしまうものがあります。例えばIEはco.jpは拒否するのですが、地域型、都道府県型のJPドメインは受け入れてしまいます。

 CookieのフォーマットにはSet-Cookieというフォーマットと、Set-Cookie2というフォーマットがあります。Set-Cookie2では、example3.co.jpのサーバはexample3.co.jpをdomain属性としてCookieを発行します。ブラウザは、Cookieのdomain属性が別のサイトで発行されたものである場合は受け入れを拒否することができます。このSet-Cookie2のアプローチを採用すれば、セカンドレベルドメインをドメイン属性として簡単に受け入れてしまうことに基づく攻撃は防ぐことができます。

※Set-Cookie2はIETFによってRFC2109、2965で標準化されていますが、Set-Cookie(Netscapeの定義)と互換性がないため事実上死文化しています。

 現在、Set-Cookie2をサポートしているのはOPERAだけですので、これを解決策とするわけにはいきません。しかも、問題はこれだけではありません。最初に示した、「攻撃者のサイトexampleB.co.jpに行ったのに、どうしてexampleA.co.jpが発行したCookieを受け入れてしまうのか」という問題については、まだ何も説明していません。

 domain属性、path属性から言えば「exampleB.co.jp」と「exampleA.co.jp」ではpath属性が違いますので、co.jpとかtokyo.jpなどのドメイン属性をたとえ受け入れてしまったとしても、path属性が違っていますので拒否されるはずです。しかし、HTTPヘッダインジェクションと、セションフィクセーションという2つの攻撃を組み合わせて仕掛けられると、これを受け入れてしまう可能性が高くなります。例えば次のように考えてみてください。攻撃者のexampleB.co.jpに行って、Locationヘッダに改行とSet-Cookieを埋め込まれてしまうことは考えられます。攻撃者は予め標的サイトのexampleA.co.jpでもらっておいたCookieの属性をそのまま記述します。userIDやdomain属性、path属性もexampleAのものです。これを標的サイトexampleAにリダイレクトする際に、ユーザのブラウザは攻撃者の情報の入ったCookieをexampleA.co.jpと関連付けて保存してしまうかもしれません。
 標的サイトにHTTPヘッダインジェクションの脆弱性がある場合だけでなく、XSS脆弱性のある場合にも同様のことが考えられます。



■ 対策
 現在のところ、セションIDを送り込まれてしまうということを完全に防ぐことは難しそうですので、「セションIDを送り込まれても、セションをハイジャックされない」方法を考えるべきです。
 セションフィクセーションでは、攻撃者によって送り込まれたCookieを使って、ユーザが標的サイトにログインし、Cookieとユーザ情報が紐づけられた段階で、攻撃者がユーザになりすますという攻撃方法が想定されています。これを回避する方法として、現在推奨されているのが、ログインが成功した時点で、サイト側で古いセションをIDを無効化し、セションIDを再発行するという方法です。



7.1.2 セッション変数にも注意が必要

 Webページ間でデータの受け渡しを行うのにはhiddenフィールドを使うという方法があります。Web間で受け渡す要素ですので、表示する必要がありません。hiddenといっても隠すということではなくその時点で表示と関係ないという意味です。

 hiddenフィールドを使うと簡単にWebページ間でデータの受け渡しを行うことができますが、危険性をはらんでいます。hiddenフィールドで指定したデータはブラウザには表示されませんが、他のデータと一緒にブラウザに送信されていて、ユーザによって容易に参照・改ざんされる可能性があるからです。

 Web間で受け渡しするデータはセション変数に保存すべきです。多くのWebアプリケーションの実行環境では、複数のWebページ間でやり取りできるきる記憶領域をセション毎に用意しています。セションが続く限りこの記憶領域にデータを保持することができます。この記憶領域を「セション変数」といいます。セション変数に設定されたデータはサーバ側に保持され、ブラウザ側に流出してしまうことがないため、hiddenフィールドに比較すると安全に、Webページ間でのデータの受け渡しが可能です。ただ、セション変数はセションID(Cookie)と紐づけられてサーバ上に保存されますので、Cookieと同様にセションフィクセーションに対する注意が必要です。

 セションフィクセーションに対する対策としては、セッション変数に変更があったらセションIDを変更したうえで、セション変数の値を移し替えることです。変更されたセションIDはユーザのブラウザにだけ通知され、攻撃者には未知の値となるため、攻撃者は情報を参照できなくなります。



7.2 TCPシーケンス番号予測攻撃

 TCPシーケンス番号予測攻撃はスプーフィング攻撃の性質を持っていますので、こちらで説明しました。



7.3 中間者攻撃

 中間者攻撃(Man-in-the-Middle攻撃、MITM攻撃)とは、二者間の通信の途中に不正な手段で割り込み、通信の盗聴や改竄を行う攻撃です。

 アリスとボブの間の通信にチャールズが割り込んだ場合について考えてみましょう。中間者攻撃では、アリスがボブと通信をしようとするときに、アリスが送信したパケットにボブの振りをして返信し、ボブに対してはアリスの振りをしてパケットを送信します。このようにして、アリスとボブが通信をしている間、アリスに対しては、ボブと通信をしていると思わせ、ボブに対してはアリスと通信をしているように思わせることができれば、アリスとボブの間の通信を全て盗み見ることもできますし、アリスとボブの間の通信を改ざんすることも可能です。

 もっとも一般的な中間者攻撃ではWiFiルータが使われます。攻撃者は、タブレットパソコンやノートパソコンでWiFiルータを作って、空港や喫茶店などに置き、一般のユーザに使わせます。名前は、公共エリアでよく使われる名前にします。ユーザがこのルータを使って外部と通信をすれば、攻撃者はログイン情報などを奪取することができます。正規のルータでも暗号化実装の弱点が見つかっていれば通信を盗み見られる可能性があります。



7.3.1 暗号化通信でも危ないことも

 中間者攻撃に対しては暗号化通信が安全とされていますが、暗号化で全て解決するわけでもありません。公開鍵暗号方式に対して、中間者攻撃が成功する場合について考えてみましょう。アリスとボブが公開鍵暗号方式を使って暗号化通信をしようとするときに、チャールズが割って入って、ボブにうその情報を伝えるという場合についてはどうでしょうか。

 初めに、アリスはボブの公開鍵が必要なのですが、もし持っていない場合は、何らかの方法で公開鍵を入手しなくてはなりません。アリスがボブから公開鍵を送ってもらうということが考えられます。この場合は、チャールズがこれを妨害して(奪取し)、自分の公開鍵をボブの公開鍵として送ってしまうということでもいいでしょう。アリスはチャールズの公開鍵を、ボブの公開鍵と思い込みます。アリスはこの公開鍵でボブ宛てのメッセージを暗号化して、ボブに送ります。チャールズはこれを横取りして、解読します。アリスが使った公開鍵はチャールズのものですから、チャールズは自分の持っている秘密鍵で内容を盗み見ることができます。そして、内容を嘘のものに書き換えて、ボブの公開鍵で暗号化してボブに送ります。ボブはメッセージを受け取り、自分の秘密鍵で解読して、メッセージを平文に戻します。

 暗号化通信なのに案外簡単に解読されてしまいました。何がいけなかったのでしょうか。公開鍵が確かにボブの公開鍵であるという保証のところが少し弱かったと言えます。ここで、しっかりした公開鍵の基盤が必要ということになります。公開鍵は公開鍵サーバのようなところに預けて、必要ならここから入手できるようにするべきです。ただし、公開鍵を預かるときに、これば確かにボブの公開鍵であるという点をもっとしっかり検証しなくてはなりません。チャールズの公開鍵を、ボブの公開鍵と騙されて登録してしまうことのないようにしっかりとした仕組みが求められます。



7.3.2 ワンタイムパスワードでも危ないことも

 MITM攻撃はユーザがワンタイムパスワード(OTP)を使っているときでも成功してしまう可能性があります。MITM攻撃では、攻撃者がワンタイムパスワードを奪い、そのワンタイムパスワードの期限が切れる前に署名し、顧客の認証情報を銀行等のポータルに送信することができてしまうためです。

 具体的には次のようになります。ユーザは多分フィッシングメールを受けます。リンクをクリックするとMITMに誘導されてしまいます。このサイトは、本物そっくりなので、ここでワンタイムパスワードなどの認証情報を入力します。ここまでは、フィッシング攻撃と全く同じです。通常のフィッシングでしたら、ワンタイムパスワードを奪われても心配ありません。ワンタイムパスワードは再利用できないからです。しかし、MITM攻撃では、ワンタイムパスワードの使用時間が切れる前に、銀行サイトに即座に接続し、盗んだ認証情報を使って本物のユーザに成りすまします。こうなると、銀行サイトは、認証情報を確認して、MITMに口座へのアクセスを許可してしまいます。

 ユーザを安全に認証するための新たな技術が求められています。例えば、PCとは別経路で認証する方法などです。具体的には、スマトフォンの専用アプリに取引内容を送付して、改ざんがないかユーザに確認を求める方法などが考えられます。



7.3.3 中間者攻撃の対策

■中間者攻撃の対策
1)オープンなWiFiルータはなるべく使わない。閲覧のみで、ログインはしない!!!
2)平文による通信はなるべく避ける
3)公的な認証局の発行した電子証明書であることを確認する
4)正規の通信先であるか電子証明書から確認する
5)アプリケーションの脆弱性を解消する



7.3.4 トロイを使った中間者攻撃:MITB

 MITMと同じことをブラウザに潜ませたマルウェアにさせるのがMITB(Man in the Browser)です。MITBは、MITMと同様に動作するプロキシ型のマルウェア(トロイの木馬)をブラウザに感染させ、ブラウザと外部サーバの間の通信を傍受し、場合によっては改竄を行います。

 MITBで怖いのは、ユーザがOTP(ワンタイムパスワード)やスマートカード、あるいはPKIなどを使って、金融機関がユーザを認証するまで、介入しないことです。認証が済んで本物のセッションが生成されると、このセッション上で、トランザクションを改ざんします。セッションが本物で、改ざんがリアルタイムなのでユーザは不正に気付くことができません。例えば、アリスがA銀行のサイトで、ボブに1000ドル送金するようにリクエストしたとします。このとき、MITBがイーブに2万ドル送金するように改竄してリクエストしてしまうという具合です。銀行がイーブへの2万ドルの送金の確認を求めると、MITBは元のリクエストに基づく確認ページに改竄して、アリスに提示します。アリスが処理の詳細をレビューして確認すると、銀行は2万ドルをイーブに送金してしまいます。



8 不適切な入力確認


8.1 バッファーオーバーラン

 こちらで説明しました。

8.2 return-to-libc攻撃

 return-to-libcはバッファーオーバーランと同様にスタック領域のリターンアドレスを書き換えることで攻撃をする手法です。バッファーオーバーランの場合はスタック上に悪意のコードを格納して、メモリ溢れを起こさせた際に、関数戻り番地を悪意のコードを格納した番地に書き換えます。しかし、これは簡単なことではありません。return-to-liveはこれをもっとシステマチックにしました。return-to-lbcではメモリ溢れの際に戻り番地を、別のサブルーチンのアドレスに書き換えるとともに、引数も書き換えてしまいます。この方法では、悪意のコードをわざわざ埋め込む必要がありません。

 UNIX系にはlibc(C言語のライブラリー)という共有ライブラリがあります。これは、多くのプログラムによって共通して使われる部品のようなものです。libcは常にリンクされていて、攻撃に使いやすい様々な機能を備えています。例えばlibcのsystem()は引数さえ正しく指定すれば、任意のプログラムを実行することができます。別の場所を呼び出す場合でも総称してreturn-to-libcと呼ばれています。

 メモリバッファーオーバーフロー対策としては、スタック領域でコードを実行させないとか、そのように設計した関数に置き換えるなどの方法がありますが、return-to-libcはスタック上でコードを実行するわけではないので、これは効き目がありません。対策としては、スタック内容の破壊を検出したり、破壊されたセグメントを復旧する手法が有効とされています。また、実行プログラムの各モジュールのコードが配置される位置をランダムに変更することで、コードの位置を的確に指定できないようにするASLR(Address Space Layer Randomization)が有効であるとされています。



8.3 ディレクトリトラバーサル攻撃

 ディレクトリトラバーサル(Directory Traversal)とは、ディレクトリを横断するという意味です。従って、ディレクトリトラバーサル攻撃とは、ディレクトリを横断する攻撃のことです。Webサーバでは、ドキュメントルートというディレクトリの配下のファイルを公開しています。このWebアプリケーションのディレクトリ内から、ディレクトリトラバーサルの手法を使ってファイルをアクセスされると、本来外部からのアクセスを許す予定でないファイルがオープンされてしまう可能性があります。

 Webのアプリケーションプログラムで、ファイル名をパラメータとして受け入れるようになっている場合にどのようなことが起こるか考えてみましょう。

 カレントディレクトリ内のファイルをオープンすることを念頭に置いて、ディレクトリ修飾を付けることなくファイル名のみでファイルをオープンできるようにしている次のようなプログラムがあるとします(Perlスクリプト)。

open(HANDLE, "<$filename");

このプログラムは、フルパス名が与えられると、そのパス名が示すファイルをオープンしてしまいます。例えば、$filenameに「/etc/passuwd」等のパス名が与えられると、ファイルが表示されてしまいます。

※Webのドキュメントが保管されているディレクトリ以外は、本来公開予定ではありませんので、アクセス権限が正しく管理されているとは限りません。アクセス権限が正しく管理されていればWebアプリケーションに任意のディレクトリのファイル名を渡したとしても、OSがそのアクセスを拒否してくれるはずです。

 ディレクトリトラバーサル攻撃はこの攻撃を少し変形したものです。ディレクトリトラバーサルは上で説明したように、ディレクトリ構造を横断するようにファイルを読み込もうとする手法です。例えば、Webサーバなどは元々公開する目的のドキュメントを置いておく場所ですので、ディレクトリやファイルは誰でも閲覧できるように設定されています。このディレクトリとファイルは、Webサーバ(Apacheなど)の設定ファイル(例えば、httpd.conf)の中で、ドキュメントルートとして設定してあるディレクトリの配下に集められています。

 /var/www/がドキュメントルートとして設定されているとします。もちろん、他のデレクトリを指定しても構いません。設定は次の通りです。

dir = "/var/ww":
open(HANDLE、 "<$dir/$filename");

ここで、$filenameに「../../etc/passwd」と指定すると外部ディレクトリにあるパスワードファイルが漏えいしてしまうかも知れません。あるいは悪意のコードを書き込まれてしまう可能性もあります。

※ディレクトリ構造の中で「..」は1つ上のデレクトリ(親ディレクトリ)を、「/」はルートディレクトリを表しますが、ディレクトリ名あるいはファイル名が続くときは、前後をつなぐ役割をします。例えば、Webの公開ディレクトリの中にいて、「../abc/def」と指定すれば、1つ上の親ディレクトリに行って、そのディレクトリ内にある「abc」というディレクトリの中にある「def」というファイルを指定したことになります。現在/var/wwにいて、../../etc/passwdと指定した場合は、2つ上にディレクトリに上がりますので、ルート("/")ディレクトリまで行って、ルート直下の/etcデレクトリの中にある"passwd"という名前のファイルを探すことになります。

※OSコマンドインジェクションでは、OSコマンドを発行しますが、そのコマンドがカレントディレクトリで実行可能かは分かりません。もし、実行できない場合は、そのコマンドが存在するディレクトリ、あるいは(シンボリックリンクが張られているために)実行可能なディレクトリまで移動したうえで、コマンド実行をする必要があります。このような場合には、ディレクトリトラバーサルの手法が有効となります。



■対策
①外部からファイル名を直接指定できないようにする。
②ファイルを開くときは、固定のディレクトリを指定し、かつファイル名にディレクトリ名が入らないようにする。

■保険的な対策(上記対策を実施できない場合)
① 「../」(UNIX、Linuxなどの場合)、「..\」(Windowsの場合))を含むパス名を受理しないようにする。また、エンコード後に「/」「../」「..\」と等価となる文字列も適切に処理する。例えば「%2F」「..%2F」「..%5C」あるいは、二重エンコードした「%252F」「..%252F」「..%255C」など。

②Webサーバ内のファイルのアクセス権限を見直して、正しく管理する。



9 サイドチャネル攻撃

9.1 コールドブート攻撃

 コールドブートとはコンピュータの電源が完全に切れた状態から起動することです。

※コールドブートという言葉があるのですから、ウォームブートという言葉もあるに違いありません。では、ウォームブートとは何でしょうか。これは、OSが動いている状態で再起動命令をすることです。例えば、再起動(リブート)のボタンを押すとか、BIOSの設定画面から「Ctrl+Alt+Del」を押すとかです。この場合、OSは完全にシャットダウンしてからの再起動になりますが、ハードウェアは電源OFFにはなっていません。ウォームブートでは、通電状態のまま再起動しますので、ハードウェアのチェックプログラム(起動時のBIOSによるデバイスの初期化やチェック)を省略することができ、素早く起動することができます。

 コールドブート(cold boot)では、デバイスやOSの初期化やチェックを行うため、起動に時間がかかりますが、ハードウェアの構成を変更したり、デバイスの設定を変更した場合は、コールドスタートでないと変更が反映されないことがあります。

 前置きが長くなりましたが、「コールドブート攻撃」とは一体何でしょうか?コンピュータの電源を落としても、しばらくの間メモリにはデータが残っています。これを利用して、電源をオフした後に、メモリを取り外して、特殊な機器を使って「情報を盗んで」、これを悪用することで、攻撃を行う手法です。パスワード、あるいは「暗号の鍵(共通鍵や公開鍵暗号の秘密鍵)」を盗みます。パスワードを盗めば成りすましができますし、秘密鍵を盗めば、盗んだハードディスクに保存されている暗号化ファイルを復号することができます。

■対策
 盗むといってもその場でパソコンを開けて、メモリだけ盗んでいくというようなことは余りないでしょうから、とりあえずパソコンの盗難対策をすることが大切です。特に仕事が終わった後、机の上に放置されているノートパソコンが心配です。

●サーバルームは入退出管理をしっかりする。ラックには鍵をかける。
●個人の机の上のパソコンは盗難対策をする(例:ワイヤで机に固定、アラームの設置)。
●ノートパソコンは仕事が終わって退社する際に、机の引き出しにしまって、鍵をかける。
●メモリを取り外しにくい構成にする。
●ブート可能なデバイスを限定する(USBメモリで起動してメモリを読み取るなどの手法を防ぐ)。



          

10  パスワード破り

 パスワードを奪う方法は様々です。よく知られているのが総当たり攻撃、辞書攻撃、リプレイ攻撃、レインボー攻撃などです。これ以外には、トロイの木馬、スニッフィング、フィッシング、ファーミング、クロスサイトスクリプティング、ソーシャルエンジニアリングなどの方法があります。何らかの方法で奪ったパスワードを使って行うパスワードリスト攻撃なども有名です。



     

10.1 総当たり攻撃

 総当たり攻撃(Brute Force Attack)は、代表的なパスワード攻撃でパスワードの文字列の可能なすべての組み合わせについて検査する方法です。

 総当たり攻撃に強いパスワードにするためには、できるだけ組み合わせの数が多くなるようにしなくてはなりません。

■総当たり攻撃に対する強さ
1) 8桁の数字だけのパスワードは組み合わせの数が10^8(10の8乗)となります。これは1億通りの組み合わせということになります。今市販のパソコンでも1秒間に100億回程度の計算をしますので、0.01秒しかかからない?そんなわけにはいきません。総当たり攻撃では、「入力する」「正解かどうかチェックする」「不正解の場合は1ビット変更する」あるいは「1ビット増やす」の操作を繰り返す必要がありますので、そんなに簡単ではありません。IPAが2008に行った試算では約17日かかっています。

※IPAが試算で使ったのはIntel Core Duo T7200 2.00GHz、メモリ3GBのパソコンで、パスワード解析に使用したアルゴリズムは未公開です。また、ネットワーク経由のものかも不明です。

2) 数字とアルファベットの大文字・小文字で、10+26×2=62、更に通常のキーボードにあるASCII文字31種を加えると93通りになります。これを8桁使用すると93^8=5595818096650401となります。これもIPAの2008年の試算では約1千年となっています。



■総当たり攻撃対策
・パスワードを長くする(一定以上の長さのないパスワードは拒否)
・大文字、小文字、数字、記号の組み合わせを強制
・パスワードの試行回数の制限
・一定速度以上のパスワード試行の禁止
・一つのアクセス元からの連続試行回数の制限
・一定以上の間違いに対して管理者にメール連絡

 長いパスワードを要求すると、パスワード忘れが発生し、管理部門が大忙しになる可能性があります。また、一定以上の試行回数があったらそのアカウントを停止するという方法は確かに有効なのですが、正規のユーザがこれによってブロックされたという例もあります。



■逆総当たり攻撃
 総当たり攻撃の逆に、1つのパスワードに対して、IDを総当たりで順に試していくという攻撃方法もあります。これは「逆総当たり攻撃」(リバースブルートフォース)と呼ばれています。これは、「パスワード長が短くパスワードの使用できる文字種が少ない」システムには極めて有効です。パスワードが4桁で、IDが連続した10桁の数字というような場合、パスワードを一つ決めて、IDを1000000000から順に試していけばかなりの確率で成功することになります。しかも、この方法では、パスワードの試行回数を制限するという方法が有効ではありません。



■ボットネットからの攻撃
 ボットネットを利用して、支配下の複数のコンピュータに1台ずつ順に攻撃させるという方法もあります。この方法は、「パスワードの試行回数を制限する」「一定速度以上のパスワード試行の禁止」「一つのアクセス元からの連続試行回数の制限」などの方法が効果を持ちません。



10.2 辞書攻撃

 ユーザがパスワードに使いそうな言葉を集めたファイルを用意し、そのファイルにある言葉や単純な英数字の組み合わせを逐一試行することでパスワードを割り出す方法を辞書攻撃と言います。

■辞書攻撃対策
 人の名前(特に家族、友人、有名人)、ペットの名前、自動車のブランド名、映画名、辞書に載っているような単語、電話番号、生年月日、単純な文字の並び、あるいはそれを少し修正しただけの文字列をパスワードとしないことが重要です。



10.3 リプレイ攻撃

 リプレイ攻撃(反射攻撃)とは、ユーザのログイン時にネットワークを流れるデータをコピーし、それを再利用することでそのユーザに成りすます攻撃手法です。暗号を復号化する必要がありませんので、どんな強力な暗号システムでも太刀打ちできません。この攻撃を防ぐために開発されたのが「ワンタイムパスワードシステム」です。



10.4 レインボー攻撃

 レインボー攻撃は、ハッシュ値に変換されたパスワードを解析する攻撃手法です。ハッシュ値は一方向性関数の出力値ですので、ハッシュ値から元の入力値を導き出すことは極めて難しくなります。従って、パスワードをハッシュ値で管理すれば安全とされています。しかし、レインボー攻撃はこれを破ろうとするものです。

 レインボー攻撃は、予めパスワードとなりうる文字列を想定して、その文字列のハッシュ値を計算したリストを用意し、そのリストと攻撃対象のパスワードのハッシュ値を比較し、本来のパスワードを推測するという方法を使っています。事前に膨大な数のリストを用意する必要があります。



10.5 パスワードリスト攻撃

10.5.1 パスワードリスト攻撃とは

 パスワードリスト攻撃とは、悪意を持つ第三者が何らかの方法で予め入手し、リスト化したIDとパスワードを使って、Webサイトの攻撃を試み、結果として利用者のアカウントで不正にログインしてしまう攻撃です。

 利用者は複数のサイトに同じIDとパスワードでアカウント登録している場合が多いので、パスワードリスト攻撃は非常に効率の良い攻撃方法になっています。



10.5.2 パスワードリスト攻撃の対策

10.5.2.1 パスワード使いまわしを避けるための方法
 パスワードリスト攻撃の原因は利用者が複数のWebサービスに対して同じIDとパスワードを使いまわしていることです。

 IPAが2014年8月に発表した報告書によると、金銭に関連したサービスサイト(インターネットバンキングやネットショッピングなど)と同一のパスワードを使いまわしている人の割合が25.4%となっています。そして、パスワードを使いまわしている理由の64.1%が忘れてしまうからとなっています。

 パスワードリスト攻撃の対策は、複数のパスワードを適切に管理することです。最近のコンピュータの性能を考えるとパスワードは従来のアルファベット大文字小文字、数字と記号を使って8桁では安心できません。これから先のことを考えると12桁位を目安としたいところです。12桁のパスワードを複数、多分インターネットサービスをよく利用する人は10弱くらいは必要とすると思います。

 従来はリテラシーのテキストでは、パスワードはメモしない、全部暗記すべしと書かれていましたが、もはやこれは無理というものです。12桁のパスワードを10個近く暗記するというのは通常の能力の人にはできません。これからは、パスワードはメモするということにしましょう。ただ、このメモを紛失してパスワードが漏えいしてしまってはいけません。

 いくつか具体的な方法をあげてみます。

≪紙にメモする≫
 紙にメモする場合はアカウント毎に別の紙に書くと管理が大変で、紛失しやすいので、1枚の紙に書いてはどうでしょうか。名刺大の紙に書いてはどうでしょうか。小さな字で丁寧に書いてください。紛失・盗難にあっても漏えいしないようにしなくてはなりません。そのために、パスワードのコアになる部分を作ります。英語の歌の一節をとってきて、単語の最初の文字をつなぎ、自分なりの変形を加えて、コアの部分を作ります。このコアの部分は英語の一節ですので、簡単に記憶できると思います。コアの部分は完璧に暗記しなくてはならないので、8桁位で構いません。アルファベットの大文字小文字、数字、記号を入れてください。このコアの部分はメモには書き込みません。例えば*で代用します。ここから、Googleアカウントを作る場合は、*GG11とかしておきます。Yahoo!なら、*8whoのようにします。後ろの4桁は若干分かりやすすぎますが、例ですから、お許しください。皆さんは、もっと分かりにくいものを工夫してください。このリストはたとえ紛失・盗難にあっても情報漏えいしないと思います。このリストの紙にはユーザ自身の個人情報は一切入れないでください。自分の名刺の裏に書いておくなどは言語道断です。

≪電子ファイルに保存≫
 IDとパスワードのリストを表計算ソフトやテキスト編集ソフトなどに書いてパスワードを掛けて保存してください。テキスト編集ソフトの場合はファイルにパスワードを掛けることができませんので、zip等の圧縮ファイルにしてパスワードを設定してください。

≪パスワード管理ツール≫
 パスワード管理の専用ツールを導入するという手もあります。パスワード管理ツールを使う場合は、この管理ツールのマスターパスワードだけを覚えておけば大丈夫です。



10.5.2.2 不正ログインに気づく/防止する
 一部のインターネットサービスでは、不正なログインにユーザが気づくことができる機能が提供されていることがあります。各サービスの特徴を理解して、ご利用ください。

■ ログイン通知
 通常のIPアドレスとは異なるアドレスからログインがあった場合は、メール等で通知してくれるサービスです。

■ ログイン履歴
 ログイン履歴をとって必要な場合に教えてくれるサービスです。ログインした時刻、アクセス元のIPアドレス、URL等の履歴です。履歴を確認することで、不正なアクセスの有無を確認できます。

■ 認証コード
 IDパスワードに加えて予め登録しておいた認証コード(携帯電話の番号等)を使用してログインを行う二段階認証の仕組みです。認証コードは一定のものではなく、時間経過やログインの度に変化するので、窃取されても安全です。

■ ワンタイムパスワード
 コンピュータにアクセスする度に一度限りのパスワードを発行するシステムです。アクセスする度にパスワードが異なりますので、窃取されても安心してシステムを使うことができます。



11 その他の攻撃

11.1 Off-by-oneエラー

 off-by-oneとは「位置・順序などが一つずれて」いるという意味です。off-by-oneエラーは境界条件の判定に関して1つエラーしているという意味で使われます。例えば、プログラミングでループを1回余計回ってしまうとか、1回少なく実行されるなどのエラーを指します。

 プログラミングにおいて、このエラーがあると、メモリ領域を上書きすることが可能です。例えばリトルエンディアンのアーキテクチャの場合は、このバグによってフレームポインターの最下位のバイトを書き換えることができます。これを利用すると、攻撃者は呼び出し中のルーチンのローカル変数を書き換えることが可能です。

※リトルエンディアンはデータのバイトごとの配置順序のことです。リトルエンディアンはバイト単位で下位側から並べます。例えば「1234ABCD」という4バイトデータがあったら、バイト単位で小さい順に「CD」「AB」「34」「12」と並べますので、Off-by-oneのバグがあれば、最下位バイトを書き換えることができます。Intelのx86等はリトルエンディアンのアーキテクチャを採用しています。



11.2 ドライブバイダウンロード

 ドライブバイダウンロード(Drive-By Download)は、Webサイトを閲覧しただけで利用者のパソコンにウィルスを感染させてしまう攻撃手法です。ドライブバイダウンロードは、主に利用者のパソコンのOSやアプリケーションなどの脆弱性が悪用されています。

■Webサイトの管理者向けの対策
 出来れば、セキュリティ専門会社のサービスを利用する。できない場合は、複数のパソコンにそれぞれ異なる会社のウィルスセキュリティソフトを導入して、それぞれのパソコンからWebサイトを定期的にチェックする。


■パソコン利用者向けの対策
 OSやアプリケーションを最新バージョンにしておくこと。ウィルスに感染してしまった場合は、最悪の場合、パソコンを購入時の状態(初期状態)に戻す必要もあるので、こまめにバックアップをとっておくこと。








更新履歴

2017/10/21    「10 パスワード破り」を追加
2017/9/24     「11.2 ドライブバイダウンロード」を追加
2017/9/24     「8.3 ディレクトリトラバーサル攻撃」を追加
2017/9/24     「9.1 コールドブート攻撃」を追加
2017/9/24     「11.1 Off-by-oneエラー」「8.2 return-to-libc攻撃」を追加
2017/9/23     「4.10 DNSリバインディング」「10.2 リプレイ攻撃」を追加
2017/9/22     「7.3 中間者攻撃」を追加
2017/9/21     「6.2 クロスサイトクッキング」を追加
2017/9/20     「5.6 DLLインジェクション」を追加
2017/9/19     「4.7 クリックジャッキング」「4.9 ファーミング」を追加
2017/9/18     「5.7 フォーマット文字列攻撃」を追加
2017/9/17     「5.5 OSコマンドインジェクション」に危ないコマンドの例を追加
2016/8/1      新規作成


       




































































































ページの先頭