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

9.サーバセキュリティ > 9.7 セキュアプログラミング

バッファとは
メインメモリ内の、一時的な記憶領域である。
バッファという英語は、本来は緩衝材という意味である。なので、ハードディスクとメモリなどの、速度の違いを吸収するバッファ(緩衝材)という意味がもともとだ。だが、ここでのバッファは、一時的な記憶領域という意味で使われる。バッファ領域には、メモリ上のヒープ領域とスタック領域がある。
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上での不正実行ですよね。
そうであれば、大した問題にならないのでは?
それは違う。
その脆弱性を突いて、任意のプログラムを実行させるのである。
具体的には、プログラムの戻りアドレスまで上書きさせて、違う場所に戻らせる。そこに、任意のプログラムを実行させる命令を書いておけば、何でもできてしまう。つまり、コンピュータが乗っ取られたのと同然の状態になる。

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

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

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

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つ分の領域を確保します。

セッション管理とは
4

セッションってそもそも何でしたっけ? 
TCPのコネクションとの違いも教えて下さい
TCPのコネクションは3wayハンドシェークが行われる一連の通信。一方のセッションという言葉は、あいまいな言葉である。かなり乱暴ではあるが、買い物サイトにログインした情報と考えてほしい。
 一つのセッションに複数のTCPコネクションが作成されることになるだろう。
2

なぜセッション管理が必要なんですか?
Webサイトでショッピングをする際に、ログインすることが多い。ログインした情報を持っておけば、買い物がスムーズに行える。たとえば、購入履歴のページでは、ログインIDをもとに表示できる。発送の段階ではログインIDをもとに住所を表示できる。
このように、Webページをまたがって一連の処理をするときに、セッション管理が求められる。
参考であるが、IPAの文献には以下の記載がある。
電子商取引サイトのようにWebサーバーにユーザがログインしてからログアウトするまで、ログイン情報を保持したままページを移管するには、このままでは問題がある。そこで、クライアントとサーバー間でその情報を保持し、アクセス制御を一つの集合体として管理する仕組みが必要となる。この仕組みをセッション管理と呼んでいる。
http://www.ipa.go.jp/security/awareness/administrator/secure-web/chap6/6_session-1.html

セッションIDの管理方法
大きく以下の3つがある。
クッキー(Cookie)
たとえば、Gmailにログインすると、クライアントのブラウザに、以下のようなCookieが作成される。
NAME GX
VALUE xxxx(長いので省略)
DOMAIN mail.google.com
PATH /mail
EXPIRES 2013/07/01 6:05:36

URLリライティング
クエリストリングで、SID(セッションID)をURLに埋め込むのだ。
URLに sid=xxx などと直接書くのだ。
http://~xxx.com/aa.aspx?sid=xxx
当然ながら、セッションIDが見えているわけだから、セッションハイジャックなどの攻撃にあいやすくなる。
情報セキュリティスペシャリスト試験を目指す女性SE 

でも、他の管理方法だって、HTTPSで暗号化されていないのであれば、キャプチャすれば見えてしまうと思います。セキュリティレベルは同じでは?



URLに含まれているかどうかは、一つのポイントだと思う。
IPAのセキュアプログラミグ講座にも「URLリライティングの方式では、URLの一部にセッションIDが含まれているため、キャッシュ、ログ、Referer:ヘッダ等を通じて第三者にその値が漏えいするおそれがある」(https://www.ipa.go.jp/security/awareness/vendor/programmingv2/web.html)とあります。

hiddenフィールド
hidden(隠された)という言葉の通り、HTMLのソースの中に、表からは見えないように埋め込む。
formタグの場合、以下のように埋め込んで、次のページに渡すことができる。
<input type="hidden" name="sid" value="123">
とはいえ、ソースを開けば見えてしまうし、改ざんも可能。セキュリティ面で優れるとはいいにくい。
それに、プログラミングにて、常にhiddenのフィールドを書く必要があり、かなり手間だ。

今のところ、①のCookieによるsession管理が主流だ。
以下は、上記の3つを図にしてみた。
素材3_3_セッションの管理方法


IPAの「『セキュア・プログラミング講座 (Webアプリケーション編)』 ブートアップセミナー」(http://www.ipa.go.jp/files/000030878.pdf)では、セッションIDを運ぶ手段が、以下の図のように1枚で整理されています。3つの内容は同じです。
Cookie

分類の仕方は考え方によるところがあるので、これは一例と思ってください。
上記のIPAの文献では、考え方は同じだが、2つに分類している。
2) セッション管理
セッション管理を実現するには、一般には以下のような方法が利用される。
ア) Cookieを利用
Webサーバー側で発行されたセッションIDをクライアントのCookieに持たせることで、特定ユーザの識別を行う。
イ) hiddenフィールドを利用
入力フォームをWebサーバーに送信する際に利用するFORMタグのhiddenフィールドにセッションIDを持たせることで、セッション管理を実施する。Cookieを使用できない場合に、利用されることが多い。
③のhiddenフィールドも、GETメソッドを使えば②のようにURLに記載される。

IPAの「『セキュア・プログラミング講座 (Webアプリケーション編)』 ブートアップセミナー」(http://www.ipa.go.jp/files/000030878.pdf)では、ローカルプロキシツールの例として、OWASP ZAP、Fiddler、Burp Proxyが挙げられている。
最初に掲載されているOWASP ZAPが無償であることからも利用するにはいいと思う。
①OWASP ZAPダウンロード
https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project
から、Download ZAP
②JREのダウンロード
③OWASP ZAPを使った脆弱性診断
以下に解説があるが、スパイダー機能でURLを見つけ出し、そのURLに対してスキャンをする(攻撃>動的スキャン)
http://gihyo.jp/dev/column/newyear/2016/owasp?page=2
★詳細は別途記載予定

このページのトップヘ