情報処理安全確保支援士(情報セキュリティスペシャリスト)試験に合格するためのサイトです。
過去問を多数引用しながら、基礎知識をしっかり学んでもらうように作ってあります。
また、情報処理安全確保支援士(情報セキュリティスペシャリスト)を楽しく学べるように工夫したいと思います。
カテゴリ:

9.サーバセキュリティ

平成24年度春期試験から、情報セキュリティスペシャリスト試験において、試験問題に出題するプログラム言語は、C++、Java、ECMAScriptの3言語となった。
http://www.jitec.ipa.go.jp/1_00topic/topic_20111026_sc_yougo.html

ECMAScript(エクマスクリプト)は聞き慣れないが、JavaScriptと考えていけばいいだろう。

同一源泉ポリシー(same origin policy)に関しては、IPAの以下の資料に詳しい解説がある。
http://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/706.html

情報セキュリティスペシャリスト試験の過去問(H24SC秋午後1問1)の問題を見てみよう。
マッシュアップサービスの実現に関しては,まず,  Ajax (Asynchronous JavaScript十XML)という技術を用いることを検討した。
Ajaxを用いると, Webページ全体を再描画することなく,現在表示されているWebページの表示の一部だけを更新することができる。例えば,[ a ]を利用するHTMLファイル群をブラウザがダウンロードして実行すると,非同期的又は同期的にWebサーバにアクセスし,そのレスポンスデータを用いてWebページを更新することができる。
しかし,通常,ブラウザではセキュリティ確保のための[ b ]ポリシが採用されているので,[ a ]を利用するHTMLファイル群をダウンロードして実行する際,FQDN,プロトコル又はポート番号のいずれかが,ダウンロードしたものと異なるURIにはアクセスできず, A社が想定するターゲット型広告サービスを実現できない。

設問1 本文中の[ a ],[ b ]に入れる適切な字句を解答群の中から選び,記号で答えよ。
解答群
ア APT          イ ATM          ウ Same-Origin
エ XMLHttpRequest  オ アノニマス     カ プライバシ
Ajax(エイジャックス)については、以下の記事も参照いただきたい。http://nw.seeeko.com/archives/50654480.html

正解は、aがエのXMLHttpRequestで、bがウのSame-Originである。

Webサーバの簡単なたてかた。Windows7や8ではIISで立てられる。ASPによるプログラミングも簡単である。後日きちんと書きたい。 ツールとしては、IPAから以下が公開されている。最低限の手間と時間はかかるが、有効だと思う。 http://www.ipa.go.jp/security/vuln/appgoat/index.html

バッファとは
メインメモリ内の、一時的な記憶領域である。
バッファという英語は、本来は緩衝材という意味である。なので、ハードディスクとメモリなどの、速度の違いを吸収するバッファ(緩衝材)という意味がもともとだ。だが、ここでのバッファは、一時的な記憶領域という意味で使われる。バッファ領域には、メモリ上のヒープ領域とスタック領域がある。
buffer
★参考:データの構造
午前問題でやったかと思うが、キューとスタックがある。
キューはFIFO(First In First Out)、スタックはLIFO(Last in First Out)である。

buffer2
過去問
ここで、過去問(H19春SV午後1問1)を見てみよう。この問題では、C言語にてstrcpy関数を使ったプログラムが掲載されている。
T君 :はい。このプログラムでは,バッファオーバフローの結果,[ a:スタック]領域に確保された変数の値が,意図に反して書き換えられる可能性があります。私がこのプログラムを実行して確認したところ,変数val1がメモリ上に展開されたときの先頭アドレスは0xbffffa60で,同様に変数val2では0xbffff9e0,変数val3では0xbffff5e0でした。このとき,コマンドライン引数として一定バイト数以上の長さの文字列が与えられると,変数[ b:val2 ]がバッファオーバフローを起こして,変数[ c:val1 ]の値が書き換えられてしまいます。
決められた領域に記憶されるのであるが、文字数が大きいと、他の領域も書き換えてしまう。
b3
まつもとゆきひろさんの「コードの世界」

この本に、バッファオーバフローの解説があるので、引用させてもらう。
・「バッファ」という言葉の解説として、「データを保持するために確保する記憶領域」と述べられている。
・「バッファオーバーフロー」の解説として「固定長のバッファに対して入力していた場合、想定よりもはるかに大きなデータを入力することで、プログラムを異常終了させるものです
・「最悪の場合、プログラムの制御を奪われます」という理由として、「Cではローカル変数はシステム・スタック上に取られますから、システム・スタックをある特定のパターンで書きつぶすことで、関数からの戻り先アドレスを書き換えることが可能だからです
・解決策として「これらの関数には配列の長さを指定する「より良い代替関数」が存在しますから、そちらをお勧めします」として、strcpyではなくstrncpy、strcatではなくstrncatなどが紹介されている。
c2f058cb
「Cでは」という表現がありますが、
C言語(CやC++)以外では、起こらないのでようか?
そう考えてよい(と思います)。
まつもとさんの上記の本でも「そもそも、Cのように、配列の長さをチェックさえしない言語を使っていることが、トラブルの原因であるといえます」と述べられている。C#やRubyなどを使いましょうということだろう。

c2f058cb
よく分からないなりにも、なんとなく仕組みが分かってきました。
でも、手の込んだ攻撃ですね。本当に実現できるのでしょうか?

単純な例を考えよう。Wordに必要以上に大きなファイルや、中身がWordでは無いデータを開かせると不正終了するだろう。このようなイメージだ。
Webサーバのhttpdというプロセスに、不正なものを送り込めば、同じようにhttpdが不正終了してしまうから、サービスをダウンさせることができる。
sef2

なるほど。
不正終了させる手口はなんとなくイメージできました。
でも、情報流出させるなどの込み入った処理をさせるのは大変ですよね。
確かにそう。
「戻り先アドレス」の場所に、ピタリとあふれさせることは不可能ではないかと思ってしまう。
しかし、ほんとんどの場合は、攻撃ツールによるものだ。
ApacheやJavaやOfficeなどの脆弱性が見つかり、それを攻撃するバッファオーバフローのツールが出回ると、一気に被害が増える。
sef1 
でも、ApacheやJavaやOfficeの脆弱性があっても、ApacheやJava上やOffice上での不正実行ですよね。
そうであれば、大した問題にならないのでは?
それは違う。
その脆弱性を突いて、任意のプログラムを実行させるのである。
具体的には、プログラムの戻りアドレスまで上書きさせて、違う場所に戻らせる。そこに、任意のプログラムを実行させる命令を書いておけば、何でもできてしまう。つまり、コンピュータが乗っ取られたのと同然の状態になる。

過去問では、SQLインジェクションに関して、以下のように述べられている。
「Webアプリケーションに悪意ある入力データを与えてデータベースの問合せや操作を行う命令文を組み立てて、データを改ざんしたり不正に情報取得したりする攻撃」(H22AP秋 午前問43)より

SQLインジェクションは、SQL文を操作する文字列をWebフォームなどに注入(Injection)し、データベースに不正にアクセスする攻撃。
例えば、以下のようなフォームがある。
login画面_情報セキュリティスペシャリスト試験

サーバの認証プログラムとして、以下のSQL文が入っているとします。

 SELECT * FROM USER WHERE UserName = '(フォームのユーザ名が入る)'

ここで、フォームに a' or '1'='1 と入力すると
 SELECT * FROM USER WHERE UserName = 'a' or '1'='1'
となり、どんなユーザを入れても成立してしまう。または、コメントを意味する「--」を付ければ、それ以降が無視される。

コマンドを成功させるだけでなく、SQLのUNION句を使って別のSQL文をくっつければ、DBの中身を表示することも可能だ。

対策に関しては、IPAのサイトから以下が公開されています。
http://www.ipa.go.jp/security/vuln/documents/200811_JOGA.pdf
http://www.ipa.go.jp/security/vuln/vuln_contents/sql.html

バッファオーバフローに関する過去問(H28秋SC午後1問2)を見てみましょう。
脆弱性の中でも,バッフアオーバフロー脆弱性(以下,BOF脆弱性という)は,最近開発されたソフトウェアにおいても数多く報告されている。BOF脆弱性は,主に,スタックベースBOF脆弱性とヒープベースBOF脆弱性に分類される。ソフトウェアにBOF脆弱性がある場合,当該ソフトウェアへの入力によって,①開発者が想定しないメモリ領域に書きこまれ、開発者の意図しない命令が実行されることがある。

設問2(1)本文中の下線①について,スタックベースBOF脆弱性を悪用する攻撃の場合,関数呼出し時にスタックに必ず積まれるはずの,何の値を書き換えることによって攻撃が開始されるか。 20字以内で答えよ。

正解は、
「呼び出し元関数への戻りアドレス」です。

SQLインジェクションの対策は、IPAの以下の資料にまとめられています。
http://www.ipa.go.jp/files/000024396.pdf

その情報を参考にすると、主な対策は以下です。

1.根本的解決
(1)エスケープ処理
①バインド機構の利用
②プログラムでのエスケープ処理
 入力フォームによる入口でのチェックも有用
 
2.保険的対策
(1)エラーメッセージを非表示
 エラーメッセージは、攻撃者に情報を与えてしまう。
 また、ブラインドSQLインジェクション(Blind SQL injection)という手法があり、入力値と応答結果から、脆弱性を把握する。たとえば、ID/Passを入力したときに、「IDが存在しません」「パスワードが間違っています」と丁寧にエラーを返せば、攻撃者にもIDが違うのかPassが違うのかの情報を与えてしまう。
(2)データベースアカウント
権限の見直し。必要最小限の権限しか与えておかなければ、被害も少なくなる。

H21SC春午前Ⅱ問14
SQLインジェクション対策について、Webアプリケーションの実装における対策とWebアプリケーションの実装以外の対策の組合せとして、適切なものはどれか。

Webアプリケーションの実装における対策

Webアプリケーションの実装以外の対策
Webアプリケーションの中でシェルを起動しない。chroot環境でWebサーバを実行する。
セッションIDを複雑なものにする。SSLによって、通信内容を秘匿する。
バインド機構を利用する。データベースのアカウントのもつデータベースアクセス権限を必要最小限にする。
パス名やファイル名をパラメタとして受け取らないようにする。重要なファイルを公開領域に置かない。
 
今回の内容はとても難しい内容ですが、SQLインジェクションというキーワードから、「データベース」に関する対策を選ぶと、ウのみになります。

これを使えば、エスケープ処理は不要だ。
http://www.ipa.go.jp/files/000024396.pdf

静的プレースホルダは情報処理技術者試験で問われるキーワードです。バインド機構や、プリペアドステートメントという言葉を使う場合もあります。Prepared Statementなので「用意された構文」です。用意された構文が変化することなく、入力された文字は文字列として理解されるので不正な文字を入れるという攻撃を防げます。

過去問(H18秋SU午後Ⅱ問1)では、「バインド機構を利用する」ことの解説として、「プレースホルダと呼ばれる一時的な特殊文字を使用してSQL文のひな形を用意しておき,後で実際の値(変数)を割り当ててSQL文を完成させる方法です。変数は自動的にエスケープ処理されるので,DBMSの種類によって異なるエスケープ処理を意識する必要がなくなります」とあります。

具体例をみましょう。以下は、上記サイトの引用であるが、入力されたデータは「?」で表わされます。そして、入力されたデータが文字として直接実行されるのだ。
$sth = $dbh->prepare(
"SELECT id, name, tel, address, mail FROM usr WHERE uid=? AND passwd=?");
$sth->execute($uid, $passwd);
1

わかったような…
これまでは、上記のuidのところに、以下のように入力されると、構文が変わってしまう。
1' or 'a'='a' --
 しかし、?で処理し、値だけを判断するので、 「1' or 'a'='a' --」という文字列で処理される。


C言語でのメモリ空間とアドレスに関して、実際に試しながら解説します。
以下のプログラムを書いてみましょう。
#include <stdio.h>
 
int main(){
    int a,b;    //整数a,bを定義   
    a = 10,b = 20;   //aに10,bに20を代入
    printf("aのアドレス:%p\n",&a);   // &を付けることで、aのアドレスを表示する。
    printf("bのアドレス:%p\n",&b);   //pはアドレス(ポインタ)を表示する場合に指定する。
 return 0;
}
非常に簡単なプログラムで、整数a、bを定義し、それぞれ10と20という値を入れます。
この値は、パソコンのメモリ空間上に保存されます。
このとき、これらのaやbの値が、どこに保存したかを管理しておく必要があります。そこで、メモリにはアドレス(住所)があります。
では、これらaやbの値が、メモリ空間上のどこに保存されているかを表示するのが上記のプログラムです。
では、このプログラムを実行してみましょう。

C:\C>gcc -o pointer main.c

C:\C>pointer.exe
aのアドレス:0028FF2C
bのアドレス:0028FF28
1行目でコンパイルし、作成されたpointer.exeを実行すると、aのアドレスが「0028FF2C」でbのアドレスが「0028FF28」であることが分かります。
メモリ空間上では、以下のようになっています。
a
このように、int型ではメモリ上の4つ分の領域を確保します。

このページのトップヘ