戦国IT - 情報処理技術者試験の過去問対策サイト
お知らせお問い合わせ料金プラン

情報処理安全確保支援士 2018年 秋期 午後101


ソフトウェア開発に関する次の記述を読んで、設問1~3に答えよ。

 U社は、IoT機器の開発を行う、従業員数400名の企業である。IoT機器のソフトウェアの開発にはC/C++言語を使っている。IoT機器に搭載するOSには、Linuxを利用してきたが、今後はLinux以外も利用する予定である。これまで製品に大きなトラブルはなかったが、2020年東京オリンピック・パラリンピックに向けてIoT機器に関するセキュリティリスクが高まると経営層が判断し、開発におけるセキュリテイ対策を強化することになった。そこで、開発部の部長と✕主任がセキュリティ対策技術を調査した。   〔メモリ破壊攻撃の概要〕  メモリ破壊脆弱性は、プログラム実行時に、メモリ上にある制ることによって、実行制御を奪うなどのメモリ破壊攻撃に悪用される。情報を書き換えメモリ破壊脆弱性の一種にバッファオーバフロー脆弱性がある。  例えば、図1に示すプログラムVunがあったとする。Vuinは、スタックバッファオーバフロー脆弱性の学習用に作成した、32ビット版Linuxで実行可能なプログラムである。図2はVuln内の関数fooが呼び出された後のメモリマップである。プログラム実行時に、変数bが指し示すデータが不正な場合、そのデータによって、aに書き換えられると、関数fooの終了時にshellコードへ処理が遷移する。しかし、①このような遷移があっても、データ実行防止機能(以下、DEPという)が機能していると、攻撃は成功しない。  攻撃者が、DEPを回避するため、図2中のshellコードへ処理を移させる代わりに、b中の実行可能なコードやc領域にマップされているVulnの断片コードを利用するケースがある。例えば、a攻撃の際、ab関数の先頭アドレスで書き換えて、攻撃者の意図したb関数を呼び出すd攻撃もある
情報処理安全確保支援士試験(平成2018 年度 午後1 問01 図01)
情報処理安全確保支援士試験(平成2018 年度 午後1 問01 図02)
〔メモリ破壊攻撃に対する対策技術〕  現在、メモリ破壊攻撃に対する対策技術(以下、M対策技術という)が普及している。X主任は、DEPを含めた代表的なM対策技術を調査し、表1にまとめた。
情報処理安全確保支援士試験(平成2018 年度 午後1 問01 表01)
〔M対策技術の動作概要〕  例えば、Vulnのコンパイル時にSSPが適用されていると、関数fooを呼び出す際、図2のベースポインタレジスタ保存値より下位にeが挿入される。もしも、eが上書きされた場合は、攻撃と判断し、Vulnの実行を停止する。  なお、Vulnの場合は簡単ではないが、攻撃者がeの値を正確に推測して上書きできてしまうと、aの書換えが可能となり、d攻撃を防げない。その対策としては、ライブラリ関数のアドレス推定を困難にさせるfが有効である。  しかし、fc領域にある実行可能なコードを用いる攻撃に対しては効果がない。そうした攻撃はPIEによって緩和される。さらに、Vulnの場合、Automatic Fortificationによって、ライブラリ関数gを安全な関数に置き換えることで、バッファオーバフローの原因を排除することができる。   〔脆弱性対策強化〕  L部長とX主任が表1の技術を確認したところ、表1の備考欄の指摘以外にも②Automatic Fortificationではバッファオーバフローの原因を排除できないケースがあると分かった。  L部長は次に、表1の技術を適用することによる影響を確認した。その結果、次のことが分かった。例えば、ソースコードに脆弱性があっても、SSPを適用してコンパイルしていると、メモリ破壊攻撃が成立しないが、そのソースコードを③別の開発環境でコンパイルすると問題となる場合があることが分かった。  これらについては、U社内でコーディングスタンダードを定め、それによって対処することにした。検討の結果、U社は表1の技術を全て採用することにした

設問1〔メモリ破壊攻撃の概要〕について(1)〜(3)に答えよ。

(1)本文中のadに入れる適切な字句を、解答群の中から選び、記号で答えよ。
解答群  ア:Return-to-libc  イ:ROP  ウ:テキスト  エ:ヒープ   オ:ベースポインタレジスタ保存値  カ:ライブラリ  キ:リターンアドレスX

模範解答

a:キ b:カ c:ウ d:ア

解説

解答の論理構成

  1. 【問題文】には「そのデータによって、aに書き換えられると、関数fooの終了時にshellコードへ処理が遷移する。」とあり、図2ではスタック上に「リターンアドレスX」が示されています。スタックバッファオーバフローで最終的に書き換えるターゲットはリターンアドレスであるため、a=「リターンアドレスX」すなわち記号「キ」と判断します。
  2. 次に「攻撃者が、DEPを回避するため…b中の実行可能なコードやc領域にマップされているVulnの断片コードを利用するケースがある。」との記述を参照します。
    • 図2にはスタックより下位に「ライブラリ」、さらに下位に「Vuln ⇒ テキスト領域」が描かれています。
    • 従って、b=「ライブラリ」→記号「カ」、c=「テキスト」→記号「ウ」と対応付けられます。
  3. 「例えば、a攻撃の際、ab関数の先頭アドレスで書き換えて、攻撃者の意図したb関数を呼び出すd攻撃もある」と続きます。ライブラリに存在する既存関数(典型的には“system”など)を呼び出す古典的手法は“Return-to-libc”攻撃です。したがって、d=「Return-to-libc」→記号「ア」と決まります。
  4. 以上を整理すると
    a=キ、b=カ、c=ウ、d=ア となり、模範解答と完全に一致します。

誤りやすいポイント

  • a「ベースポインタレジスタ保存値」を取り違える。スタック保護機構の説明にベースポインタが出てくるため混同しやすいですが、実際に乗っ取るターゲットはリターンアドレスです。
  • bを「ヒープ」と誤答するケース。図2に「ヒープ」も描かれているものの、文中で“実行可能なコード”と書かれているため、通常 NX/DEP の下でも実行可能属性が付いている「ライブラリ」が正しいと気付きたいところです。
  • dを「ROP」と選択するミス。ROP も DEP 回避技術ですが、文中の「b関数の先頭アドレスで書き換えて直接呼び出す」という説明は典型的 Return-to-libc の動作を指します。

FAQ

Q: リターンアドレスの改ざんとベースポインタの改ざんは何が違いますか?
A: リターンアドレスは ret 命令実行時に次に戻るアドレスを保持しており、ここを書き換えればプログラムの制御フローを奪えます。ベースポインタはスタックフレーム参照用で、改ざんしてもすぐにコード実行にはつながりません。
Q: “ライブラリ”ならば DEP で実行禁止にならないのですか?
A: 通常の NX/DEP はデータ領域の実行を禁止するだけで、共有ライブラリ (.so) のテキスト領域は実行可能です。そのため Return-to-libc では system() など既存のライブラリ関数を安全な場所として利用します。
Q: ROP と Return-to-libc はどう区別するべきでしょうか?
A: Return-to-libc はライブラリ内の1関数を呼び出す比較的単純な手法、ROP はライブラリや実行ファイル中の短い命令列(ガジェット)を連鎖させ任意処理を組み立てる進化版です。問題文の「先頭アドレスで書き換えて関数を呼び出す」という記述は前者を示しています。

関連キーワード: バッファオーバフロー、DEP, ASLR, リターンアドレス、Return-to-libc

設問1〔メモリ破壊攻撃の概要〕について(1)〜(3)に答えよ。

(2)本文中のに入れる適切なアドレス値を図2中から選び、ア〜オの記号で答えよ。

模範解答

あ:㋒

解説

解答の論理構成

  1. 問題文の前提
    • 「プログラム実行時に、変数bが指し示すデータが不正な場合、そのデータによって、aに書き換えられると、関数fooの終了時にshellコードへ処理が遷移する。」
    • ここで「a」はスタックに保存された「リターンアドレス」を指す。従って には「shellコードの先頭アドレス」を書き込む必要がある。
  2. 図2の読み取り
    • 図2にはスタック領域の上部に「(ここにshellコードが入っている。)」と示され、その近くに ㋑ と ㋒ のアドレスが並ぶ。
    • スタック上のコードに制御を移したいので、スタック領域内を示すアドレスを選ぶ必要がある。
  3. 各アドレスの意味
    • ㋐「ffffffff」:カーネル空間の終了番地でありユーザープロセスからは実行できない。
    • ㋔「08048350」:テキスト領域(実行ファイル本体)。DEP 回避を目的とする今回の攻撃では使わない。
    • ㋓「bfffdf000」:問題文において「char d[100]」が割り当てられている地点。ここに書き込むとシェルコードではなくバッファ領域に飛んでしまう。
    • ㋑「bfffff2bc」および ㋒「bfffff29d」:どちらもスタック上端付近だが、図2では ㋒ が「shellコード」が配置された行と一致している。
  4. 結論
    • 「shellコードへ処理が遷移する」条件を満たすアドレスは「bfffff29d」。
    • よって、選択肢は「㋒」。

誤りやすいポイント

  • ㋓「bfffdf000」を選んでしまう
    「char d[100]」の開始地点なので、飛んでもシェルコードではなくデータ領域を実行することになりクラッシュする可能性が高いです。
  • ㋔「08048350」を選んでしまう
    テキスト領域は DEP により実行可能ですが、問題文の設定は「スタックに置いた shell コード」に飛ばす攻撃なので前提が異なります。
  • スタックのアドレス成長方向を誤解する
    x86/Linux ではスタックは高位アドレスから低位アドレスへ伸長します。図の上部ほど高位アドレスである点に注意が必要です。

FAQ

Q: スタック上の任意コード実行は DEP で防げるのでは?
A: 問題文も「①このような遷移があっても、データ実行防止機能(以下、DEPという)が機能していると、攻撃は成功しない」と述べています。今回は DEP が有効でない前提、もしくは DEP を迂回する前提での議論です。
Q: ㋑ と ㋒ のどちらもスタック上なのに、なぜ ㋒ が正解?
A: 図2では「shellコード」が格納されている行と同じ位置に ㋒ が描かれているためです。㋑ は shell コード領域より上(アドレスがさらに高い)ので、正確には shell コードの外側になります。
Q: もし ASLR が有効なら ㋒ を書き込んでも意味がないのでは?
A: その通りです。ASLR が有効ならスタック開始位置が実行毎に変化し、固定アドレス ㋒ に書き換えても失敗します。問題文後半で「ASLR」が「ライブラリ関数のアドレス推定を困難にさせる」と説明されているのはこのためです。

関連キーワード: バッファオーバーフロー、スタック、リターンアドレス、シェルコード、ASLR

設問1〔メモリ破壊攻撃の概要〕について(1)〜(3)に答えよ。

(3)本文中の下線①について、攻撃が成功しない理由を35字以内で述べよ。

模範解答

shell:コードがDEPで実行禁止にされているスタック領域にあるから

解説

解答の論理構成

  1. 【問題文】では、攻撃手順として「aに書き換えられると、関数fooの終了時にshellコードへ処理が遷移する。」と説明しています。つまり攻撃者はスタック上に置いた shell コードを実行させたい意図です。
  2. ところが同じ段落の後半で「①このような遷移があっても、データ実行防止機能(以下、DEPという)が機能していると、攻撃は成功しない」と明記されています。
  3. DEP は “実行不可属性” を利用し、スタックやヒープなどデータ領域を「実行できない領域」に設定します。そのためリターンアドレスを書き換えてスタック上の shell コードへ飛んだとしても CPU が命令として実行せず例外を発生させます。
  4. よって結論は「スタック領域にある shell コードは DEP によって実行を拒否される」ことが攻撃失敗の理由となります。

誤りやすいポイント

  • DEP を「アドレスをランダムにする機能」と誤解し、ASLR の説明を書いてしまう。
  • 「スタックが書き換えられないから失敗する」と書いてしまい、DEP の“実行禁止”という本質を外す。
  • shell コードがヒープやライブラリにあれば成功すると混同し、スタックに限定した説明を落とす。

FAQ

Q: DEP が有効でもコードをヒープに置けば実行できますか?
A: ヒープもデータ領域なので DEP により実行不可属性が付与されます。したがって単純に場所を変えても実行できません。
Q: ASLR と DEP の違いは何ですか?
A: ASLR は「配置をランダム化」して予測困難にする防御、DEP は「データ領域を実行不可」にして実行そのものを阻止する防御です。機能目的と仕組みが異なります。
Q: DEP を回避する代表的な手口は?
A: 「d攻撃」のようにコードを自前で置かず、既存の実行可能領域(例:ライブラリ関数)を連結呼び出しする手法(ROP など)が典型です。

関連キーワード: DEP, 実行不可属性、スタック、バッファオーバフロー、メモリ破壊

設問2〔M対策技術の動作概要〕について、(1)、(2)に答えよ。

(1)本文中のefに入れる適切な字句を表1中の用語を用いて答えよ。

模範解答

e:canary f:ASLR

解説

解答の論理構成

  1. 【問題文】では
    “関数fooを呼び出す際、図2のベースポインタレジスタ保存値より下位にeが挿入される。もしも、eが上書きされた場合は、攻撃と判断し、Vulnの実行を停止する。”
    とあり、これはスタックバッファオーバフロー検知の典型手順です。
    表1の「SSP (Stack Smashing Protection)」の概要には
    “スタック領域で canary と呼ばれる値を利用してスタックバッファオーバフローの有無を確認する技術”
    と明記されています。したがって e には “canary” が入ります。
  2. 続いて
    “その対策としては、ライブラリ関数のアドレス推定を困難にさせるfが有効である。”
    と記述されています。攻撃者がコードリユース攻撃を行うためには関数やライブラリの絶対アドレスを知る必要があります。
    表1の「ASLR (Address Space Layout Randomization)」の概要は
    “プログラムの実行時に、データ領域、ヒープ領域、スタック領域及びライブラリを、ランダムにマップする OS の技術”
    であり、まさにアドレス推定を難しくします。したがって f には “ASLR” が入ります。
  3. よって解答は
    e:canary
    f:ASLR
    となります。

誤りやすいポイント

  • SSP と DEP を混同する
    DEP は「実行不可ページ」を設定して 実行 を防ぎますが、スタック領域に特別な値を置いて改ざん検知を行うのは SSP です。
  • “アドレス推定を困難にさせる”というキーワードから PIE を選んでしまう
    PIE は実行ファイルのテキスト領域までランダム化しますが、根本原理は OS の ASLR に依存します。問題文で “ライブラリ関数のアドレス” と限定しているので ASLR が正解です。
  • canary の位置を誤解する
    canary は「ベースポインタレジスタ保存値より下位」、つまりリターンアドレスよりも手前に配置されることを押さえましょう。

FAQ

Q: canary の値は固定ですか?
A: いいえ。多くの実装ではプロセス起動時にランダム値を生成して埋め込みます。これにより攻撃者が正確に上書きする難易度が上がります。
Q: ASLR は 32ビット OS だと効果が限定的とありますが、なぜですか?
A: 32ビットアドレス空間は最大でも 4GB しかなく、そのうちカーネル空間などを除くとユーザ空間はさらに狭まります。乱数で使えるビット数が少なく衝突しやすいため、推定が容易になるからです。
Q: SSP を適用済みでも別の開発環境でコンパイルすると危険というのは?
A: コンパイラやオプションによって SSP が無効化されたり、最適化で保護コードが省略されたりする場合があります。ビルド環境依存の対策に過信せず、ソースコード自体の安全性を確保することが重要です。

関連キーワード: canary, ASLR, SSP, バッファオーバフロー、スタック保護

設問2〔M対策技術の動作概要〕について、(1)、(2)に答えよ。

(2)本文中のgに入れる適切なライブラリ関数名を答えよ。

模範解答

g:strcpy

解説

解答の論理構成

  1. 本文には「Automatic Fortificationによって、ライブラリ関数gを安全な関数に置き換えることで、バッファオーバフローの原因を排除することができる。」とあります。
  2. Automatic Fortification が対象にするのは、境界チェックを行わずにバッファへ書き込むことで有名な C 標準ライブラリ関数です。
  3. 中でもバッファサイズを確認せずにコピーを行う代表例が「strcpy」。この関数が原因でスタックバッファオーバフローが発生し得ることは、試験でも頻出の定番知識です。
  4. よって、g に入るのは「strcpy」と判断できます。

誤りやすいポイント

  • 「gets」「strcat」など他の危険関数と混同する。Automatic Fortification が最優先で置換する代表格は「strcpy」であることを押さえましょう。
  • 「memcpy」はコピー長を明示的に渡すため、境界未チェックという点では「strcpy」ほど危険度が高くありません。
  • ASLR や SSP など他の対策技術と役割を混同し、Automatic Fortification の着目点(コンパイル時に脆弱な関数を差し替える)を見落とす。

FAQ

Q: Automatic Fortification はすべてのバッファオーバフローを防げますか?
A: いいえ。本文にもあるとおり「書き込み先のサイズが不明な場合は機能しない」ため、万能ではありません。
Q: 置換後はどのような安全関数に変わるのですか?
A: 具体的には _FORTIFY_SOURCE マクロが有効な場合、コンパイラが __builtin___strcpy_chk などサイズ検査付きの内部関数に置換します。
Q: 「strcpy」以外に代表的な置換対象はありますか?
A: 「strcat」「sprintf」「gets」など境界チェックを行わない文字列操作関数が対象になります。

関連キーワード: バッファオーバフロー、Automatic Fortification, strcpy, SSP, ASLR

設問3〔脆弱性対策強化〕について、(1)、(2)に答えよ。

(1)本文中の下線②について、図1のプログラムにおいて、排除できないケースに該当する処理を行番号で答えよ。また、排除できない理由を30字以内で述べよ。

模範解答

行番号:16行目 排除できない理由:ポインタを使って直接メモリ操作しているから

解説

解答の論理構成

  • 【問題文】には “②Automatic Fortificationではバッファオーバフローの原因を排除できないケース” とあります。
  • 表1で “Automatic Fortification” は「バッファオーバーフロー脆弱性の原因となりうる脆弱なライブラリ関数を、コンパイル時に境界チェックを行う安全な関数に置換する技術」と説明されています。
    → 置換対象はあくまで “ライブラリ関数” です。
  • 図1のプログラムでは
    “16: while ((s1[i++] = *errmsg++) != '\0');”
    と、自前の while ループで *errmsg の内容を s1 に 1 文字ずつ代入しています。
    → strcpy、strncpy などのライブラリ関数を使っておらず、ポインタ演算で直接メモリを書き換えています。
  • したがって Automatic Fortification が介入できず、バッファ境界チェックは行われません。
    → 排除できないケースに該当する行は “16行目” となり、理由は「ポインタを使って直接メモリ操作しているから」です。

誤りやすいポイント

  • strcpy(d, b)(7行目)もバッファオーバーフロー原因ですが、Automatic Fortification で置換可能なため “排除できないケース” には当たりません。
  • fprintf などの I/O 関数はバッファコピーを伴わないため、対象外です。
  • 「ポインタを使う=必ず危険」ではなく、境界確認の有無が判断基準になります。問題では“ライブラリ関数を介さない”点に着目しましょう。

FAQ

Q: 16行目はループなので「境界チェックしている」と考えてはいけませんか?
A: ループ条件は終了文字 '\0' の有無だけで、コピー先 s1[100] のサイズ確認をしていません。従って境界チェックとは言えません。
Q: Automatic Fortification は全ての strcpy を安全な関数へ置換しますか?
A: 書き込み先サイズがコンパイラに分からない場合など、置換できないことがあります(表1「備考」参照)。
Q: ポインタ操作を完全に防ぐにはどうすればよいですか?
A: コーディングスタンダードで手動コピー禁止、strncpy_s など境界付き関数の使用義務付け、静的解析ツール活用などが現実的です。

関連キーワード: Automatic Fortification, バッファオーバーフロー、ポインタ操作、メモリ破壊、手動コピー

設問3〔脆弱性対策強化〕について、(1)、(2)に答えよ。

(2)本文中の下線③について、どのような問題か。また、どのような開発環境の場合に問題となるか。それぞれ25字以内で述べよ。

模範解答

問題:メモリ破壊攻撃を防げないこと 開発環境:SSPを適用できないコンパイラを利用する開発環境

解説

解答の論理構成

  1. 問題文は「ソースコードに脆弱性があっても、SSPを適用してコンパイルしていると、メモリ破壊攻撃が成立しないが、そのソースコードを③別の開発環境でコンパイルすると問題となる場合がある」と述べています。
  2. ここでの“問題”とは、SSP が効かなくなることで「メモリ破壊攻撃が成立する」危険が再び顕在化する点です。
  3. では「別の開発環境」とは何か。SSP は「スタック領域で canary と呼ばれる値を利用してスタックバッファオーバフローの有無を確認する技術」であり、
    • コンパイラが SSP 対応オプションを持っている
    • そのオプションを有効にしてビルドする
      という前提が必要です。
  4. したがって「SSP を適用できないコンパイラ」や「SSP を無効にしてビルドする設定」の開発環境で再コンパイルすると canary が挿入されず、攻撃を抑止できません。
  5. 以上より、 • 問題:メモリ破壊攻撃を防げないこと
    • 開発環境:SSP を適用できないコンパイラを利用する開発環境
    となります。

誤りやすいポイント

  • 「別の開発環境」を OS の違いと誤読し、コンパイラ要件を見落とす。
  • 「メモリ破壊攻撃が成立しない」を“脆弱性が消える”と誤解し、対策不要と判断してしまう。
  • SSP を “実行時機能”と認識し、ビルド時に無効化されるリスクを考慮しない。

FAQ

Q: なぜ SSP が無効のままビルドされる可能性があるのでしょうか?
A: コンパイラが古い/組込み向け軽量版で SSPI オプションを持たない、あるいはビルドスクリプトで明示的にオフにしている場合があります。
Q: SSP 以外の M 対策技術を全部入れていれば安心ですか?
A: いいえ。SSP を欠いたままだとスタックバッファオーバーフロー検知が抜け落ち、他の技術だけでは防ぎ切れない攻撃経路が残ります。
Q: コーディングスタンダードでどのように担保できますか?
A: 「SSP オプションを必須とし、ビルドログで確認」「SSP 非対応コンパイラの利用禁止」をガイドライン化する方法が一般的です。

関連キーワード: SSP, スタックバッファオーバーフロー、メモリ破壊攻撃、コンパイラ、canary
戦国ITクイズ機能

\ せっかくなら /

情報処理安全確保支援士
クイズ形式で学習しませんか?

クイズ画面へ遷移する

すぐに利用可能!

©︎2026 情報処理技術者試験対策アプリ

このサイトについてプライバシーポリシー利用規約特商法表記開発者について