【転載】ラテラルムーブメント(横展開)の時に、いまだによく使われる SMB。横展開が実行された時の Windows ログの出方について。

さとっぺ retweeted:





ラテラルムーブメント(横展開)の時に、いまだによく使われる SMB。横展開が実行された時の Windows ログの出方についてまとめてあります。検出のロジックを考える時の参考になります。

Detecting Lateral Movement 101:
link.medium.com/hInMBpJJs8
:

さとっぺ retweeted:

ラテラルムーブメント(横展開)の時に、いまだによく使われる SMB。横展開が実行された時の Windows ログの出方についてまとめてあります。検出のロジックを考える時の参考になります。



Detecting Lateral Movement 101:

link.medium.com/hInMBpJJs8


ーー日本語訳ーー

横方向の動きの検出101:Windowsログ分析による動きのSMB / Windows管理共有の追跡

MITER ATT&CKリファレンス:戦術:横方向移動
テクニックID:T1021(リモートサービス)
サブテクニックID:T1021.002(リモートサービス:SMB / Windows管理共有)
通常、敵対者は、被害者組織に最初の足がかりを得ると、横方向への移動を開始します。一旦初期アクセスを得ると、彼らは特権をエスカレートさせ、エスカレートした特権を使って横方向に移動し、マルウェアを伝播させたり、さらに偵察して標的情報を収集したりします。
脅威のアクターが組織内を横方向に移動する手法は数多くあります。MITER ATT&CKは、攻撃者が使用するこれらのさまざまな技術を理解するために開始するのに最適なリソースの1つです。MITERは、「ラテラルムーブメント」戦術の下で、これらのラテラルムーブメント手法を非常によく整理しています。サイバー防御チームとして、これらの手法とそれらを検出および防止する方法を知っておく必要があります。
この簡単な記事では、敵が横方向に移動するために使用する手法の1つであるSMB共有について説明します。これは、組織内を横方向に移動するために敵対者が最も使用する手法の1つであり、それを検出する準備を整える必要があります。Windowsイベントログによって、この手法がどのように見えるかがわかります。

敵対者はこの手法をどのように使用しますか?

攻撃者は、管理者が合法的な作業に使用するデフォルトのWindows管理共有を乱用します。Windowsでは、デフォルトで、管理活動用にc $、admins $、IPC $共有が提供され、これらの共有には管理アカウントからアクセスできます。
攻撃者は、特権が昇格すると、これらの共有を他のワークステーションからマッピングし、マルウェアをコピーして横に移動します。さらに、net.exeなどのWindowsネイティブサービス/バイナリを使用して共有に接続し、移動によって生成されるアラートを削減します。以下は、ネットワーク共有をマップするために使用されるコマンドです。このコマンドは、マシン192.168.189.155のc $ admin-shareをマップします。
net use m:\\ 192.168.189.155 \ c $ / USER:kirtar

投稿用画像

このアクティビティは、ソースマシンとターゲットマシンでいくつかのフットプリントを作成します。このアクティビティを検出するには、どのログを探す必要がありますか?

横方向の動きをどのように検出しますか

これにより、ソースマシンのセキュリティログに2つの重要なログエントリが生成されます。
イベントID 4688(SysmonイベントID 1):プロセスの作成[コマンドライン監査を有効にして]イベントID
4648:明示的な資格情報を使用してログオンが試行されました。
一般的な組織では、通常のユーザーは他のワークステーションまたはサーバーの管理共有を移動してマップしません。したがって、通常のユーザーのワークステーションからのnet.exe(管理共有のマッピング)のSysmon eventid 1(4688 —セキュリティ)を調査する必要があります。
イベントID 1(コマンドラインパラメーター付きの4688)は、次の重要な詳細情報を提供します
-現在のプロセスとそのフルパス- 説明-
元の
ファイル名-
実行時にバイナリと共に渡されるコマンドラインパラメーター
-ユーザーの現在のディレクトリ-
スポーンしたアカウント/ユーザーこのプロセス
-プロセスバイナリイメージの
ハッシュ-親プロセス-
親プロセスコマンドラインパラメータ
次のスクリーンショットは、LAPTOP-O5R917V2 \ kirtarのアカウントを使用して、c $共有がIPアドレス192.168.189.155のマシンにマッピングされていることを示しています。親プロセスは、net.exeがcmd.exeを介して実行されることを示しています。ハッシュ、親プロセスのコマンドライン、イメージパスに関する詳細は、スクリーンショットで確認できます。
これにより、攻撃者がマルウェアをコピーした可能性のあるマシン(宛先)とともに、侵害された可能性のあるアカウントとマシンに関する重要な情報が得られます。

投稿用画像
図1.ソースでのSysmon EventID 1 —プロセスの作成(net.exe)

ソースで生成される他のログは4648です。このログは、攻撃者が明示的な認証情報を使用してネットワーク共有をマッピングするときに生成されます。このイベントは、宛先IPとホスト名、および両方のアカウント(元のアカウントと切り替えられたアカウント)に関する非常に重要な情報を提供します。この情報は、前のイベントから受け取った情報を実証するのに役立ちます。以下のスナップショットを見てください。

投稿用画像
図2. 4648(使用される明示的な資格情報)

スクリーンショットに示すように、元のアカウントはLAPTOP-O5R917V2 \ kirtarと切り替えられたアカウントkirtarです(これはリモートマシンへの認証に使用されます)。ターゲットマシンSANS-SIFTのホスト名。さらに、ネットワーク情報は宛先IPアドレス(192.168.189.155)を提供します—これは、前のイベントのコマンドラインパラメーターに対して検証できます。
宛先での検出
同じコマンドで、宛先マシンにもいくつかのログが生成されます。宛先で以下のログが生成されます。
4776-コンピューターがアカウントの資格情報を検証しようとしました
4672-新しいログオンに割り当てられた特別な権限
4624(タイプ3)-アカウントが正常にログオンしました

投稿用画像
図3.管理者特権によるローカル認証の典型的な三部作

これら3つのイベントすべての時間を確認すると、ほぼ同時にログに記録されています。これらのイベントは、ローカルNTLM認証(4776)がローカル管理アカウント(4672)を介してネットワーク(Type3)で発生するために生成されます。
宛先で生成される主要なログの1つは、EventID 5140です。これは、実際のイベント(ネットワーク共有アクセス)の「ログ」です。
このログは、次の情報を提供します
-共有へのアクセス/マッピングに使用されるアカウント-
ソースマシンのIPアドレス(共有へのアクセス元)
-共有の名前とパス
上記で実行したコマンドの結果として生成された5140 EventIDの次のスクリーンショットを参照してください。これは、アカウントSans-SIFT \ kirtarがC $共有へのアクセスに使用されていることを示しています。この共有にアクセスするソースマシンのIPは192.168.189.1です。

投稿用画像
図4. EventID 5140(ネットワーク共有オブジェクトにアクセスしました。)

このログに関連する警告がいくつかあります(5140)。このログはデフォルトでは有効になっていません。詳細な監査ポリシー設定の[オブジェクトアクセス]で[ファイル共有]監査を有効にして、GPOで有効にする必要があります。次に、2008R2 +エディションで利用できます。5140に必要な監査ポリシー構成を示す次のスクリーンショットを見てください。

投稿用画像
図5. 5140の監査ポリシー構成

したがって、これまでに見てきたように、この横方向の動きを検出するために活用できるWindowsセキュリティイベントログがかなりあります。正確なフィルターに基づいてアラートを作成すると、精度を向上させ、横方向の動きの検出における誤検知を減らすのに役立ちます。
同様に、イベントログを使用して、他の横方向の移動手法も検出できます。他のテクニックについても記事を書こうと思います。
現時点ではこれで終わりです。読んでいただき、ありがとうございます。

―原文

Detecting Lateral Movement 101: Tracking movement SMB/Windows Admin Shares through Windows Log Analysis

MITRE ATT&CK Reference : Tactic: Lateral Movement
Technique id: T1021 (Remote Services)
Sub-technique Id: T1021.002 (Remote Services: SMB/Windows Admin Shares)
Adversaries, typically, start moving laterally once they get initial foothold in the victim organization. Once they get initial access, they escalate their privileges and move laterally with the escalated privileges either to propagate their malware or to further reconnaissance & collect the targeted information.
There are many techniques by which threat actors move laterally in the organization. MITRE ATT&CK is one the best resources to start with to understand these various techniques used by the adversaries. MITRE has very well organised these lateral movement techniques under “Lateral Movement” tactic. As a cyber defense team, we should be aware of these techniques and how to detect and prevent them.
In this quick article, I am going to talk about one of the techniques used by the adversaries for moving laterally — SMB Shares. This is one of the most used techniques by adversaries to move laterally in the organization and we should be better prepared to detect it. We will see how Windows Event Logs make this technique highly visible.

How Adversaries Use this technique?

Adversaries abuse the default Windows admin shares that are used by the administrators for legit work. Windows, by default, provides c$, admins$ and IPC$ shares for administrative activities and these shares are accessible through administrative accounts.
Adversaries, once escalated privileges, map these shares from other workstations and copy their malware and move laterally. Moreover, they use windows native services/binaries like net.exe to connect to the shares to reduce any alerts generated by their movement. Following is the command used to map network share — this command maps c$ admin-share of the machine 192.168.189.155.
net use m: \\192.168.189.155\c$ /USER:kirtar

Image for post

This activity creates a few footprints at the source as well as the target machines.Which logs we need to look for to detect this activity?

How to detect the lateral movement?

This will generate 2 important log entries in Security logs at the source machine.
Event ID 4688 (Sysmon EventID 1): Process Create [ with command line auditing enabled]
EventID 4648: A logon was attempted using explicit credentials.
In a typical organization, normal users do not go around and map the admin shares of the other workstations or the servers. Hence, any Sysmon eventid 1 (4688 — security) for net.exe (mapping admin share/s) from the workstation of the normal users should be investigated.
EventID 1 (4688 with command line parameters) provides following key details
-Current Process with its full path
-Description
-Original File Name
-Command Line parameters passed with the binary while executed
-Current directory of the user
-the account/user who has spawn this process
-hashes for the process binary image
-Parent Process
-Parent Process command line parameters
The following screenshot shows that c$ share is mapped of the machine with IP Address 192.168.189.155 by using account of LAPTOP-O5R917V2\kirtar. The parent process shows that net.exe is executed via cmd.exe. The details related to hash, parent process command lines, image path can be seen in the screenshot.
This gives us crucial information about potentially compromised account and machine along with the machine(destination) where adversaries might have copied their malware.

Image for post
Figure 1. Sysmon EventID 1 at Source — Process Create (net.exe)

The other log generated at the source is 4648. This log is generated as attacker uses an explicit credential to map the network share. This event provides very important information about the destination IP & hostname and both of the accounts (original and switched). This information will help us to substantiate the information received from the previous event. Look at the snapshot below.

Image for post
Figure 2. 4648 (explicit credentials used)

As shown in the screenshot, the original account is LAPTOP-O5R917V2\kirtar and the switched account kirtar (this is used for authenticating to the remote machine). The hostname of the target machine SANS-SIFT. Furthermore, Network Information provides the destination IP address (192.168.189.155) — this can be verified against the command-line parameters of the previous event.
Detection at the Destination
The same command generates a few logs on the destination machine as well. Following logs are generated at the destination.
4776 — The computer attempted to validate the credentials for an account
4672 — Special privileges assigned to new logon
4624 (Type 3) — An account was successfully logged on

Image for post
Figure 3. Typical trilogy for local authentication with administrative privileges

Look at the time for all these 3 events, they are logged at nearly same time. These events are generated because local NTLM authentication (4776) happens over the network (Type3) via local administrative account (4672).
One of the key logs generated at the destination is EventID 5140. This is “the log” for the actual event — network share access.
This log provides the following information
-the account used for accessing/mapping the share
-IP address of the source machine (from where the share is accessed)
-Name and Path of the share
Please see the following screenshot of 5140 EventID generated as a result of the command that we ran above. It shows that account Sans-SIFT\kirtar is used to access the C$ share. The IP of the source machine from where this share is accessed is 192.168.189.1.

Image for post
Figure 4. EventID 5140 (A network share object was accessed.)

There are couple of caveats related to this log (5140). This log is not enabled by default, this needs to be enabled via GPO by enabling “File Share” auditing under “Object Access” in Advanced Audit Policy Configuration settings. Secondly, it is available in 2008R2+ editions. Look at the following screenshot that shows the audit policy configuration required for 5140.

Image for post
Figure 5. Audit Policy configuration for 5140

So, as we have seen there are quite a few windows security event logs that can be leveraged to detect this lateral movement. Creating Alerts based on the precise filters will help in improving precision and reducing false positives in detecting lateral movement.
Similarly, event logs can be used to detect other lateral movement techniques as well. I will try to write articles for other techniques as well.
That’s it for now. Thanks for reading and happy hunting fellas !!
by :
Kirtar Oza
Twitter : @Krishna (kirtar_oza)
LinkedIn: https://www.linkedin.com/in/kirtaroza/
email: kirtar.oza@gmail.com

【転載】AD環境のクライアントログイン処理。図でのまとめ。

画像

tike retweeted: AD環境のクライアントログイン処理。図でのまとめ。 twitter.com/ashokkrishna99…:

tike retweeted:

AD環境のクライアントログイン処理。図でのまとめ。 twitter.com/ashokkrishna99…

【転載】AWS×コンテナで基本的なDevSecOpsアーキテクチャをデザインしたお話 - How elegant the tech world is...!

AWS×コンテナで基本的なDevSecOpsアーキテクチャをデザインしたお話 - How elegant the tech world is...!:

f:id:iselegant:20200726123858p:plain

先日、僕が担当する業務でECS/Fargate利用を前提にDevSecOpsアーキテクチャをデザインし、社内のAWS勉強会にて登壇する機会をいただきました。
本ブログでも内容をかいつまんでご紹介できればと思います。

AWSによらず、コンテナを利用されている方にとって、一つのプラクティス例としてご参考になれば幸いです。
※コンテナ自体の説明や必要性に関する内容は省略していますm(_ _)m

そもそもDevOpsとは?

DevSecOpsの導入意義をお伝えするた前に、まず軽くDevOpsの意義をお伝えします。

※とは言え、この記事をご訪問されている方にとっては「何をいまさら...」な内容かもしれませんし、ググればDevOps自体の情報はたくさん見つかりますので、重要なポイントのみ述べることにします。

DevOpsとは、一言で述べれば、開発チームと運用チームが協力してビジネス価値を高める活動概念です。

昨今、ITはビジネス効率化の手段だけではなく、ビジネス差別化の手段の一つとなっています。
スマホネイティブなサービスが普及し、利用者に新しいユーザー体験がに届けられることができるようになりました。併せて、サービスに対する利用者からのフィードバックも受け取りやすくなっており、多数の競合サービスに引けを取らないように、サービス提供者が改善やニーズ取り込みを素早く行い、価値を提供し続けることが重要になってきています。

このような活動を継続するためには、MVP(Mimimum Viable Product)のように利用者にとって本当に価値のあるものを小さく早く届けることが重要です。

f:id:iselegant:20200726123147p:plain

ここで、ユーザーフィードバックをモニタリングする責務はサービス運用チームが担うことが多いかと思います。
また、ニーズを受け、新たな機能追加などは開発チームが行います。
継続的にサービス価値を高めるためには、以下のように運用と開発のフェーズを順番に踏んでいるわけですね。

DevOps_feedback-diagram.ff668bfc299abada

AWSが提供するページより図を引用(DevOps とは? - DevOps と AWS | AWS)

つまり、変化に対して柔軟かつ品質の良いサービスを提供し続けるには、開発と運用がうまく協調する必要があります。
かつ、このサイクルをいかに早く回していけるか、が重要となります。

うまく協調するためには縦割りな組織構造よりはサービス・ソリューションに最適な組織作りアジャイル開発やCI/CDといったラクティス、「Git」「Docker」「AWS Codeシリーズ」等のツールなど、これら要素組み合わせることで達成を目指していきます。
DevOpsはこれらの取り組みの総称としても表現できます。

ちなみに、CI/CD視点からの切り口になってしまいますが、AWSでは年間190 million(1.9億回)もアプリケーションがデプロイ可能な環境が整っているそうです。

www.youtube.com

また、以下はAWSの最新情報から集計した2018年12月〜2020年5月のAWS月別リリース数ですが、2020年に関しては平均116件/月ものリリースがなされています。

f:id:iselegant:20200726123238p:plain

まさにDevOpsを体現しているからこそ成し遂げている結果ですね。

なぜDevSecOpsが求められるのか?

DevSecOpsとは、一言で述べるとDevOpsの取り組みにセキュリティを協調させたものです。

DevOps実践のもとで高速でサービスを追加していくと、それに応じてセキュリティ観点で脆弱な作り込みリスクも増えることになります。
また、後続の工程でセキュリティテストを実施して問題が健在化すると当然手戻りが発生します。
設計や構築などより早いタイミングで問題を検出できることが、結果的に安定なサービス提供につながるでしょう(より早い工程段階でセキュリティ対策を施すことを「シフトレフト」と呼んだりします)。

一度セキュリティインシデントが発生すると、ユーザーからの信頼が失墜し、ビジネスの根幹を揺るがすことが多いのが実情です。

もちろん、扱う情報や業界規制等によって取るべきセキュリティ対策のレベルを見直すことも重要です(個人情報を保有する or しない、クレジットカード情報や金融系取引情報を扱う or 扱わない、などで守り方の温度感も変わってきます)。
すべてのサービス層で重厚なセキュリティ対策を施すと対応に必要な工数が増えたり、運用の手間が増えてしまうため、スコープの見極めは大切です。

とは言え、メンバー全員で責務を持つことでセキュリティ意識を底上げさせ、自動化として組み込むことができれば、その手間をなるべく減らしつつ、リスクを下げることもできそうですね。
DevOpsにセキュリティ系のツールをうまく組み込み、メンバー全員で開発ライフサイクルのセキュリティに責任を持つという視点を醸成することがDevSecOpsの意義の一つなのだと考えています。

次に、プラクティスの一つであるCI/CDに対して、どのようなセキュリティツールを活用するとDevSecOpsの土台が実現できるか、という点に着目していきます。

コンテナに求められるセキュリティ対策要件

ここでは、コンテナアプリケーションで必要なセキュリティ対策について考えてみます。

結局のところ、アプリケーションに脆弱性を作り込まないように対処する点は従来のアプリケーション開発となんら変わりありません。
コンテナはベースイメージOS上にアプリケーションと必要な依存パッケージ等を一つのイメージとして閉じ込めています。つまり、ベースイメージOS自体やパッケージに対する脆弱性対応について考慮する必要があります。
また、Dockerfile等によるコンテナイメージ作成プロセスが適切に行われているかどうか、という点についても考慮する必要があります(動作に対して不要なパッケージが混入している、本来は不要であるrootユーザーでプロセス実行がされている、等)。

基本的な対策としては、まず以下の検討ポイントを挙げました。

  • イメージ作成プロセスの妥当性
  • イメージ内OS・アプリケーションの脆弱性チェック
DevSecOps実践を目指す中で、CI/CDにこれらのセキュリティ対策をどのように行っていくか、がポイントの一つになります。

※実際には、コンテナイメージ自体の保護に加えて、レジストリやCI/CDパイプライン、コンテナオーケストレーションツール等の保護なども考慮する必要があります。
また、開発ライフサイクル全体でセキュリティに必要な対応を俯瞰すると、SAST(Static Application Security Testing)、DAST(Dynamic Application Security Tesing)、IAST(Interactive Application Security Testing)など
全体の位置付けを考慮する必要がありますが、話が膨らむ上に今回のトピックから焦点がぶれてしまうので、敢えてコンテナCI/CDに組み込むセキュリティ対策という観点でお話しています。

キーファクターとなるOSS

要件に合うセキュリティ対策を実装するべく、今回はOSSを中心に以下ツールを選定しました(コスト都合かつスモールに始めたかったので、セキュリティベンダーが提供する商用ツールは一旦見送りにしました)。

f:id:iselegant:20200726123858p:plain

ここから、順番に各ツールの特徴を見ていきます。

hadolint

コンテナイメージ作成はDockerfileの記述内容に従って実行されますが、hadolintはDockerfileを静的解析することでベストプラクティスに従った流れかどうかチェックしてくれるツールです。

github.com

プログラミング言語Haskell」で開発されたDockerfileのLinterなので、hadolintと命名されているようです。

ちなみに、hadolintはShellCheck)と呼ばれるシェルスクリプトの静的解析をベースにしてチェックもしてくれます。
実際のところ、Dockerfile内はシェルスクリプトの内容を含むケースがが多く、ShellCheckベースの検証で安全ではない記述方法の検出は大変助かります。

例えば、次の様なDockerfileにてチェックを掛けると、hadolintがいくつかのダメ出しで知らせてくれます。

FROM debian RUN node_version = "0.10" \ && apt-get update && apt-get -y install nodejs="$node_version"
COPY package.json usr/src//app
RUN cd /usr/src/app \ && npm install node-static EXPOSE 80000
CMD ["npm", "start"]
f:id:iselegant:20200726124407p:plain

上記例はhadolint側でのチェック内容を表示するために、敢えてhadolint REDOME内の内容記載をそのまま転記しているため、実際にはここまでひどく(?)指摘されることは無いと思います(たぶん)。

CI/CD内でイメージ作成の前処理として上手に組み込むことで、イメージ作成プロセスを安全に維持できそうですね。

trivy

trivyはAquaSecurity社が提供するコンテナ脆弱性スキャナーです。

github.com

日本人の福田鉄平さんが開発し、その後はAqua社側にてメンテナンス及び提供されています。
その他の脆弱性スキャナーツールと比較して軽量かつ高機能であり、インストールもスキャン方法も非常に簡単で使いやすいのが特徴です。
参考情報として、下記は英国政府の技術ブログですが、ここでもtrivyが活用されていました。

technology.blog.gov.uk

次のようにイメージを引数として実行することで、該当する脆弱性をCVE番号とともに出力してくれます。

f:id:iselegant:20200726124005p:plain

出力結果には重大度レベル(SEVERITY)も併せて表示されます。
LOW < MEDIUM < HIGH < CRITICALの順列で影響が大きくなるので、これらの結果を基に優先的に対応すべき脆弱性対象を確認することができます。

さて、イメージの脆弱性スキャン機能ですが、AWSのマネージドなコンテナレジストリであるECRでも提供しています。
なぜtrivyを採用したかというと、アプリケーションの依存パッケージまで踏み込んでスキャンしてくれるかどうかという点で優位性があるからです。
ECRのイメージスキャンはClairというOSSをベースに作成されています。
ClairはコンテナのOSパッケージレベルをスキャン対象としており、trivyと比較してスコープが異なります。

また、スキャン可能なベースイメージも異なります。具体的に、ClairはBusyboxやAlpineの最新バージョンなどのスキャンには対応していません

※参考:Docker Image Security: Static Analysis Tool Comparison - Anchore Engine vs Clair vs Trivy - a10o.net - Alfredo Pardo


加えて、Alpine Linuxの例で述べれば、Clairとtrivyは脆弱性情報の収集先情報源が異なることから、検出対象精度の数に2倍弱の違いがあるようです(詳細はGithubのtrivy REDOME.mdをご覧ください)。

Clair uses alpine-secdb. However, the purpose of this database is to make it possible to know what packages has backported fixes. As README says, it is not a complete database of all security issues in Alpine. Trivy collects vulnerability information in Alpine Linux from Alpine Linux aports repository. Then, those vulnerabilities will be saved on vuln-list.
alpine-secdb has 6959 vulnerabilities (as of 2019/05/12). vuln-list has 11101 vulnerabilities related to Alpine Linux (as of 2019/05/12). There is a difference in detection accuracy because the number of vulnerabilities is nearly doubled.
以上の理由より、導入と利用が簡単かつ高精度なtrivyを採用することにしました。

Dockle

Dockleは天地知也さんが開発したコンテナイメージに含まれるセキュリティホールをチェックしてくれるツールです。
hadolintとは異なり、Dockerfileではなくイメージに対するスキャンであり、ベースOSイメージ側の設定内容に関しても踏み込んでスキャンしてくれる点が特徴です。
また、CIS(Center for Internet Security)と呼ばれる国際的なインターネットセキュリティ標準化に取り組む団体が提供しているベンチマークに対する遵守状況もチェックしてくれます。

Trivy同様、インストール及び実行が簡単で以下のように検出可能です。

f:id:iselegant:20200726124713p:plain

hadolintやTrivyとは異なる観点でのチェックを行ってくれるため、こちらも利用する方針としました。

CI/CDアーキテクチャへの落とし込み

ここまでにご紹介したDevSecOpsツールをCI/CDに組み込んでいくのですが、まずはベースとなるECS/FargateのCI/CDアーキテクチャを考えてみます。

f:id:iselegant:20200726124823p:plain

開発環境のCI/CD構成をシンプルに表現したものです。

処理の流れとしては、次の通り。

  1. 開発者がCodeCommit上にソースコードをプッシュすると、CodePipelineが起動
  2. CodeBuildにて以下の順番でビルドを実施が実施
    • アプリケーションのビルド&テスト
    • Dockerイメージのビルド
    • ECRへのDockerイメージプッシュ
  3. ビルド処理が完了するとCodeDeployに遷移
  4. CodeDeployにより、ECS/Fargate上にビルドしたコンテナイメージが展開
今回はファーストステップとしてシンプルにデザインと導入を進めたかったので、ビルドフェーズ内(CodeBuildの動作仕様を定義するbuildspec.yml内)に各処理を定義してスキャンする方針としました。

ここで、コンテナイメージビルド処理より前にhadolintによりDockerfileのチェック自体は先行で実施しておくのが望ましそうです。
イメージビルド後、影響度の大きい脆弱性が見つかったらより早い段階で検知すべきという考え方から、trivyイメージスキャンを優先しています。最後にDockleでCISベンチマークに従っているかをチェックする流れとしました。

ビルドフェーズ内の処理を図で表現すると次のようになりました。

f:id:iselegant:20200726124850p:plain

なお、開発環境ではアプリケーションの機能動作確認を優先的に行うべきであり、CRITICALな対象ではない限り、このタイミングでビルド処理を止めたくないというニーズがありました(LOWレベルの検出でアプリケーション開発が止まってしまうと、逆にアジリティを下げる原因にもなってしまう可能性があったからです)。

また、trivyで脆弱性が検出された場合、対象や対応状況を管理しておきたいと考え、セキュリティイベントの統合マネージドサービスであるSecurity Hubに集約することで実現しています。
各種ツールはJSON形式で結果を出力できるため、buildspec.yml内にてSecurity HubのASFFと呼ばれる標準的な検出結果形式に各脆弱性情報を整形し、SDKからSecurityHubにインポートすることで集約管理することができます。

また、マルチアカウント構成を考慮し、AWSアカウント毎に個別にセキュリティ情報を管理・モニタリングするのではなく、アカウント間で情報を集約できようにセキュリティ管理専用のAWSアカウントを作成し、メンバーシップ設定を実施をすることで統合しています。

f:id:iselegant:20200726125057p:plain

ここで、少しだけbuildspec.ymlの記載例に踏み込んで見たいと思います。
各buildspec内フェーズ毎の動作をコメントと併せて記載してみました。

version: 0.2 env: variables: : phases: install: runtime-versions: docker: 18 : pre_build: commands: - docker pull hadolint/hadolint - docker run --rm -i hadolint/hadolint hadolint - < Dockerfile - TRIVY_VERSION=$(curl -sS https://api.github.com/repos/aquasecurity/trivy/releases/latest | jq -r .name | sed -e 's/v//g') - rpm -ivh https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.rpm - DOCKLE_VERSION=$(curl --silent "https://api.github.com/repos/goodwithtech/dockle/releases/latest" | \ grep '"tag_name":' | \ sed -E 's/.*"v([^"]+)".*/\1/' \ ) && rpm -ivh https://github.com/goodwithtech/dockle/releases/download/v${DOCKLE_VERSION}/dockle_${DOCKLE_VERSION}_Linux-64bit.rpm : build: commands: - docker build -t ${APP_NAME}:${IMAGE_TAG} . - docker tag ${APP_NAME}:latest ${PUSH_ECR_REPO_URI}:${IMAGE_TAG} : post_build: commands: - trivy --no-progress -f json -o trivy_results.json --exit-code 0 ${PUSH_ECR_REPO_URI}:${IMAGE_TAG} - (Security Hubへ結果をインポートするスクリプトを実施(trivy_results.jsonがインポート対象)) - trivy --no-progress --exit-code 1 --severity CRITICAL ${PUSH_ECR_REPO_URI}:${IMAGE_TAG} - exit `echo $?` - dockle --format json --exit-code 1 --exit-level "FATAL" ${PUSH_ECR_REPO_URI}:${IMAGE_TAG} - exit `echo $?` - $(aws ecr get-login --region ${AWS_REGION} --registry-ids ${AWS_ACCOUNT_ID} --no-include-email) - docker push ${PUSH_ECR_REPO_URI}:${IMAGE_TAG} : artifacts: files:
    :
今回は手始めにtrivyの出力結果をSecurity Hubに登録する流れを実装しています。

上記のbuildspec.ymlでは、trivyによるイメージスキャンを2回実行しています。
この理由として、SEVELITYによらず全ての脆弱性情報をSecurity Hubに登録するため、一時的に結果をすべて出力する目的で1回目を実行しています。
SecurityHubへの登録完了後、CRITICALな対象があればビルドを中止して修正を優先すべきという方針としているため、CRITICALレベルに絞って再度実行することでリターンコードを取得しています(1回目のtrivy実行時に内部で脆弱性情報がキャッシュされているため、2回目のスキャン自体は高速です)。

実際にビルド中に脆弱性が見つかると、次のようにSecurity Hub側に自動登録されます。

f:id:iselegant:20200726125301p:plain

シンプルですが、これで脆弱性情報の管理・モニタリングまで含めたフローが完成しました。

プロダクション稼働を考慮した際の課題点

ここまででDevSecOpsを実践するアーキテクチャの一例をご紹介しました。
ただ、本番運用で利用しようとすると、まだ色々と至らない点が存在します。
ここでは、その課題点について少し向き合って見ようと思います。

アプリケーション毎に同一チェック処理を定義する必要がある

hadolintやTrivy、Dockleによるスキャンはアプリケーション毎にその流れはほぼ同じになることが見込まれます。
しかし、現状ではアプリケーション毎に別々のbuildspec.yamlに定義する作りとなっています。
これではアプリケーションの数が増えてくると定義が重複し、管理コストが増してしまいます。
状況によっては個別のCI内処理に組み込むより、共通化して切り出すほうが望ましい形になります。
この点について、先日クックパッドさんの開発者ブログにて、まさにこの問題に対処した素晴らしい内容が公開されました。

techlife.cookpad.com

LambdaやSQS活用し、非同期かつ疎結合に処理するようにアーキテクチャが設計されています。
規模拡大に伴い、このような形が望まれてくると思いますので、併せてこちらもご参考にするのが良いと思います(僕自身も参考にさせていただいています)。

CI/CD実行時にのみにセキュリティチェックがされる

現状の構成ではCI/CDが実行されたタイミングでセキュリティチェックがされます。
しかし、当然の話ですが、実際に脆弱性情報はCI/CDとは別の時間軸で日々報告されています。
IPAが運営するJVN iPediaベースの情報になりますが、1ヶ月あたり1000件以上の脆弱性が報告されています。

仮に、とあるアプリケーションの更新がしばらく実行されていないケースでは、プロダクション環境で稼働中のアプリケーションに該当する脆弱性が発見されたとしても、CI/CDのみが発見の契機であり、見逃してしまうかもしれません。

アプリケーションの重要度にもよりますが、より確実に検知を目指すのであれば定期的なチェック処理を実装する必要がありそうですね。
※この観点はCI/CD組み込みというよりは、運用視点での日々のモニタリング活動側に含まれるかもしれません。

各環境毎にSEVELITYとどう向き合うか

今回、trivyに関してはSEVELITYがCRITICALな場合にビルド処理を異常終了する仕様にしました。
というのは、CRITICALな状態でのプロダクション環境デプロイはまず避けるべきですし、このレベルで検知されるとアプリケーション機能追加より対応を優先すべきと判断したからです。

この異常終了する判断のしきい値ですが、アプリケーションの内容によってはHIGHが適切かもしれません。

一方、開発環境では、ビジネス価値をもたらす機能追加の検証を優先したい場合があります。
そのような場合、ステージング環境で一度止めるという選択肢もケースによってはあるかもしれません。
ただし、ステージング環境の利用は総合テストフェーズで利用されるシーンも多く、シフトレフトな考え方と若干反するとも考えられます。

DevSecOpsに取り組むにあたって、アプリケーションの重要度、各環境毎の目的のバランスを見極めながら、ビルドを止めるのか、それとも後で対応するのか、といったことをCI/CD構築と併せて検討するという視点も重要な検討ポイントだと考えています。

ECRでは現状DCTに対応していない

少しDeep Diveな内容になりますが、Dockerには「Docker Content Trust(DCT)」というイメージ自体の完全性やイメージ提供者の検証を行う仕組みがあります。
これはDocker 1.8から実装された機能で、署名済みかつ検証済みのコンテナイメージしか利用させなくすることができます。

DCTの有効化は簡単で、docker pulldocker pushを行う際の環境にて、環境変数をセット(DOCKER_CONTENT_TRUST=1)することで有効になります(CodeBuildにおいては、buildspec.yml内で環境変数を定義すればDCTが有効になります)。
ちなみに「DCTが有効な状態でpull/pushがされるか?」というのは、Dockleのチェック対象となっています(さきほどDockleの出力例をご紹介しましたが、その中でINFOレベルで出力されている「CIS-DI-0005」が該当します)。

このDCT、内部的にNotaryと呼ばれるサーバー・クライアント側OSSが安全なイメージの作成と検証動作を担ってます。

github.com

docs.docker.com

しかし残念ながら、現時点ではECRはこのNotaryをサポートされておらず、ECRに検証済イメージをプッシュしようとするとエラーになってします。

そのため、現状ではDCTを無効化した上でDockleによるチェックの際「CIS-DI-0005」を対象から除外する必要があります。

f:id:iselegant:20200726125626p:plain

なお、今月開催された(AWS Cloud Containers Conference)のECRに関するセッション「Security Best Practices with Amazon ECR」内で、スピーカーのOmar Paul氏ECRのSr Product Manager)が、ECRのNotary GA目処として2021年内であることを名言しています。

github.com

ECRでのDCT利用はもう少し先になりそうですね。

その他参考情報

今回ご紹介したアーキテクチャを検討する上で参考にした情報も併せて共有しておきます。

AWSの公式ブログでもtrivyを扱った事例がいくつか紹介されていたりします。
以下はAWS Container Heroでもあり、Aqua社のVP OSSでもあるLiz Rice氏が寄稿したtrivy × CodePipelineの記事になります。

aws.amazon.com

また、以下はtrivyをSecurity Hubに取り込む際の例がサンプルコード付きで紹介されています。

aws.amazon.com

次の参考情報は、AW re:Inforce 2019 (AWS主催のセキュリティ&コンプライアンス系カンファレンス)にて実施されたコンテナ × DevSecOpsに関するワークショップの内容です。
以下のような構成をハンズオン形式で学べるので、DevSecOpsをサッと学ぶにはちょうどよいボリューム感かと思います。

diagram-basic-arch.png

※図を引用(Container DevSecOps - Integrating security into your container pipeline Overview)

さいごに

最後までお読みいただきありがとうございました。
ブログで誰かに何かを伝えようと思うと、どうも内容が盛りだくさんになってしまいがちです...
読みにくい&わかりにくい箇所があったかもしれませんが、皆さんがコンテナでDevOpsを実践する方々に少しでもコンテナ自体のセキュリティを意識するきっかけとなれば嬉しいです。

※お決まりの言葉ですが、ここでの内容はすべて筆者の私見であり、所属する組織の意見でも代表するものでもありません。また、あくまで特定の秘匿情報ではなく公開可能な情報から述べているため、その点はご留意ください。

ではでは。