vclusterとFalcoでハニーポットを構築する:エピソード1

By 清水 孝郎 - OCTOBER 4, 2022

SHARE:

Output AWS command

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

ハニーポットは、高いレベルでは、正当なアクセスから攻撃者の注意をそらすため、または攻撃者の活動に関する情報を収集するために、攻撃者を誘い出すためのメカニズムです。ここでは、vlcusterとFalcoを使ったハニーポットの小さな例をビルドしていきます。

kubernetes honeypot vcluster Falco
この最初のエピソードでは、ランタイム侵入検知のためにvclusterとFalcoを使用して簡単なSSHハニーポットを構築する方法について説明します。

なぜハニーポットなのか?

ハニーポットは、アプリケーション、システム、ネットワーク、IoTデバイス、SCADAコンポーネントなど、ほとんどあらゆる種類のデジタル資産をモデル化できます。ハニートークンは計測された単一ファイルを表し、ハニーネットは複数のシステムとインフラストラクチャーからなる広大なネットワークを表すなど、その複雑さは多岐にわたります。

そのため、ハニーポットは情報収集に非常に有効であり、ブルーチームやセキュリティリサーチャーが攻撃者のツール、テクニック、手順(TTP)を知る窓となるだけでなく、さまざまなセキュリティツールに供給する侵害の指標(IoC)の基礎となる情報を提供することができます。

ハニーポットを分類する方法の1つに、複雑さのレベルによるものがあります。

相互作用の大きいハニーポットと小さいハニーポット

低相互作用ハニーポットは、ハニーポット界のアヒルのおとりです。実行するために多くのリソースを必要としませんが、一般的に綿密な検査には耐えられません。標準的なポートで比較的現実的なバナー・メッセージで応答するような簡単なことはするかもしれませんが、通常、できることはこの程度です。ポートやサービスのスキャンで表示されたとき、攻撃者は一時的に興味を持つかもしれませんが、それ以外の反応がないため、長くは続かないでしょう。さらに、相互作用の少ないハニーポットは、攻撃者が本当に対話できる攻撃対象が少ないため、攻撃者が何をしているのかあまり見えてきません。

相互作用の低いハニーポットがアヒルのおとりなら、相互作用の高いハニーポットは本当のアヒルです。攻撃者をおびき寄せるにはこちらの方がずっと良いのですが、アヒルを失う可能性もあります。相互作用の高いハニーポットは、実際のアプリケーションを実行している実際のシステムで構成されていることが多く、攻撃者が何をしているかを詳細に追跡できるように計測されています。これにより、連鎖的なエクスプロイトなど、より複雑な活動の全容を把握できるほか、アップロードされたツールやバイナリ、使用されたクレデンシャルなどのコピーを入手することができます。これらは情報収集の観点からは素晴らしいことですが、攻撃者の手に本当に資産を直接渡してしまうわけですから、その資産を使って何を行っているかを注意深く監視する必要があります。

相互作用の大きいハニーポットにおける主な課題の1つは、攻撃者を他の環境から隔離することです。Kubernetesなどのコンテナ化ツールを使って構築されたハニーポットの場合、ハニーポットを本当に実行しているクラスタの部分と、それを監視・維持するための関連機器から攻撃者を慎重に遠ざけておく必要があります。これは困難なことであり、攻撃者がアクセスできるように公開できるものを制限せざるを得ないこともあります。攻撃者がクラスター自体またはインストルメンテーションを標的にするために使用できるものはすべて除外するか、不要な改ざんが発生しないように回避策を講じる必要があります。

仮想クラスターによるレスキュー

仮想クラスターは、ホストのKubernetesクラスターの上で動作するKubernetesクラスターです。複数の仮想クラスターをそれぞれ別の環境で動作させ、他の仮想クラスターやホストクラスターに到達できないようにすることが可能です。

仮想クラスターは独自の隔離された空間の中で動作しているため、攻撃者はホストクラスター上で動作している「本物」の同等物を目にしないため、その内部に非常に機密性の高いアイテムを露出することができます。このようにして、攻撃者がハニーポット自体を破壊することを心配することなく、Kubernetesインフラの要素やメンテナンスツールなどを公開することができるのです。

vcluster architecture
vclusterとは – アーキテクチャー

このために使える仮想クラスタープロジェクトはいくつかありますが、現在vclusterが最も洗練され、よくサポートされています。vclusterの人々はとてもフレンドリーで親切です。ぜひ彼らのSlackに立ち寄って挨拶してください!

vclusterのハニーポットをビルドしよう

vlcusterを使ったハニーポットの小さな例をビルドするつもりです。これは意図的にシンプルな例ですが、将来やりたいかもしれないいじり方のための良い基礎を提供してくれます。

このデモを実現するためには、以下のバージョンのツールが最低限必要です:

  • Minikube v1.26.1
  • Helm v3.9.2
  • kubectl v1.25.0
  • vcluster 0.11.2

vclusterハニーポットとFalcoのインストールをステップバイステップで行います

まず、vclusterのバイナリをインストールしますが、これは非常に簡単な作業です。

$ curl -s -L "https://github.com/loft-sh/vcluster/releases/latest" | sed -nE 's!.*"([^"]*vcluster-linux-amd64)".*!https://github.com\1!p' | xargs -n 1 curl -L -o vcluster && chmod +x vcluster;
1 curl -L -o vcluster && chmod +x vcluster;
  % 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 36.8M  100 36.8M    0     0  10.4M      0  0:00:03  0:00:03 --:--:-- 11.2M
$ sudo mv vcluster /usr/local/bin;
$ vcluster version
vcluster version 0.11.2

ローカルKubernetesクラスターをプロビジョニングする

Kubernetesクラスターをプロビジョニングするには、さまざまな方法があります。この例では、minikubeを使用します。

注意:
ここでは、minikube用のvirtualbox、qemu、またはkvm2ドライバーを使用できますが、
noneドライバーは使用できません。Falcoは、noneを使用しようとすると、後でドライバー
を正しくデプロイすることができなくなります。

さらに、virtualboxドライバーを使用しているため、これを実際のハードウェア上にデプロイする必要があります。これはVMの中やEC2インスタンスなどでは動きません。
クラスターをプロビジョニングしてみましょう。startコマンドを実行すると、minikubeがビルドを行う間、1〜2分ほど実行されます。

$ minikube start --vm-driver=virtualbox
😄  minikube v1.26.1 on Ubuntu 22.04
✨  Using the virtualbox driver based on user configuration
👍  Starting control plane node minikube in cluster minikube
🔥  Creating virtualbox VM (CPUs=2, Memory=6000MB, Disk=20000MB) ...
🐳  Preparing Kubernetes v1.24.3 on Docker 20.10.17 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🔎  Verifying Kubernetes components...
🌟  Enabled addons: storage-provisioner
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

Falcoでハニーポットをインストゥルメント化する

次に、Falcoをインストールします。

$ helm repo add falcosecurity https://falcosecurity.github.io/charts
"falcosecurity" has been added to your repositories
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "falcosecurity" chart repository
Update Complete. ⎈Happy Helming!⎈
$ helm upgrade --install falco --set driver.loader.initContainer.image.tag=master --set driver.loader.initContainer.env.DRIVER_VERSION="2.0.0+driver" --set tty=true --namespace falco --create-namespace falcosecurity/falco
Release "falco" does not exist. Installing it now.
NAME: falco
LAST DEPLOYED: Thu Sep  8 15:32:45 2022
NAMESPACE: falco
STATUS: deployed
REVISION: 1
TEST SUITE: None
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.
Tip: 
You can easily forward Falco events to Slack, Kafka, AWS Lambda and more with falcosidekick. 
Full list of outputs: https://github.com/falcosecurity/charts/tree/master/falcosidekick.
You can enable its deployment with `--set falcosidekick.enabled=true` or in your values.yaml. 
See: https://github.com/falcosecurity/charts/blob/master/falcosidekick/values.yaml for configuration values.

Falco Podはスピンアップに1分ほどかかります。kubectl を使って状態を確認し、ログを見ることで、すべてがスムーズに進んだことを確認することができます:

$ kubectl get pods -n falco -o wide
NAME          READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
falco-zwfcj   1/1     Running   0          73s   172.17.0.3   minikube   <none>           <none>
$ kubectl logs falco-zwfcj -n falco
Defaulted container "falco" out of: falco, falco-driver-loader (init)
Thu Sep  8 22:32:47 2022: Falco version 0.32.2
Thu Sep  8 22:32:47 2022: Falco initialized with configuration file /etc/falco/falco.yaml
Thu Sep  8 22:32:47 2022: Loading rules from file /etc/falco/falco_rules.yaml:
Thu Sep  8 22:32:47 2022: Loading rules from file /etc/falco/falco_rules.local.yaml:
Thu Sep  8 22:32:48 2022: Starting internal webserver, listening on port 8765

すべてを組み合わせて仮想クラスターを作成する

次に、ホストクラスターにvclusterが住むためのネームスペースを作成し、そこにvclusterをデプロイする必要があります。

$ kubectl create namespace vcluster
namespace/vcluster created
$ vcluster create ssh -n vcluster
info   Detected local kubernetes cluster minikube. Will deploy vcluster with a NodePort & sync real nodes
info   Create vcluster ssh...
info   execute command: helm upgrade ssh https://charts.loft.sh/charts/vcluster-0.11.2.tgz --kubeconfig /tmp/3673995455 --namespace vcluster --install --repository-config='' --values /tmp/641812157
done √ Successfully created virtual cluster ssh in namespace vcluster
info   Waiting for vcluster to come up...
warn   vcluster is waiting, because vcluster pod ssh-0 has status: ContainerCreating
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

SSH ハニーポットターゲットをインストールする

vclusterがインスタンス化されたので、その中に意図的に安全でないsshサーバーを作成して、ハニーポットのターゲットとして使用します。これは、以前、EC2上のSSHを安全にするで紹介したものです。

ここでは、ターゲットとして使用するために、sourcecodebox.ioから意図的に安全でないsshサーバーのhelm chartをデプロイすることにします。このサーバーの認証情報は、root/THEPASSWORDYOUCREATEDです。

$ helm repo add securecodebox https://charts.securecodebox.io/
"securecodebox" has been added to your repositories
$ 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
Update Complete. ⎈Happy Helming!⎈
$ helm install my-dummy-ssh securecodebox/dummy-ssh --version 3.14.3
NAME: my-dummy-ssh
LAST DEPLOYED: Thu Sep  8 15:53:15 2022
NAMESPACE: default
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!

異なるコンテキストを検証する

さて、vclusterの中で何かが動いています。2つの異なるcontextを見てみましょう。
注意:
Kubernetes のコンテキストは、特定のクラスターへのアクセス方法を定義する一連の
パラメーターです。 コンテキストを切り替えると、kubectl などのコマンドで行うすべて
の操作がクラスター間で変更されます。

まず、現在のvclusterパースペクティブを使って、クラスターに存在するすべてのリソースを見てみましょう。

$ kubectl get all --all-namespaces
NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE
kube-system   pod/coredns-6ffcc6b58-h7zwx        1/1     Running   0          m26s
default       pod/my-dummy-ssh-f98c68f95-vwns   1/1     Running   0          m1s
NAMESPACE     NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
default       service/kubernetes     ClusterIP   10.96.112.178   <none>        443/TCP                  m26s
kube-system   service/kube-dns       ClusterIP   10.97.196.120   <none>        53/UDP,53/TCP,9153/TCP   m26s
default       service/my-dummy-ssh   ClusterIP   10.99.109.0     <none>        22/TCP                   m1s
NAMESPACE     NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/coredns        1/1     1            1           m26s
default       deployment.apps/my-dummy-ssh   1/1     1            1           m1s
NAMESPACE     NAME                                      DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/coredns-6ffcc6b58        1         1         1       m26s
default       replicaset.apps/my-dummy-ssh-f98c68f95   1         1         1       m1s

Kubernetesの通常のインフラストラクチャーと、my-dummy-sshのPodとサービスがデフォルトのネームスペースで稼働していることが確認できます。Falco はホストクラスターにインストールされており、vcluster 内からは見えないため、Falco のリソースは表示されないことに注意してください。

次に、vcluster から切断することで、コンテキストを切り替えてみましょう。これで、ホストクラスターのコンテキストに戻ることができます。

$ vcluster disconnect
info   Successfully disconnected from vcluster: ssh and switched back to the original context: minikube

ここで、kubectlで再度すべてのリソースを表示してみましょう。

$ kubectl get all --all-namespaces
NAMESPACE     NAME                                                READY   STATUS    RESTARTS   AGE
falco         pod/falco-zwfcj                                     1/1     Running   0          5m
kube-system   pod/coredns-d4b75cb6d-ttwdl                        1/1     Running   0          4m
kube-system   pod/etcd-minikube                                   1/1     Running   0          4m
kube-system   pod/kube-apiserver-minikube                         1/1     Running   0          4m
kube-system   pod/kube-controller-manager-minikube                1/1     Running   0          4m
kube-system   pod/kube-proxy-dhg9v                                1/1     Running   0          4m
kube-system   pod/kube-scheduler-minikube                         1/1     Running   0          4m
kube-system   pod/storage-provisioner                             1/1     Running   0          4m
vcluster      pod/coredns-6ffcc6b58-h7zwx-x-kube-system-x-ssh    1/1     Running   0          1m
vcluster      pod/my-dummy-ssh-f98c68f95-vwns-x-default-x-ssh   1/1     Running   0          5m
vcluster      pod/ssh-0                                           2/2     Running   0          1m
NAMESPACE     NAME                                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
default       service/kubernetes                     ClusterIP   10.96.0.1       <none>        443/TCP                  4m
kube-system   service/kube-dns                       ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   4m
vcluster      service/kube-dns-x-kube-system-x-ssh   ClusterIP   10.97.196.120   <none>        53/UDP,53/TCP,9153/TCP   1m
vcluster      service/my-dummy-ssh-x-default-x-ssh   ClusterIP   10.99.109.0     <none>        22/TCP                   5m
vcluster      service/ssh                            NodePort    10.96.112.178   <none>        443:31530/TCP            1m
vcluster      service/ssh-headless                   ClusterIP   None            <none>        443/TCP                  1m
vcluster      service/ssh-node-minikube              ClusterIP   10.102.36.118   <none>        10250/TCP                1m
NAMESPACE     NAME                        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
falco         daemonset.apps/falco        1         1         1       1            1           <none>                   5m
kube-system   daemonset.apps/kube-proxy   1         1         1       1            1           kubernetes.io/os=linux   4m
NAMESPACE     NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
kube-system   deployment.apps/coredns   1/1     1            1           4m
NAMESPACE     NAME                                 DESIRED   CURRENT   READY   AGE
kube-system   replicaset.apps/coredns-d4b75cb6d   1         1         1       4m
NAMESPACE   NAME                   READY   AGE
vcluster    statefulset.apps/ssh   1/1     1m

これで、Falcoのリソースと、sshインストールで同期したリソースが確認できます。今回は、ホストクラスター上に作成したvclusterネームスペースで実行されていることが確認できます。

ハニーポットをテストする

さて、これですべて揃いました。ハニーポットターゲットでFalcoのルールをトリガーさせるために何かを行い、これまでのところすべてがどのように動作するかを見てみましょう。

実際の侵入をシミュレートする最も便利な方法は、3つの異なるターミナルウィンドウを使用することです。

ターミナル1

ターミナル 1 では、ローカルマシンに ssh サーバーを公開するために、ポートフォワードをセットアップします。sshサービスを公開するために、テスト中はこのターミナルを開いたままにしておく必要があります。

kubectl port-forward svc/my-dummy-ssh 5555:22

このコマンドは、サービスを127.0.0.1、ポート5555で公開します。このウィンドウでは、vcluster コンテキストで実行されていることを確認する必要があります。ホストクラスターのコンテキストで実行している場合は、vcluster connect ssh -n vclusterコマンドを実行することで切り替えが可能です。

$ kubectl port-forward svc/my-dummy-ssh 5555:22
Forwarding from 127.0.0.1:5555 -> 22
Forwarding from [::1]:5555 -> 22

ターミナル2

このターミナルでは、先ほど公開したサービスに 5555 番ポートで ssh します。認証情報はroot/THEPASSWORDYOUCREATEDです。

$ ssh -p 5555 [email protected]
The authenticity of host '[127.0.0.1]:5555 ([127.0.0.1]:5555)' can't be established.
ED25519 key fingerprint is SHA256:eLwgzyjvrpwDbDr+pDbIfUhlNANB4DPH9/0w1vGa87E.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[127.0.0.1]:5555' (ED25519) to the list of known hosts.
[email protected]'s password: 
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 5.10.57 x86_64)
 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

sshでログインした後、Falcoのルールをトリガーするようなことをしたいと思います。例えば、/etc/shadowを見ると、ヒットするはずです。

root@my-dummy-ssh-7f98c68f95-5vwns:~# cat /etc/shadow
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:::
<snip>

ターミナル3

このターミナルでは、Falco Podのログを表示します。

$ kubectl logs falco-zwfcj -n falco
23:22:26.726981623: Notice Redirect stdout/stdin to network connection (user=root user_loginuid=-1 k8s.ns=vcluster k8s.pod=my-dummy-ssh-7f98c68f95-5vwns-x-default-x-ssh container=cffc68f50e06 process=sshd parent=sshd cmdline=sshd -D terminal=0 container_id=cffc68f50e06 image=securecodebox/dummy-ssh fd.name=172.17.0.1:40312->172.17.0.6:22 fd.num=1 fd.type=ipv4 fd.sip=172.17.0.6)
23:22:27.709831799: Warning Sensitive file opened for reading by non-trusted program (user=root user_loginuid=0 program=cat command=cat /etc/shadow file=/etc/shadow parent=bash gparent=sshd ggparent=sshd gggparent=<NA> container_id=cffc68f50e06 image=securecodebox/dummy-ssh) k8s.ns=vcluster k8s.pod=my-dummy-ssh-7f98c68f95-5vwns-x-default-x-ssh container=cffc68f50e06

ここで、ポート転送の結果、Notice Redirect stdout/stdin to network connectionルールのエントリーが多数表示されます。しかし、/etc/shadow を覗き見した結果、「信頼できないプログラムによって読み取られるために開かれた機密ファイル」という警告ルールが発せられたことも確認できるはずです。

Falco detects inside container inside honeypotFalcoは、ハニーポット内のコンテナ内を検出する

ほら! これは、ターゲットへのssh接続を介して、vclusterクラスターの内部とホストクラスターの内部で、私たちがしてはならないことに手を出しているのをFalcoがキャッチしているのです。

すべてを焼き尽くす

Falcoとsshサーバーをアンインストールし、minikubeをクリーンアウトし、後でつまずくかもしれないいくつかの一時ファイルを整理してください。

$ helm delete falco --namespace falco; helm delete my-dummy-ssh --namespace default; minikube delete --all -purge; sudo rm /tmp/juju*
release "falco" uninstalled
release "my-dummy-ssh" uninstalled
🔥  Deleting "minikube" in virtualbox ...
💀  Removed all traces of the "minikube" cluster.
🔥  Successfully deleted all profiles
[sudo] password for user:

しかし、待ってください、まだあります!

仮想クラスターは、ハニーポットや一般的なセキュリティリサーチでの利用が期待されています。今後の展開と、技術産業がこれらのツールをどのように利用するかという点で、エキサイティングな分野であることは間違いないでしょう。

ここでビルドしたものは良いスタートですが、さらに磨きをかけ、強化できる興味深いものがたくさんあります。

このシリーズの次のパートでは、Falco Sidekickを使用したレスポンスエンジンを追加し、2番目の仮想クラスターのハニーポットビットを増やし、vclusterの設定を微調整してより安全にする予定ですので、ご期待ください。