vclusterとFalcoによるハニーポット: エピソード II

By 清水 孝郎 - DECEMBER 21, 2023

SHARE:

本文の内容は、2023年12月21日に JASON ANDRESS が投稿したブログ(https://sysdig.com/blog/how-to-honeypot-vcluster-falco-part-2/)を元に日本語に翻訳・再構成した内容となっております。

本記事は、Falco、vcluster、その他のさまざまなオープンソース ツールを使用したハニーポット構築に関するシリーズのパート 2 です。前回の記事については、「 vcluster と Falco を使用したハニーポットの構築: エピソード I 」を参照してください。

最後にヒーローたちと別れたとき

前回の記事では、高インタラクション ハニーポットについて説明し、vcluster を使用して、意図的に脆弱性を持たせた SSH サーバーをクラスター内に構築し、サーバーが奪取されたときに環境内の他のものに悪影響を及ぼさないようにしました。次に、ホストに Falco をインストールし、SSH サーバーへの攻撃を行い、Falco ログを監視して、 /etc/shadow  が読み取られたときに適切なルールがトリガーされることを確認しました。 

これはすべて素晴らしいことですが、これは単なる始まりにすぎません。今回は、ハニーポット内で何が起こっているかに反応できるように、ハニーポットに追加の機能を追加します。これらの追加要素の一部は、将来追加機能を追加するためのインフラストラクチャーも構築します。 

基本を超えていきますので、これからが楽しくなります。

私たちの欠点

前回の記事のセットアップには 2 つの大きな欠点がありました。他にもいくつかありますが、それらについては後ほど説明します。

まず、ハニーポットの以前のバージョンでは、実際のハードウェアの上にある OS 上で直接実行する必要がありました。これは、最終的に無秩序に拡大するハニーポット ビットをサポートするハードウェアの部隊をセットアップしない限り、実際にはうまく拡張できないため、実用性は限られています。当時、これがMinikubeFalcoでこれを行う唯一の方法でした。以前の Falco には、他の方法で行う必要があるカーネル モジュールがなかったためです。幸いなことに、これはもう当てはまりません。よりクラウドネイティブなアプローチを採用し、これを AWS の EC2 インスタンス上に構築できるようになり、すべてが満足できるものになります。クラウドへ行きましょう!

注:これから構築するハニーポットは、定義上、意図的に脆弱なシステムです。監視方法はまだあまり構築されていないため、インターネットに公開することはお勧めしません。

第二に、古いハニーポットは、ポッドの機密ファイルを調べたときに Falco ログに文句を言う以外、ほとんど何もしませんでした。これも修正できます。Falcosidekick と Falco Talon を使用して、Falco ルールをトリガーするときにハニーポットが実際に何かを実行できるようにします。

レスポンスエンジン

レスポンス エンジンは、EDR (エンドポイント検出と対応)、SIEM (セキュリティ情報とイベント管理)、SOAR (セキュリティ オーケストレーション、自動化と対応)、および XDR (拡張検出と対応)のコンテキストでよく使用される用語です。詳細については、 EDR vs. XDR vs. SIEM vs. MDR vs. SOAR を参照してください。

これは、セキュリティの脅威に対する自動対応を実行するコンポーネントです。これはまさにこの場合に必要なツールです。 

ハニーポットとの対話によって Falco ルールのいずれかに違反した場合、自動アクションを実行する必要があります。私たちの特別なケースでは、攻撃者が所有していたポッドをシャットダウンして、その場所にクリーンなポッドを再起動できるようにします。これには Falco Talon というツールを使用します。また、別のツールである Falcosidekick も含める予定です。これを使用すると、環境内で発生するイベントに応じて他のことを行うための柔軟性が将来的にはさらに高まります。 

Falco Sidekick

Falco でハニーポットを構築する

Falcosidekick は、Falco を他の多くの素晴らしいツールに接続することを可能 にする優れたツールです。Falcoをモニタリングやアラートの実行、異なるツールへのログの送信、その他あらゆることに利用することができます。これは、Falco Talonにイベントを送信するために使用する連携ツールです。

Falco Talon

Falco Talon は、トリガーした Falco ルールに対する実際の対応を実行する駒です。Talon には、どの Falco ルールに対応する必要があるか、およびそれらのルールがトリガーされたときに何をすべきかを定義する独自の内部ルール セットがあります。 

手を動かします

早速始めて、いくつかのものを構築してみましょう。 

今回は、AWS上のUbuntu Server 22.04 t3.xlarge EC2インスタンス上にハニーポットを構築します。もっと小さいインスタンスでもよいかもしれませんが、インスタンスに十分なリソースがないと、すべてが起動しなくなる可能性があります。t2.microのような非常に小さなインスタンスは、ほぼ間違いなく、すべてを適切に機能させるのに十分な馬力を備えていません。

理論的には、適切なアプリケーション ビットがすべて揃っていれば、これを同様のクラウド サービス上に構築して動作させることができるはずです。 

前提条件として、次のツールを指定されたバージョン以降でインストールしておく必要があります。

残りの部分は、プロセスを進めながらインストールします。 

Minikubeを起動する

1 – まず、Docker ドライバーを使用して minikube を起動します。動作を確認し、いくつかの依存関係をダウンロードします。

2 – 次に、minikube の Ingress アドオンを有効にします。これにより、間もなくインストールする SSH サーバーにアクセスできるようになります。

1 $ minikube start --vm-driver=docker

😄  minikube v1.32.0 on Ubuntu 22.04
✨  Using the docker driver based on user configuration
📌  Using Docker driver with root privileges
👍  Starting control plane node minikube in cluster minikube
🚜  Pulling base image ...
💾  Downloading Kubernetes v1.28.3 preload ...
    > preloaded-images-k8s-v18-v1...:  403.35 MiB / 403.35 MiB  100.00% 51.69 M
🔥  Creating docker container (CPUs=2, Memory=3900MB) ...
🐳  Preparing Kubernetes v1.28.3 on Docker 24.0.7 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔗  Configuring bridge CNI (Container Networking Interface) ...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🔎  Verifying Kubernetes components...
🌟  Enabled addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

2 $ minikube addons enable ingress

💡  ingress is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
You can view the list of minikube maintainers at: https://github.com/kubernetes/minikube/blob/master/OWNERS
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231011-8b53cabe0
    ▪ Using image registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20231011-8b53cabe0
    ▪ Using image registry.k8s.io/ingress-nginx/controller:v1.9.4
🔎  Verifying ingress addon...
🌟  The 'ingress' addon is enabledCode language: JavaScript (javascript)

Falcoをインストールする

1 – 次に、Falco の Helm チャートにアクセスできるように、falcosecurity helm リポジトリを追加する必要があります。

2 – リポジトリを追加したら、更新して最新のチャートを取得します。

3 – kubectl を使用して、Falco をデプロイするネームスペースを作成します。これと同じネームスペースを、後で Sidekick と Talon にも使用します。

4 – そして、Falco のインストールを開始します。 ここで、Falco ログのバッファリングを無効にするための追加の引数がいくつかあることがわかります。これにより、イベントをより迅速に取得し、Falco のインストール中に Sidekick をインストールし、Web UI を有効にし、TalonがリスニングするURL を指すように Sidekick の送信 Webhook を設定します。

1 $ helm repo add falcosecurity https://falcosecurity.github.io/charts
"falcosecurity" has been added to your repositories

2 $ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "falcosecurity" chart repository
...Successfully got an update from the "securecodebox" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈

3 $ kubectl create namespace falco
namespace/falco created

4 $ helm install falco falcosecurity/falco --namespace falco \
--set tty=true \
--set falcosidekick.enabled=true \
--set falcosidekick.webui.enabled=true \
--set falcosidekick.config.webhook.address="http://falco-talon:2803"
NAME: falco
LAST DEPLOYED: Wed Dec  0 19:38:38 2023
NAMESPACE: falco
STATUS: deployed
REVISION: 1
NOTES:
Falco agents are spinning up on each node in your cluster. After a few
seconds, they are going to start monitoring your containers looking for
security issues.


No further action should be requiredCode language: JavaScript (javascript)

💡ノート: Falco についてさらに詳しく知りたい場合は、 Falco 101コースをご覧ください。

Falcoルールを更新

後で、SSH サーバーにアクセスできるようにポート転送を設定します。 Falco はこれについて声高に主張する予定で、“Redirect STDOUT/STDIN to Network Connection in Container”ルールが大量にトリガーされ、Falco ログで実際に関心のあるルールを確認したり、送信したりすることが困難になります。 Talon には追加イベントがたくさんあります。 そのルールを無効にしてみましょう。

私たちが無効にしているルールを確認したい場合は、ここのFalco ルール リポジトリで見つけることができます。

1 – ルールの変更を保持する一時ファイルを作成し、そこにcustomRulesセクションを挿入します。

2 – 次に、 override.yaml を追加します。

3 – そして、Falco ルール ファイルの既存のルールをオーバーライドします。

4 – さらに、Falcoにそれを無効にしたいことを伝えます。

5 – helm を使用して Falco をアップグレードし、作成したファイルをそれにフィードして、以前に持っていた残りの値を再利用するように指示します。

6 – 最後に、既存の Falco ポッドを削除して、ルールセットでルールが無効になった新しい Falco ポッドを立ち上げます。

1 echo "customRules:" > /tmp/customrules.yaml
2 echo "  override.yaml: |-" >> /tmp/customrules.yaml
3 echo "    - rule: Redirect STDOUT/STDIN to Network Connection in Container" >> /tmp/customrules.yaml
4 echo "      enabled: false" >> /tmp/customrules.yaml

5 $ helm upgrade falco falcosecurity/falco --namespace falco --values /tmp/customrules.yaml --reuse-values
Release "falco" has been upgraded. Happy Helming!
NAME: falco
LAST DEPLOYED: Wed Dec  0 23:56:23 2023
NAMESPACE: falco
STATUS: deployed
REVISION: 2
NOTES:
Falco agents are spinning up on each node in your cluster. After a few
seconds, they are going to start monitoring your containers looking for
security issues.


No further action should be required.

6 $ kubectl delete pods -n falco -l app.kubernetes.io/name=falco
pod "falco-94wsk" deletedCode language: JavaScript (javascript)

Falco Talonをインストールする

それではFalco Talonをインストールしましょう。

1 – 現在アルファ版であるため、Talon は標準の Helm リポジトリでは公開されていません。GitHub から Talon リポジトリのクローンを作成して、helm チャートのコピーを取得します。 

2 – Talon リポジトリをざっと見てみると、その Helm チャートと、その構成を保持するいくつかの yaml ファイルが確認できます。 rules.yaml を次の一連の手順で を変更します。

3 – 次に、Talon を Falco および Sidekick とともに falco ネームスペースにhelmで簡単にインストールします。

1 git clone https://github.com/Issif/falco-talon.git /tmp/falco-talon

Cloning into '/tmp/falco-talon'...
remote: Enumerating objects: 1599, done.
remote: Counting objects: 100% (744/744), done.
remote: Compressing objects: 100% (349/349), done.
remote: Total 1599 (delta 473), reused 565 (delta 338), pack-reused 855
Receiving objects: 100% (1599/1599), 743.58 KiB | 2.81 MiB/s, done.
Resolving deltas: 100% (866/866), done.

 
2 ls /tmp/falco-talon/deployment/helm/
Chart.yaml  rules.yaml  templates  values.yaml


3 $ helm install falco-talon /tmp/falco-talon/deployment/helm --namespace falco

NAME: falco-talon
LAST DEPLOYED: Thu Dec  0 00:01:53 2023
NAMESPACE: falco
STATUS: deployed
REVISION: 1
TEST SUITE: NoneCode language: PHP (php)

Talon ルールと設定を更新する

先ほど説明したように、Talonのルールは別に設定する必要があります。今、 rules.yaml にあるものをちょっと覗いてみましょう。

1 – ファイル内の各ルールは ‘- name’  で指定されており、確認できる例がいくつかあります。

2 – これは私たちが再現したいルールに沿ったものですが、パラメータのセクションは削除できます。

1 $ cat /tmp/falco-talon/deployment/helm/rules.yaml 

- name: Rule Labelize                                                                                                                                                                     
  match:                                                                                                                                                                                  
    rules:                                                                                                                                                                                
      - Terminal shell in container                                                                                                                                                       
    output_fields:                                                                                                                                                                        
      - k8s.ns.name!=kube-system                                                                                                                                                          
  action:                                                                                                                                                                                 
    name: kubernetes:labelize                                                                                                                                                             
    parameters:                                                                                                                                                                           
      labels:                                                                                                                                                                             
        suspicious: "true"                                                                                                                                                                
- name: Rule NetworkPolicy                                                                                                                                                                
  match:                                                                                                                                                                                  
    rules:                                                                                                                                                                                
      - "Outbound Connection to C2 Servers"                                                                                                                                               
  action:                                                                                                                                                                                 
    name: kubernetes:networkpolicy                                                                                                                                                        
  before: true                                                                                                                                                                            
2 - name: Rule Terminate                                                                                                                                                                    
  match:                                                                                                                                                                                  
    rules:                                                                                                                                                                                
      - "Outbound Connection to C2 Servers"                                                                                                                                               
  action:                                                                                                                                                                                 
    name: kubernetes:terminate                                                                                                                                                            
    parameters:                                                                                                                                                                           
      ignoreDaemonsets: true                                                                                                                                                              
      ignoreStatefulsets: trueCode language: JavaScript (javascript)

これは、以前に Falco ルールを編集した方法と非常によく似た方法で機能します。

1 – 一連の行を /tmp/falco-talon/deployment/helm/rules.yamlファイルにechoします。Talonルールに名前を付け(これは任意の名前です)、どのFalcoルールとマッチさせたいかを伝え(これはFalcoルールの具体的な名前です)、マッチした場合にどのようなアクションを取らせたいかを伝える必要があります。この場合は、ポッドを終了させます。

2 – Slackアラートを設定しないので、ここでTalonチャートディレクトリのvalues.yamlの出力の1つをコメントアウトする必要があります。もしこれをしなければ、何も害はありませんが、後でTalonのログにエラーが表示されるでしょう。

3- もう一度、helmのアップグレードを行い、更新されたファイルを参照します。今回は-reuse-values引数を使ってhelmに既存の設定を残すように指示していないことに注意してください。これを行うと、 values.yaml への変更が含まれなくなります。

4 – 次に、既存のポッドをkillして更新する必要があります。

1 $ echo -e '                                                                                                                                                           ' >> /tmp/falco-talon/deployment/helm/rules.yaml

$ echo -e '- name: Sensitive file opened                                                                                                                                                             ' >> /tmp/falco-talon/deployment/helm/rules.yaml

$ echo -e '  match:                                                                                                                                                                                  ' >> /tmp/falco-talon/deployment/helm/rules.yaml

$ echo -e '    rules:                                                                                                                                                                                ' >> /tmp/falco-talon/deployment/helm/rules.yaml

$ echo -e '      - "Read sensitive file untrusted"                                                                                                                                                   ' >> /tmp/falco-talon/deployment/helm/rules.yaml

$ echo -e '  action:                                                                                                                                                                                 ' >> /tmp/falco-talon/deployment/helm/rules.yaml

$ echo -e '    name: kubernetes:terminate ' >> /tmp/falco-talon/deployment/helm/rules.yaml

2 sed -i 's/^\s*-\s*slack/ # - slack/' /tmp/falco-talon/deployment/helm/values.yaml

3 $ helm upgrade falco-talon /tmp/falco-talon/deployment/helm --namespace falco

Release "falco-talon" has been upgraded. Happy Helming!
NAME: falco-talon
LAST DEPLOYED: Thu Dec  0 00:10:28 2023
NAMESPACE: falco
STATUS: deployed
REVISION: 2
TEST SUITE: None

4 $ kubectl delete pods -n falco -l app.kubernetes.io/name=falco-talon

pod "falco-talon-5bcf97655d-gvkv9" deleted
pod "falco-talon-5bcf97655d-wxr4g" deletedCode language: JavaScript (javascript)

vcluster をインストールする

SSH サーバーを分離して実行できるように、vcluster をダウンロードしてセットアップします。

1 – ここでは、 GitHub リポジトリから最新の vcluster バージョンを取得するための環境変数を設定します。

2 – 次に、その環境変数を使用してダウンロード URL を構成します。

3 –curl を使用してファイルをダウンロードし、/usr/local/bin に移動させます。

4 – 次に、vcluster のバージョンをチェックして、すべてが正しくインストールされていることを確認しましょう。 

5 – 最後に、すべてが存在する vcluster ネームスペースを作成します。

1 $ LATEST_TAG=$(curl -s -L -o /dev/null -w %{url_effective} "https://github.com/loft-sh/vcluster/releases/latest" | rev | cut -d'/' -f1 | rev)

2 $ URL="https://github.com/loft-sh/vcluster/releases/download/${LATEST_TAG}/vcluster-linux-amd64"

3 $ curl -L -o vcluster "$URL" && chmod +x vcluster && sudo mv vcluster /usr/local/bin;
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 61.4M  100 61.4M    0     0  80.7M      0 --:--:-- --:--:-- --:--:--  194M

4 $ vcluster version
vcluster version 0.18.0

5 $ kubectl create namespace vcluster
namespace/vcluster createdCode language: JavaScript (javascript)

vcluster に SSH サーバーをインストールする

これでvclusterが使えるようになったので、目的のSSHサーバーをインストールします。

1 – まず、vcluster ネームスペースに SSH という名前の仮想クラスターを作成します。また、コンテキストを SSH クラスターに切り替えたことに注意することも重要です。 

2 – 次に、仮想クラスター内に SSH というネームスペースを作成します。

3 – SSH サーバーのチャートを取得できるように、securecodebox リポジトリを追加します。

4 – そして、簡単な更新を実行して最新のチャートを取得します。

5 – ここでは、helm を使用して、意図的に脆弱な SSH サーバーをインストールします。

6 – 最後に、vcluster から切断します。これにより、コンテキストが minikube に戻ります。

1 $ vcluster create ssh -n vcluster

05:36:45 info Detected local kubernetes cluster minikube. Will deploy vcluster with a NodePort & sync real nodes
05:36:45 info Create vcluster ssh...
05:36:45 info execute command: helm upgrade ssh /tmp/vcluster-0.18.0.tgz-1681152849 --kubeconfig /tmp/2282824298 --namespace vcluster --install --repository-config='' --values /tmp/654191707
05:36:46 done Successfully created virtual cluster ssh in namespace vcluster
05:36:46 info Waiting for vcluster to come up...
05:37:11 info Stopping docker proxy...
05:37:21 info Starting proxy container...
05:37:21 done Switched active kube context to vcluster_ssh_vcluster_minikube
- Use `vcluster disconnect` to return to your previous kube context
- Use `kubectl get namespaces` to access the vcluster

2 $ kubectl create namespace ssh
namespace/ssh created

3 $ helm repo add securecodebox https://charts.securecodebox.io/
"securecodebox" already exists with the same configuration, skipping

4 $ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "falcosecurity" chart repository
...Successfully got an update from the "securecodebox" chart repository
...Successfully got an update from the "stable" chart repository
Update Complete. ⎈Happy Helming!⎈

5 $ helm install my-dummy-ssh securecodebox/dummy-ssh --version 3.4.0 --namespace ssh \
--set global.service.type="nodePort"

NAME: my-dummy-ssh
LAST DEPLOYED: Fri Dec  0 05:38:10 2023
NAMESPACE: ssh
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Demo SSH Server deployed.

Note this should used for demo and test purposes.
Do not expose this to the Internet!

6 $ vcluster disconnect

05:38:19 info Successfully disconnected from vcluster: ssh and switched back to the original context: minikubeCode language: JavaScript (javascript)

すべてをテストしてみる

はい!これですべてが構築されました。テストしてみましょう。

前回の記事の vcluster 参照図を思い出してください。

Falco でハニーポットを構築する

これは、私たちがこの作業を通してアーキテクチャーを視覚化する際に覚えておくと役に立つでしょう。

1 – vclusterネームスペース内のポッドを見てみましょう。ここにmy-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-sshというSSHサーバーがあります。今後のためにメモしておきます。 

2 – ここでは、SSH サーバーを公開するためにポート転送を設定します。

3 – ここで、sshpass を使用してサーバーに SSH 接続し、/etc/shadow ファイルを読み取ることで、残りのイベントを開始します。 現時点ではこれを手動で行っているため、厳密には sshpass は必要ありませんが、後でこれを自動化する予定なので、そのときに必要になります。

4 – ファイルの内容を確認してみましょう。

1 $ kubectl get pods -n vcluster

NAME                                           READY   STATUS    RESTARTS   AGE
coredns-68bdd584b4-dwmms-x-kube-system-x-ssh   1/1     Running   0          4m43s
my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh      1/1     Running   0          3m42s
ssh-0                                          1/1     Running   0          5m7s

$ sleep 30

2 $ kubectl port-forward svc/"$SSH_SERVICE" 5555:22 -n vcluster & 

[1] 1196783
$ Forwarding from 127.0.0.1:5555 -> 22
Forwarding from [::1]:5555 -> 22

$ sleep 10

3 $ sshpass -p "THEPASSWORDYOUCREATED" ssh -o StrictHostKeyChecking=no -p 5555 
root@127.0.0.1 "cat /etc/shadow"

4 Handling connection for 5555
root:$6$hJ/W8Ww6$pLqyBWSsxaZcksn12xZqA1Iqjz.15XryeIEZIEsa0lbiOR9/3G.qtXl/SvfFFCTPkElo7VUD7TihuOyVxEt5j/:18281:0:99999:7:::
daemon:*:18275:0:99999:7:::
bin:*:18275:0:99999:7:::
sys:*:18275:0:99999:7:::
sync:*:18275:0:99999:7:::
games:*:18275:0:99999:7:::
man:*:18275:0:99999:7:::
lp:*:18275:0:99999:7:::
mail:*:18275:0:99999:7:::
news:*:18275:0:99999:7:::
uucp:*:18275:0:99999:7:::
proxy:*:18275:0:99999:7:::
www-data:*:18275:0:99999:7:::
backup:*:18275:0:99999:7:::
list:*:18275:0:99999:7:::
irc:*:18275:0:99999:7:::
gnats:*:18275:0:99999:7:::
nobody:*:18275:0:99999:7:::
systemd-timesync:*:18275:0:99999:7:::
systemd-network:*:18275:0:99999:7:::
systemd-resolve:*:18275:0:99999:7:::
systemd-bus-proxy:*:18275:0:99999:7:::
_apt:*:18275:0:99999:7:::
sshd:*:18281:0:99999:7:::Code language: PHP (php)

ログを確認する

SSH サーバーに対する攻撃の結果、何が起こったのかを見てみましょう。

1 – FalcoのPodを見つけ、その場所を保持するために環境変数を設定します。

2 – では、そのログを見てみましょう。冒頭のビットはFalcoが立ち上がったときのものです。ちなみに、先ほど作成したオーバーライドファイルがここに読み込まれているのがわかります。

3 – ここが重要な部分です。出力には、“Warning Sensitive file opened for reading by non-trusted program (file=/etc/shadow),” が表示されます。これは、SSH サーバーにアクセスしたときに行ったこととまったく同じです。

4 – 次に、Talon ログを見てみましょう。ここでは、Talon Podを見つけてログを取得するワンライナーをまとめます。Talon Pod が 2 つあり、必要なものはどちらにもある可能性があるため、両方からログを取得するようにします。出力が両方からインターリーブされていることがわかります。

5 – ここでは、Falco イベントが Talon に伝わっていることがわかります。 

6 – ここで、以前に作成した Talon ルールと一致しました。 

7 – これは、実行されている Talon ルールのアクションです。

1 $ FALCO_POD=$(kubectl get pods -n falco -l app.kubernetes.io/name=falco -o=jsonpath='{.items[*].metadata.name}')

2 $ kubectl logs "$FALCO_POD" -n falco

Defaulted container "falco" out of: falco, falcoctl-artifact-follow, falco-driver-loader (init), falcoctl-artifact-install (init)
Fri Dec  0 05:33:49 2023: Falco version: 0.36.2 (x86_64)
Fri Dec  0 05:33:49 2023: Falco initialized with configuration file: /etc/falco/falco.yaml
Fri Dec  0 05:33:49 2023: Loading rules from file /etc/falco/falco_rules.yaml
Fri Dec  0 05:33:49 2023: Loading rules from file /etc/falco/rules.d/override.yaml
Fri Dec  0 05:33:49 2023: The chosen syscall buffer dimension is: 8388608 bytes (8 MBs)
Fri Dec  0 05:33:49 2023: Starting health webserver with threadiness 4, listening on port 8765
Fri Dec  0 05:33:49 2023: Loaded event sources: syscall
Fri Dec  0 05:33:49 2023: Enabled event sources: syscall
Fri Dec  0 05:33:49 2023: Opening 'syscall' source with Kernel module

<snip>

3 {"hostname":"falco-wchsq","output":"18:39:24.133546875: Warning Sensitive file opened for reading by non-trusted program (file=/etc/shadow gparent=sshd ggparent=containerd-shim gggparent=<NA> evt_type=open user=root user_uid=0 user_loginuid=0 process=cat proc_exepath=/bin/cat parent=sshd command=cat /etc/shadow terminal=0 exe_flags=O_RDONLY container_id=0f044393375b container_image=securecodebox/dummy-ssh container_image_tag=v1.0.0 container_name=k8s_dummy-ssh_my-dummy-ssh-7955bc99c8-mxshb-x-ssh-x-ssh_vcluster_e10eeedf-7ad2-4a7e-8b73-b7713d6537da_0 k8s_ns=vcluster k8s_pod_name=my-dummy-ssh-7955bc99c8-mxshb-x-ssh-x-ssh)","priority":"Warning","rule":"Read sensitive file untrusted","source":"syscall","tags":["T1555","container","filesystem","host","maturity_stable","mitre_credential_access"],"time":"2023-12-08T18:39:24.133546875Z", "output_fields": {"container.id":"0f044393375b","container.image.repository":"securecodebox/dummy-ssh","container.image.tag":"v1.0.0","container.name":"k8s_dummy-ssh_my-dummy-ssh-7955bc99c8-mxshb-x-ssh-x-ssh_vcluster_e10eeedf-7ad2-4a7e-8b73-b7713d6537da_0","evt.arg.flags":"O_RDONLY","evt.time":43012267506,"evt.type":"open","fd.name":"/etc/shadow","k8s.ns.name":"vcluster","k8s.pod.name":"my-dummy-ssh-7955bc99c8-mxshb-x-ssh-x-ssh","proc.aname[2]":"sshd","proc.aname[3]":"containerd-shim","proc.aname[4]":null,"proc.cmdline":"cat /etc/shadow","proc.exepath":"/bin/cat","proc.name":"cat","proc.pname":"sshd","proc.tty":0,"user.loginuid":0,"user.name":"root","user.uid":0}}

<snip>

4 $ kubectl get pods -n falco -l app.kubernetes.io/name=falco-talon -o=jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' | xargs -I {} kubectl logs {} -n falco

2023-12-00T05:33:41Z INF init action_category=kubernetes
2023-12-00T05:33:41Z INF init notifier=k8sevents
2023-12-00T05:33:41Z INF init notifier=slack
2023-12-00T05:33:41Z INF init result="4 rules have been successfully loaded"
2023-12-00T05:33:41Z INF init result="watch of rules enabled"
2023-12-00T05:33:41Z INF init result="Falco Talon is up and listening on 0.0.0.0:2803"
5 2023-12-00T05:44:46Z INF event output="05:44:46.118305822: Warning Sensitive file opened for reading by non-trusted program (file=/etc/shadow gparent=sshd ggparent=containerd-shim gggparent=<NA> evt_type=open user=root user_uid=0 user_loginuid=0 process=cat proc_exepath=/bin/cat parent=sshd command=cat /etc/shadow terminal=0 exe_flags=O_RDONLY container_id=1536aa9c45c2 container_image=securecodebox/dummy-ssh container_image_tag=v1.0.0 container_name=k8s_dummy-ssh_my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh_vcluster_21bdc319-5566-41ee-8a64-d8b7628e5937_0 k8s_ns=vcluster k8s_pod_name=my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh)" priority=Warning rule="Read sensitive file untrusted" source=syscall trace_id=79db4b47-0112-4a22-8068-e171702e018a
6 2023-12-00T05:44:46Z INF match action=kubernetes:terminate rule="Sensitive file opened" trace_id=79db4b47-0112-4a22-8068-e171702e018a
7 2023-12-00T05:44:46Z INF action Namespace=vcluster Pod=my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh action=kubernetes:terminate event="05:44:46.118305822: Warning Sensitive file opened for reading by non-trusted program (file=/etc/shadow gparent=sshd ggparent=containerd-shim gggparent=<NA> evt_type=open user=root user_uid=0 user_loginuid=0 process=cat proc_exepath=/bin/cat parent=sshd command=cat /etc/shadow terminal=0 exe_flags=O_RDONLY container_id=1536aa9c45c2 container_image=securecodebox/dummy-ssh container_image_tag=v1.0.0 container_name=k8s_dummy-ssh_my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh_vcluster_21bdc319-5566-41ee-8a64-d8b7628e5937_0 k8s_ns=vcluster k8s_pod_name=my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh)" rule="Sensitive file opened" status=success trace_id=79db4b47-0112-4a22-8068-e171702e018a
2023-12-00T05:44:46Z INF notification action=kubernetes:terminate notifier=k8sevents rule="Sensitive file opened" status=success trace_id=79db4b47-0112-4a22-8068-e171702e018a
2023-12-00T05:33:41Z INF init action_category=kubernetes
2023-12-00T05:33:41Z INF init notifier=k8sevents
2023-12-00T05:33:41Z INF init notifier=slack
2023-12-00T05:33:41Z INF init result="4 rules have been successfully loaded"
2023-12-00T05:33:41Z INF init result="watch of rules enabled"
2023-12-00T05:33:41Z INF init result="Falco Talon is up and listening on 0.0.0.0:2803"Code language: HTML, XML (xml)

さて、クラスターを覗いて、私たちの努力の結果何が起こったのか見てみましょう。前に述べたように、SSH サーバー Podの名前は、 my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh でした。

1 – vclusterネームスペースからPodを再度取得してみましょう。SSHサーバーのポッド名はmy-dummy-ssh-7955bc99c8-k8jgl-x-ssh-x-sshです。成功です!

2 – vclusterネームスペースのイベントを見て、my-dummy-sshをgrepして、気になる部分を探します。。

3 – ここでは、新しい SSH サーバー ポッドが、 my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh 起動していることがわかります。

4 – 所有しているPod my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh がKillされているのがわかります。

1 $ kubectl get pods -n vcluster

NAME                                           READY   STATUS    RESTARTS   AGE
coredns-68bdd584b4-dwmms-x-kube-system-x-ssh   1/1     Running   0          9m11s
my-dummy-ssh-7955bc99c8-k8jgl-x-ssh-x-ssh      1/1     Running   0          95s
ssh-0                                          1/1     Running   0          9m35s

2 $ kubectl get events -n vcluster | grep my-dummy-ssh

113s        Normal    falco-talon:kubernetes:terminate:success   pod/my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh      Status: success...
113s        Normal    Scheduled                                  pod/my-dummy-ssh-7955bc99c8-k8jgl-x-ssh-x-ssh      Successfully assigned vcluster/my-dummy-ssh-7955bc99c8-k8jgl-x-ssh-x-ssh to minikube
112s        Normal    Pulled                                     pod/my-dummy-ssh-7955bc99c8-k8jgl-x-ssh-x-ssh      Container image "docker.io/securecodebox/dummy-ssh:v1.0.0" already present on machine
112s        Normal    Created                                    pod/my-dummy-ssh-7955bc99c8-k8jgl-x-ssh-x-ssh      Created container dummy-ssh
3 112s        Normal    Started                                    pod/my-dummy-ssh-7955bc99c8-k8jgl-x-ssh-x-ssh      Started container dummy-ssh
8m28s       Normal    Scheduled                                  pod/my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh      Successfully assigned vcluster/my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh to minikube
8m27s       Normal    Pulling                                    pod/my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh      Pulling image "docker.io/securecodebox/dummy-ssh:v1.0.0"
8m18s       Normal    Pulled                                     pod/my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh      Successfully pulled image "docker.io/securecodebox/dummy-ssh:v1.0.0" in 9.611s (9.611s including waiting)
8m17s       Normal    Created                                    pod/my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh      Created container dummy-ssh
8m16s       Normal    Started                                    pod/my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh      Started container dummy-ssh
4 113s        Normal    Killing                                    pod/my-dummy-ssh-7955bc99c8-mwqxg-x-ssh-x-ssh      Stopping container dummy-sshCode language: PHP (php)

そして、最初から最後まで完成しました。私たちが行ったことは次のとおりです。

  • SSHサーバーポッドを攻撃しました
  • Falco の ‘Sensitive file opened for reading by non-trusted program’ ルールが適用される
  • Falcosidekick から Falco Talon への Webhook を使用してイベントを送信しました
  • Falco Talon の‘Sensitive file opened’ルールをトリップしました
  • 問題のあるPodをターミネートしました

そして今、少しだけ自動化が進んでいます

上記のすべては、かなりの数の可動部分でした。これらすべてをスクリプトを実行するだけで実行できたら便利だと思いませんか? はい、そうです。幸いなことに、私たちはまさにそれを行うことができます。

Sysdig TRT GitHub リポジトリで、minhoney.sh ファイルをプルダウンします。実行可能に設定するとよいでしょう。ハニーポットを起動するには、–buildit 引数を指定してスクリプトを実行するだけです。

$ ./minhoney.sh --buildit

すべてを元に戻すには、-burnit 引数を指定してスクリプトを再度実行します。

<code>$ ./minhoney.sh --burnit</code>Code language: HTML, XML (xml)
ノート: –burnit を指定して実行すると、スクリプトは今後の実行で問題を引き起こす可能性のあるもののクリーンアップを試みます。Helm 内のすべてをアンインストールし、minikube 内のすべてを強制終了し、現在のユーザーが削除権限を持つ /tmp からすべてを削除します。この特定の目的のために構築されたシステムまたはインスタンス以外でこれを実行することはお勧めできません。私たちがあなたに忠告しなかったとは言わないでくださいね、私たちはあなたに完全に忠告したのですから。  

(今のところは) 以上です

一歩下がって、これまで説明してきたことをすべて確認してみると、始めから最後まで次のようになります。

Falco でハニーポットを構築する
  • SSHサーバー Podを攻撃する
  • Falco で ‘Sensitive file open for reading by untrusted program’ ルールを有効にする
  • Falcosidekick から Falco Talon への Webhook を使用してイベントを送信しました
  • Falco Talonで ‘Sensitive file open’ ルールを有効にしました
  • 問題のあるPodをターミネートしました

このシリーズの次のパートでは、これにいくつかの追加要素を加えます。ロギングとアラート、そしてすべてをセットアップするための自動化を追加します。また、攻撃対象をいくつか追加して規模を拡大していきます。

基本に関する前回のエピソードについては、「 vcluster と Falco を使用したハニーポットの構築: エピソード I 」を参照してください。