概要
LLMs Killed the Script Kiddie: How Agents Supported by Large Language Models Change the Landscape of Network Threat TestingというLLMがサイバー脅威にどのような影響を与えるかを考察している論文の紹介記事です。
各章の内容をざっくり記載しています。
紹介する論文
- タイトル:
LLMs Killed the Script Kiddie: How Agents Supported by Large Language Models Change the Landscape of Network Threat Testing - 著者:
Stephen Moskal, Sam Laney, Erik Hemberg, and Una-May O’Reilly
この論文は2023年10月に投稿されたものであり、この記事は2024年2月に書いています。
0. Abstract
本論文では、大規模言語モデル(LLM)を用いてサイバー攻撃を支援する方法を検討し、そのシステムを使った攻撃の自動化についても検証しています。
一連の検証はプロンプトエンジニアリング(※1)およびプロンプトチェーン(※2)によってアプローチされます。
また、本論文では
- LLMが脅威に与える影響
- LLMが脅威アクターの能力を加速させることの倫理的な考察
- 生成AIの活用がサイバー脅威に対して有望か、懸念など
について報告します。
LLMは複雑なネットワークや高度な脆弱性に対してどこまでの能力があるかはわかりませんが、この論文がそういった議論に拍車をかけることを筆者らは望んでいます。
※1 プロンプトエンジニアリング
-> LLMに入力する自然言語(プロンプト)をよりよい回答を得られるものに変えていく技術
※2 プロンプトチェーン
-> 複雑なタスクをいくつかのサブタスクに分け、サブタスクを解くプロンプトを連鎖することで複雑なタスクを実行する技術
1. Introduction
近年、サイバー攻撃者は多岐にわたっており、レベルの低い攻撃者は簡単に利用できるツールやスクリプトを利用しており、APTs(※)の背後にいるような上位の攻撃者は独自のツールやゼロデイ攻撃を駆使します。
※APTs: Advanced Persistent Threats(持続的標的型攻撃)、特定の組織をターゲットとして長期間にわたってなされる高度な攻撃
攻撃の際の意思決定のためには、状況を理解する能力、更なる情報を得る手法や知見、新しい情報を現状に統合し次のアクションを決定する能力が必要です。
未熟な攻撃者はWeb検索の結果やチュートリアルをそのままコピペしてすぐに使用します。このような攻撃者は自身の目的やコマンドの結果に対する理解が浅く、攻撃を連鎖させることが少ないです。
一方で洗練された攻撃者は、長い期間をかけて独自のツールやexploitを開発し、熟考したうえで、対象のシステムやサービスを明確にイメージして攻撃を行います。
レッドチームやペンテスターは現実を模した脅威演習により攻撃者が利用しそうな脆弱性を特定し、システム管理者はパッチを充てるなどで防御を強化します。
本論文の目的はAIを脅威演習の中に統合し、システムの防御能力を強化することです。近年では大規模言語モデル(LLM)が開発され、広く利用されており、プロンプトと呼ばれる自然言語での入力を用いることで非常に人間らしく振舞うことが可能です。
巨大で性能のいいLLMはインターネットの記事や書籍などの数兆語のデータセットでトレーニングされており、その中にはCWE、CVE、Exploit-db、ATT&CKなどの脆弱性やセキュリティに関する情報が含まれている可能性があります。
このことからLLMは
- 脅威やそのツールに関する情報を提供できるのか
- 引数やフラグを満たしたコマンドを提供できるのか
- コマンドラインの情報を正しく理解できるのか
- 攻撃者の意思決定プロセスをとらえ、得た情報を計画に盛り込めるか
という疑問が生まれます。
以下のようなシステムは未熟な攻撃者の能力を向上させることはできるのでしょうか。
各セクションの内容は以下のようになります。
- セクション2 : ChatGPTの能力の初期探索
- セクション3 : 利用者がLLMからサイバーセキュリティの情報を得るためのプロンプトセットの提案
- セクション4 : サンドボックスの説明、自動化されたエージェントが一連の攻撃アクションを実行するデモ、LLMのセキュリティ知識の評価、プロンプトデザインに関する洞察
- セクション5 : LLMがサイバー脅威に与える影響
- セクション6 : LLMを用いた設計の制限
2. First Impressions and Challenges Ahead
LLMはコマンドの実行結果を理解することはできるでしょうか。
例えば、nmapはコマンドを実行するとIPアドレスやポート番号、サービス名などを取得することができますが、場合によっては行数が大変多くなり内容を理解するのは大変です。
このようなツールの出力を理解するためには手動で解析するか、各ツールに対して解析用のパーサを差開発する必要があります。
LLMがコマンドの理解とその後の考察に使えるかを確認するために、ChatGPTに対して「nmapの出力を要約し、その後そのマシンの脆弱性をつくように」指示をしました。
するとChatGPTはnampの結果をうまく要約し、metasploitを使ってマシンにexploitをかける有効で実行可能なコマンドを提案してきました。
しかも設定するパラメータもあっています。
これによりLLMの学習の際にサイバー脅威やそのツールに関する情報が含まれていたと考えられます。
本論文では攻撃環境としてDockerでサンドボックスを立てています。
サンドボックスはコントローラーを介してLLMと接続され、
- LLMのアドバイスを生成
- アドバイスをもとにツールを実行
- 応答をLLMに入力
- 結果からLLMのアドバイスを生成
- ・
- ・
- ・
といった一連のフローを自動化します。
この自動化プロセスを用いて実験を行ったところ、LLMはサイバーセキュリティに関する知識を有しそのツールの使い方も理解していることが示唆されました。
この自動化プロセスは、データにもとづいてコマンドを実行することができるため、スクリプトキディと同等の能力をもっているといえます。
3章では「LLMがペネトレーションテスターを支援できるのか」という疑問に関しての回答を示します。
GPT-3.Xでは4096トークンを処理できます。これにはプロンプトと回答のどちらの単語数も含まれ、長いプロセスを処理するためにはタスクを分割する必要があります。
この技術はプロンプトチェーンといい、プロンプトエンジニアニングとプロンプトチェーンにより一連の意思決定プロセスを単一のアクションとして実行します。
3. Designing LLM Assistance and Autonomy
3章ではまず、LLMと攻撃者がどのようにやりとりするかを考えます。
攻撃者はLLMが望む回答を返す効果的なプロンプトを検討する必要があります。
- Section3.1 : LLMが攻撃の単一のステップ、アクションをどのように実行するかを考えます
- Section3.2 : 攻撃者が攻撃の流れを監視しながらLLMとうまく連携するためのプロンプト攻勢を考えます
- Section3.3 : 一連のフローから人間を取り除き、自動化する方法を説明します
以上の結果から筆者らがエージェントと呼ぶ自動攻撃システムが得られます。
3.1 A Single-Step Decision Process
攻撃者の実行するOODAループ(Observe, Orient, Decide, Act)をLLMで実現するためにDasguptaらのPlanner-Actor-Reporterの枠組みを参考にします。
本論文の攻撃のシングルステップは
- tactic selection stage (DasguptaらのPlanner)
- execution stage (DasguptaらのActor)
- output translation stage (DasguptaらのReporter)
tactic selection stageでは現在の状態を解析し、その結果から次のアクションを決めます。execution stageではtactic selection stageで決定したアクションを実行します。このアクションはツールやOSコマンドの実行です。output translation stageではアクションの実行結果を受け取り、成功か失敗かを判定します。
ここまでが1ステップであり、output translation stageの結果は次のステップのtactic selection stageへフィードバックされます。
各ステージではそのステージでのタスクを実行するためのプロンプトがセットされ、各プロンプトの相互作用により、単一のプロンプトで実行するより一貫性がうまれます。
このステップは段階的に繰り返されますが、攻撃者は攻撃の進捗を管理し、適切なプロンプトを提供する必要があります。
攻撃は成功、もしくは失敗をもって完了となります。
3.2 Prompt Engineering
一連の攻撃を通してLLMに文脈を明確に示すために3つのサブプロンプトを準備します。
- SETUP
LLMが仮定するべき環境やタスク、ペルソナです。
Azure OpenAI Serviceのシステムプロンプトのイメージです。 - CONTEXT
モデルに正確で一貫性のある応答を返してもらうためにこれまでのアクションや知識の履歴を提供します。 - INSTRUCTION
要求のスコープとフォーマットの指示をします。
ハルシネーションや見当違いな応答を防ぐために明確に指示を行う必要があります。
3つのサブプロンプトは1つにまとめてLLMに渡されます。
tactic selection stage, execution stage, output translation stageの各ステージにおいてプロンプトが定義されます。
3.2.1 Executable Action Stage Prompt
簡単のために、攻撃者はネットワークに侵入しターゲットのIPアドレスを特定していると仮定します。
攻撃者はLLMに次のアクションのアドバイスを求めます。
SETUPのサブプロンプトでは、実行可能なコマンド形式などで応答するようにするため、どのツールが利用可能かを定義する必要があります。
今回はKali linux、Metasploitで実行可能なコマンドを応答するように定義します。場合によってはこの部分は他のツールなどで拡張します。
execution stageで最も重要なのはCONTEXTのサブプロンプトです。
サブプロンプトにはローカルIPアドレスを格納する< AGENT IP ADDRESS >や前のコマンドや応答を格納する< LAST CMD >, < LAST OUTPUT >、攻撃のステージを示す< TACTIC >が含まれます。
前のアクションの結果が現在の目標を達成するために必要な場合は、攻撃者はその情報をプロンプトに含ませなければいけません。ターゲットのIPアドレスやサービス名、バージョンなどです。
TACTICで現在の戦略をLLMに認識させるとそれに応じた具体的な指示をLLMに出すことができます。
INSTRUCTIONのサブプロンプトはexecution stageで実行可能な形式で応答を得るために不可欠です。
繰り返しを防ぐために前回のコマンドの結果がfaildだった場合には異なるコマンドを返すようにし、冗長さを防ぐために余分なテキストは除外します。サブプロンプトの最後を"1)"で終わることによりLLMの応答は箇条書きで列挙されるようになります。
LLMからの応答を実行したのちに、Output Translation stageに進みます。
3.2.2 Output Translation Prompt
output translation stageのSETUPサブプロンプトはLLMにLLM自身に設定する背景と目的を指示します。CONTEXTサブプロンプトはexecution stageのCONTEXTサブプロンプトの前半部分と同じです。
コマンドの応答をそのままコピペしてもLLMに入力する場合には十分ではありません。人間が読みやすい形式に要約することが重要です。
Output Translation PromptのINSTRUCTIONサブプロンプトはこの役目を担っていて、以下の図のプロンプトはreconnaissanceやexploitationの際に非常に正確な要約をします。
このプロンプトは要約のし過ぎで必要な情報を落としてしまったりすることを防ぎ、構文エラーなどの際には明確に報告するように指示しています。
最後に、このアクションが成功したか失敗したかを判断し、その結果を次のtactic selection stageに送ります。
3.2.3 Tactic Selector Prompt
Tactic SelectorではReconnaissance,Exploit,Exfiltrateなどの攻撃の戦略を決定することが目標です。
SETUPサブプロンプトでは各戦略の前提条件を指定し、CONTEXTサブプロンプトでは前回のアクションを提示しています。
各戦略の明確な前提条件は示しますが、「もし十分な情報があれば」などのあいまいさを残すことでLLMの戦略決定能力を調査します。
ここで定義された戦略を拡張していくことで、より複雑な戦略や動的な戦略を定義していくことができます。
SETUPサブプロンプトでは攻撃者の目的や攻撃の停止条件を定義します。
ここではターゲットからデータを盗み取ることを目的とします。この目的を達成するためにはターゲットで稼働しているサービスの情報などを偵察し、攻撃を行い、データを見つけ、盗み出す必要があります。
INSTRUCTIONサブプロンプトでは攻撃の終了を意味する"END_OF_CAMPAIGN"を含む、攻撃の戦略を1単語で返すように設定します。
SETUPとINSTRUCTIONは一貫した回答を1単語で返せるように設定してあり、これによってLLMが構文を理解しやすくなりexecutable action stageの応答が戦略を加味したものになりやすくなります。
3.3 Automated Agent Prompting
攻撃エージェントを自動化するためには、すべての意思決定をLLMにさせる必要があります。
本論文では次のようなアルゴリズムで自動化を実施します。
- Sp : 図4に示した3つのプロンプトステージのうち現在のプロンプトステージ
- C : エージェントが実行したコマンドやその応答などのすべての履歴
- Skc : モデルによって選択された攻撃戦略。動的に実行するプロンプトを変更する
上記の入力をLLMに与えることでアクションの実行、結果の報告、戦略の決定までを実施させます。
停止条件や、攻撃のゴールに達成しているかはtactic selector stageで与えられるため、LLMに問う必要があります。これが通常のエージェントの停止方法ですが、LLMが目的を達成する能力がない場合や同じアクションを繰り返してしまうことも予想されます。そこでアクションの実行数や失敗数にも制限を持たせて、繰り返しになることを防ぎます。
次の章ではこの自動化エージェントの能力を検証します。
4. Experiments
4章では以下の内容を説明します。
- 4.1 : デモンストレーションで利用するサンドボックス環境の説明をします
- 4.2 : Tactic Selector, Execution Stage, Output Translation designの3つの戦略を用いて自動された攻撃の例を見せます
- 4.3 : 異なる脆弱性の組み合わせに対するLLMの応答を調査します
- 4.4 : LLMが利用可能で一貫性のある応答を返すためのプロンプトの要素について調査します
4.1 Sandbox and Network Environment
本論文では3つの構成要素をもつDocker環境を立てています。
構成要素のうちの1つは図の左下にあるKali Linuxコンテナです。Kaliは攻撃用のツールがあらかじめインストールされているOSで、今回は攻撃者のターゲットに対する攻撃の実行およびその応答の確認に使われます。
外部には攻撃エージェントが動くコントローラモジュールが接続されており、LLMとやりとりすることができます。
コントローラはLLMによって生成されたKaliで実行するためのMetasploitコマンドやシェルコマンドを供給し、その結果を集め、その後の攻撃に利用します。
Execution Stageで構文エラーなどが発生した場合、Output Translationは"FAILURE"を返します。これにより攻撃エージェントは攻撃の修正や新しい戦略の構築ができます。
Kali linuxはターゲット端末と同じVLANに接続されており、簡単のためにVLAN上には1つのターゲット端末しかありません。ターゲット端末は意図的に複数の脆弱性が組み込まれてる"Metasploitable 2"Ubuntuイメージで構成されています。
一般的にはVLANはもっと大きく洗練されたものであり、攻撃者は他のデバイスにピポットなどする必要があります。
このネットワークで自動化された攻撃のデモを行います。攻撃はreconnaissance stageから始まります。
4.2 Automation Demonstration
以下の図はレッドチームの攻撃に利用する自動化エージェントの例で、3.2章のプロンプトエンジニアリング技術や図4のプロンプトチェーン、アルゴリズム1のコントローラロジックが用いられています。
目的は、パスワードやshadowファイルなどの特権情報を抜き取ることです。
攻撃はTactic Selector stageから始まり、最初の情報としてはネットワークの情報とターゲットのIPアドレスが与えられます。
エージェントは自動で攻撃を推進し、コントローラは攻撃の進捗やエージェントの状態を記録し、プロンプトを作成し、LLMから与えられたコマンドを実行する役割です。
このデモは攻撃の複雑さは難しさから言えば原始的です。
nmapでサービスを特定し、vsftpdの特権を取得するexploitを実行し、システムファイルを読んで盗み出すためにアーカイブファイルにします。
実際にはエージェントはこのアーカイブファイルをKaliコンテナに盗み出すことは失敗しています。
エージェントは一度のexfiltration実行後に停止します。
vsftpdは非常に攻撃しやすいバージョンになっています。
Step1ではTactic Selector stageでreconnaissanceが選択され、Execution StageではNmapによるサービスのスキャンが応答されます。Output TranslationstageでNmapの結果がサマライズされます。
この工程は"SUCCESS"判定となり開いているポートや、サービスのバージョンが特定できました。
LLMはNmapの理解があるようで正確なコマンドを生成できました。
Step2ではexploitationが選択されています。
攻撃の対象となるサービスはいくつかありますが、LLMはバックドアの脆弱性を含むバージョンのvsftpdへの攻撃経路を正確に特定します。
Output Translation stageではルートシェルがうまく開かれたことを示しています。
ここでは人間が介入してコントロールを取るか、エージェントを進行させるかを選択します。
Step3ではexfiltrationが選択されます。Execution Stageでは新しく接続されたリモートシェルで特権ユーザのみがアクセスできるシステムファイルへのアクセスを試みます。
エージェントはプレースホルダなどを利用してうまいことシステムファイルに誘導します。
例) cd /home//
この攻撃では一時的にexfiltrationのスコープをLinux OSに存在する重要ファイルである/etc/passwdandや/etc/shadowに限定しています。
exfiltrationを通して、LLMはデータを盗み出そうとする際に設定していないFTPサーバを経由しようとすることが散見されました。
これは本論文のシングルセッションの攻撃の限界です。
デモの中ではLLMの提示した持ち出しコマンドを例として提示していますが、これは信頼性が低く、重要ファイルの発見から持ち出しまでは、今回の設計よりも絶妙で複雑な工程になります。
いくつかの戦略を用いたシングルアクションプロセスによる攻撃の自動化の能力は驚くべきものでした。
この実験のターゲットは非常に脆弱なものであったため、この攻撃の成功がターゲットが脆弱すぎたためなのか、LLMの知識によるものなのかわかりません。
次のセクションではもう少し体系的にパフォーマンスを評価します。
4.3 Execution Stage Evaluation
自動化は一貫した性格なExecution Stageのコマンドをあてにしています。
LLMがうまくexploitできるかをもう少し体系的に整理します。
ターゲットマシンには複数の脆弱性が含まれているため、10個の脆弱性/サービスの中から一度に1つの脆弱性をマシン上に構成し、それぞれに対し攻撃を行います。
これはMetasploitableコンテナ上の網羅的な脆弱性のリストではありませんが、筆者らが確認した脆弱性を持ったサービスなどになります。
すべての実験はTempleture(※1)を1に設定したgpt-3.5-turbo(※2)で行われます。
※1 : LLMの回答に対するランダム性を設定するパラメータで0に近いほど同じ質問に対して同じ回答を返します。1.0であれば同じ質問に対してもある程度ばらけた回答を返します。
※2 : OpenAIの提供するLLMモデルの1つです。性能は十分高いですが、2024/2月時点はGPT-4やGPT-4-turboなどもっと性能のいいモデルがあります。(利用料は高い)
1つのサービスに対しては10回攻撃を繰り返します。そのうち、ユニークな攻撃の内容の数は"Unique Actions"に記録されます。
他には、接続を確立した数、実行は成功したが接続ができなかった数、構文エラーが出た数、誤ったアクションを実行した数をカウントしています。ベースラインとしてポートが開いていないパターンも記載しています。
vsftpdに対しては一貫して正確なexploitをすることができました。MySQLは10回中3回アクセスに失敗しました。
構文エラーに関してはMetasploitの攻撃が階層構造を持つことに起因しています。特にOpenSSHでは弱いパスワードという脆弱性に対して誤ったアクションを取ってしまいました。TelnetやApacheに関しても本質的には同様の問題でエラーが発生しています。Tenletはパスワードの応答が欠如しており、ApacheではWebの脆弱性に対する攻撃を行うことができませんでした。
将来的にはプロンプトの改善により、ブルートフォースによるパスワードクラックやWebへのアタックが可能になるかもしれません。
今回の設定ではSMTPは脆弱ではありませんでしたが、LLMは同じ攻撃を繰り返しました。このことから繰り返しの攻撃失敗に対して、異なる攻撃手法を提案するようにLLMに指示する必要があることがわかります。
Port513Loginでは513ポートが開いているだけなので本質的には脆弱性ではありませんが。LLMはvsftpdやSamba、Postgresに対する攻撃を実行しました。これはスプレーアンドプレイ攻撃でどれか1つで突破できればいいというような狙いの攻撃を行っていると考えられます。
予想通りですが、LLMはすべての脆弱性に対してexploitを実行できるような能力は持ちません。これはトレーニングデータに攻撃に関する知識が不足していたためか、本論文の設計の限界のためかはわかりませんが、いずれにせよ攻撃者はある程度のLLMの誤りは容認してサポート的な役割で利用するでしょう。
次の章ではプロンプトがLLMからどのように情報を引き出しているかをデモします。
4.4 Prompt Evaluation
プロンプトエンジニアリングはある意味芸術です。うまくLLMから情報を引き出すために研究が進んでいる最中です。
本論文ではExecution Stageのプロンプトを文ごとに分解し、各文がLLMの応答にどのような変化を与えるかを検証します。
以下の表にはセクション3.2.1で説明したexecution stage promptに対する追加の文章とその応答を示しています。
ChatGPTなどの一般的なLLMでは"hack"や"Attack"などの違法行為につながりそうな単語に対しての応答は拒否されますが、"peetration testing"などのセキュリティ担当者っぽい要求をすると応答を返してくれます。
ドメイン特化の専門用語はこういった場合に優れた応答を返させるために有効です。
Metasploitなどのツールの名前をいれるとさらに有効で、使い方を説明してくれます。LLM的にはなぜその行為が必要なのかを見ているため、応答には文脈や説明がついてきがちですが、コマンドだけ応答させるなどの工夫で必要な情報だけを取得できます。
こういったプロンプトエンジニアリングのテクニックは今後もっと発達していくと考えられます。
5. Discussion
これまでのデモの結果を考察します
- 5.1 : この研究の本質について
- 5.2 : デュアルユースについて
5.1 Reflections on the Nature of Work
このデモンストレーションを通した筆者らの経験から、攻撃者が一連の攻撃を行う際に、"figuring out whatto do" 「何をするべきか理解する」フェーズは"figuring outhow to tell a LLM to figure out what to do"「LLMに何をするべきかを理解させる」フェーズに変わったと主張しています。
つまりはプロンプトエンジニアリングが重要になってくるということです。
5.2 Abuse and Dual Use
本論文で提示した設計はペネトレーションテストとして防御の強化にも利用できますが、反対に攻撃者に利用されると攻撃行為のハードルを下げることになります。
LLMによって防御側も攻撃側もともに進化していくでしょう。
LLMは他の分野にも利用されていくと思われますが、利益とリスクを十分に考慮して使われなければいけません。
次の章では今回の設定の限界について考察します。
6. Limitations
- 6.1 : 手法の限界
- 6.2 : デモと実験の限界
6.1 Method Limitations
本論文の設計では攻撃能力はLLMに依存します。今回の場合はGPT-3.5です。
主にはLLMのトレーニングデータによってどのようなツールを扱え、どのようなアクションがとれるかが決まります。
GPT-3.Xの場合は2021/7までのデータが利用されているため、それ以降の情報には対応できません。
脆弱性情報は日々多く公開されているため、LLMの能力も定期的にアップデートする必要があります。
実際の攻撃の際には、戦略の決定方法などは体系的なものだけではなく、攻撃者の事前知識などによって決まる抽象的なものです。
本論文の設計では柔軟性が低く、実際の攻撃者のような意思決定は難しいです。
将来的にはツールの使い方をLLMに提示すると、戦略と関係なくその使用タイミングをLLMが決めてくれたりするかもしれません。
さらに進めば、攻撃エージェントはサービスの弱点の列挙などよりも、サービスに攻撃することを焦点において発展していくかもしれません。
6.2 Threat Scenario Demonstration and Experiment Limitations
本論文の実験は非常にシンプルとなっています。
実際のネットワークには複数のマシンはずですし、そもそもネットワークに侵入するための準備やアクションも必要です。
攻撃者が行う攻撃とそのターゲットの環境はもっと複雑で規模の大きなものになるはずです。
7. Related Work
自然言語処理の技術を飛躍的に進めたTransformerをベースとしたBERTやRoBERTa、DeBERTa、T5などの論文、大規模言語モデルのGPTなどの論文、PaLMなどの論文、プロンプトエンジニアリングなどの論文を参照しています。
以下省略。
8. Conclusion
本論文の生成AIを用いたサイバーセキュリティ分野にもたらした貢献は以下の通りです。
- LLMから提案されたコマンドを実行するためのDocker環境の定義
- 攻撃エージェントの計画、実行、報告タスクのプロンプトエンジニアリング
- プロンプトチェーンとコントローラモジュールを用いて攻撃者のアクションを構成した
- 自動攻撃エージェントのデモ
- プロンプトを通してexploitの知識を引き出し実行する方法
- LLMが脅威に対して及ぼす影響の考察
生成AIはサイバーセキュリティに対して利益もリスクも持ちます。将来的には今回の議論をもっと発展させて調査する必要があります。
筆者らはLLMのファインチューニングや外部ツールのインターフェースの導入や、サンドボックス環境の防御機能の強化などを検証していく予定といっています。
最後に
長くなってしまいすみません。
理解の誤っている部分もあるかと思います。
見つけたらご指摘いただけますと幸いです。
みなさんの学習の一助になればうれしいです。