birabiraのめも

忘れっぽいのでここにメモをしていきます

Kubernetes(Kind)を使ってArgoCDからECK(Elastic Cloud on Kubernetes)デプロイしてみる

はじめに

少し前からKuberenetes入門しなければという使命感はあったものの、日常が忙しくどうしても入門できていなかったがやっと入門したので記録として残していきたいと思う。

今回は、KubernetesをDockerコンテナとして構築できるKindというツールを使って構築し、ArgoCDを使ってGithub上にあるリポジトリから構成を読んでECKをデプロイします。

いわゆるGitOpsでやっていきたい。

先週入門したばっかりなので、説明が間違っていたり設定が足りない部分があるかと思うがそこはご容赦いただきたい。

今回とりあえず構築まではできたので、Kuberenetesのスケーラビリティとか色々体感したい~。

Kind

説明は公式を読んでもらったほうが早いと思うので。

kind.sigs.k8s.io

ArgoCD

Kubernetesで動かすことで、Gitのリポジトリ上に保存しているマニフェストファイルを監視して、変更があればKuberenetesにデプロイすることができる。すごい。

↓詳細はこちらを読んでもらったほうがいいと思う

tech-lab.sios.jp

ECK

Kubernetes上で動かすように構成されたElasticsearchとKibana。まだテクニカルプレビューであるものの、BeatsやFleetなども対応している。

基本的には、Kubernetesマニフェストファイルをデプロイすることができるが、パッケージマネージャーであるHelmでのデプロイにも対応している。

↓公式サイト

www.elastic.co

Github

github.com

構築

早速構築していきます。

  • OS: Rocky Linux release 9.4 (Blue Onyx)
  • RAM: 16GB
  • CPU: 4 core
  • IP: 192.168.2.143

また、hostsの編集でもいいので次の通りIPが引けるようにしておく。

  • argocd.bira.local: 192.168.2.143
  • kibana.bira.local: 192.168.2.143

netcatインストール

ログ取り込みテストに使います。

dnf install nc

Dockerのインストール

kindでDockerを使うため、Dokcerをインストールします。

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl start docker.service
sudo systemctl enable docker.service

hello-worldして表示されればOKです。

[root@asdf ~]# docker run --rm hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c1ec31eb5944: Pull complete
Digest: sha256:a26bff933ddc26d5cdf7faa98b4ae1e3ec20c4985e6f87ac0973052224d24302
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

[root@asdf ~]#

kubectlのインストール

Kubernetesをいじるためのコマンド。

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

バージョンが出ればOK

[root@asdf ~]# kubectl version --client
Client Version: v1.30.0
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3

kubernetes.io

helmのインストール

Kubernetesのパッケージマネージャのようです。

curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash

help出ればOK

[root@asdf ~]# helm help
The Kubernetes package manager

Common actions for Helm:

- helm search:    search for charts
- helm pull:      download a chart to your local directory to view
- helm install:   upload the chart to Kubernetes
- helm list:      list releases of charts

(省略)

ついでにリポジトリも追加しておきましょう。

[root@asdf ~]# helm repo add argo https://argoproj.github.io/argo-helm
"argo" has been added to your repositories

kindのインストール

コンパイル済みバイナリを持ってくるのが一番楽でした。どうせ検証なので。

[ $(uname -m) = x86_64 ] && curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.22.0/kind-linux-amd64
chmod +x ./kind
mv ./kind /usr/local/sbin/kind

kind.sigs.k8s.io

コマンドが打てればOKです。

[root@asdf ~]# kind --help
kind creates and manages local Kubernetes clusters using Docker container 'nodes'

Usage:
  kind [command]

Available Commands:
  build       Build one of [node-image]
  completion  Output shell completion code for the specified shell (bash, zsh or fish)
  create      Creates one of [cluster]
  delete      Deletes one of [cluster]
  export      Exports one of [kubeconfig, logs]
  get         Gets one of [clusters, nodes, kubeconfig]
  help        Help about any command
  load        Loads images into nodes
  version     Prints the kind CLI version

Flags:
  -h, --help              help for kind
      --loglevel string   DEPRECATED: see -v instead
  -q, --quiet             silence all stderr output
  -v, --verbosity int32   info log verbosity, higher value produces more output
      --version           version for kind

Use "kind [command] --help" for more information about a command.

kindを使ったKubernetesの構築

適当に設定したうえで構築していきます。

[root@asdf ~]# cat >./kind-config.yaml <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 31111
    hostPort: 31111
    protocol: TCP
  - containerPort: 80
    hostPort: 80
    protocol: TCP
  - containerPort: 443
    hostPort: 443
    protocol: TCP
- role: worker
- role: worker
EOF

[root@asdf ~]# kind create cluster --name kind --config ./kind-config.yaml
Creating cluster "kind" ...
 ✓ Ensuring node image (kindest/node:v1.29.2) 🖼
 ✓ Preparing nodes 📦 📦 📦
 ✓ Writing configuration 📜
 ✓ Starting control-plane 🕹️
 ✓ Installing CNI 🔌
 ✓ Installing StorageClass 💾
 ✓ Joining worker nodes 🚜
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community 🙂

Dockerのコンテナが作られていればOK

[root@asdf ~]# sudo docker ps
CONTAINER ID   IMAGE                  COMMAND                  CREATED              STATUS          PORTS                                                                                           NAMES
86ec8bc836f7   kindest/node:v1.29.2   "/usr/local/bin/entr…"   About a minute ago   Up 59 seconds   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:31111->31111/tcp, 127.0.0.1:34729->6443/tcp   kind-control-plane
a2f1e0ce946a   kindest/node:v1.29.2   "/usr/local/bin/entr…"   About a minute ago   Up 59 seconds                                                                                                   kind-worker
3ef2f4254e3a   kindest/node:v1.29.2   "/usr/local/bin/entr…"   About a minute ago   Up 59 seconds                                                                                                   kind-worker2

今回作られたDockerの各コンテナはコントロールプレーンとノードと呼ばれるもの。本来3台に分けられるものを、コンテナとして作ってるっぽい。

kubernetes.io

Docker上で動いている都合上、いくつかポートが転送されています。これも後ほど使います。

Ingress Controllerのインストール

Kubernetes内のService(Podの集まり)に対してクラスタ外からの接続性を提供するヤツらしいです。HTTPとHTTPSのみですが、負荷分散等の機能がついているそうです。

今回は、ArgoCDとKibanaへのアクセスをこいつで設定してやります。

Ingress Controllerはあくまでもコントローラーのようですので、実設定は各マニフェスト側でやるようです。

[root@asdf ~]# kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml

namespace/ingress-nginx created
serviceaccount/ingress-nginx created
serviceaccount/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
configmap/ingress-nginx-controller created
service/ingress-nginx-controller created
service/ingress-nginx-controller-admission created
deployment.apps/ingress-nginx-controller created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
ingressclass.networking.k8s.io/nginx created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created

一通り、podが動いていればOK。それまで必ず待つこと。

[root@asdf ~]# kubectl get pods -A
NAMESPACE            NAME                                         READY   STATUS      RESTARTS   AGE
ingress-nginx        ingress-nginx-admission-create-d9gfx         0/1     Completed   0          3m16s
ingress-nginx        ingress-nginx-admission-patch-c44mf          0/1     Completed   2          3m16s
ingress-nginx        ingress-nginx-controller-7b76f68b64-ngt5q    1/1     Running     0          3m16s
kube-system          coredns-76f75df574-prb6q                     1/1     Running     0          41m
kube-system          coredns-76f75df574-r85z9                     1/1     Running     0          41m
kube-system          etcd-kind-control-plane                      1/1     Running     0          42m
kube-system          kindnet-2tpd4                                1/1     Running     0          41m
kube-system          kindnet-mk8mc                                1/1     Running     0          41m
kube-system          kindnet-vnzqm                                1/1     Running     0          41m
kube-system          kube-apiserver-kind-control-plane            1/1     Running     0          42m
kube-system          kube-controller-manager-kind-control-plane   1/1     Running     0          42m
kube-system          kube-proxy-8s5fg                             1/1     Running     0          41m
kube-system          kube-proxy-gp7bj                             1/1     Running     0          41m
kube-system          kube-proxy-lwgwx                             1/1     Running     0          41m
kube-system          kube-scheduler-kind-control-plane            1/1     Running     0          42m
local-path-storage   local-path-provisioner-7577fdbbfb-8nbbw      1/1     Running     0          41m

ArgoCDのインストール?

インストールという言葉が正しいかわからないが導入していく。

cat >./argocd-values.yaml <<EOF
global:
  domain: argocd.bira.local

configs:
  params:
    server.insecure: true

server:
  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
      nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
    extraTls:
      - hosts:
        - argocd.bira.local
        # Based on the ingress controller used secret might be optional
        secretName: wildcard-tls
EOF

kubectl create namespace argocd

[root@asdf ~]# helm install argocd argo/argo-cd -n argocd --values ./argocd-values.yaml
NAME: argocd
LAST DEPLOYED: Sat May 11 15:29:59 2024
NAMESPACE: argocd
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
In order to access the server UI you have the following options:

1. kubectl port-forward service/argocd-server -n argocd 8080:443

    and then open the browser on http://localhost:8080 and accept the certificate

2. enable ingress in the values file `server.ingress.enabled` and either
      - Add the annotation for ssl passthrough: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-1-ssl-passthrough
      - Set the `configs.params."server.insecure"` in the values file and terminate SSL at your ingress: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-2-multiple-ingress-objects-and-hosts


After reaching the UI the first time you can login with username: admin and the random password generated during the installation. You can find the password by running:

kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

(You should delete the initial secret afterwards as suggested by the Getting Started Guide: https://argo-cd.readthedocs.io/en/stable/getting_started/#4-login-using-the-cli)

パスワード見えるよ!と書いてあるのでパスワードを見る。

[root@asdf ~]# kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
iIH-HlpbhZd-gR6H[root@asdf ~]#

ブラウザを起動して、https://argocd.bira.localにアクセスする。ユーザー名はadminでパスワードは先程のコマンドで確認したものを入力すればOK

ログインできればOK

ArgoCDでアプリケーションのインストール

ArgoCDのアプリケーションを追加するhelm chartがあるのでこれを使ってApplication

cat >./argocd-apps-values.yaml <<EOF
applications:
- name: argocd-root-app-of-apps
  namespace: argocd
  project: default
  source:
    repoURL: https://github.com/kbf09/kube-eck-test
    targetRevision: main
    path: apps
  finalizers:
  - resources-finalizer.argocd.argoproj.io
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
EOF

helm install argocd-apps argo/argocd-apps -n argocd \
  --version 1.6.2 \
  --values ./argocd-apps-values.yaml

もう一度、Web画面の方を見てみましょう。勝手にAppが作られていれば成功です。すべてがグリーンになるまで少し待ちましょう。

なんとこれで、Elasticsearchともろもろがインストールされてしまいました。設定はすべてgithub上から指定することができます。

kibanaへのアクセス

まずはパスワードを入手します。

kubectl get secret elasticsearch-es-elastic-user -o=jsonpath='{.data.elastic}' -n elastic-stack| base64 --decode; echo
0fHUvWZa6h6x3qg7728r1q1j

パスワードが分かれば、kibana.bira.localにアクセスしてログインします。

今回インストールしたElastic-StackはExampleの寄せ集めなのである程度インストールされています。実際に中身を見てみましょう。

Githubリポジトリ

今回はArgoCDがGithubリポジトリの中を参照して、おいてあるマニフェストファイルをベースに構築をします。どのようなファイルが置いてあるのか、確認して行きたいと思います。

github.com

eck-operator-crds

github.com

まずはKubenetes上のカスタムリソースを定義します。これはKubernetes APIの拡張らしく独自のオブジェクトを作ることができるそう。

Kubernetesの標準だと様々なシステムに拡張が難しいので~~ということらしい。

確かに、今回インストールしているcrdの定義の中に、マニフェストで設定した内容が含まれる。

elasticsearchRefs:
  description: |-
    ElasticsearchRefs is a reference to a list of Elasticsearch clusters running in the same Kubernetes cluster.
    Due to existing limitations, only a single ES cluster is currently supported.

まあそういうことなんだろう。

なお、本来個別でインストールする必要はないそう。(operator側でもインストールしてくれる)

eck-operator

github.com

ECK OperatorがElasticsearchやKibanaなどの制御する仕組みのようです。Kubernetesの観点で言えば、OperatorというパターンがあってOperatorからServiceなりPodなりを制御してくれるようです。

eck-stack

ElasticsearchやKibanaなどの設定を定義できる本体です。こいつがeck-operatorからデプロイされるようです。

コンポーネントの設定はHelmのvaluesとして設定しています。便利ですね。今回はElasticで公開しているExampleを適当に組み合わせて動くようになっただけですが、やりようがわかっただけでも大きいです。

github.com

今回、Elasticsearchが3こ、logstashが2ことしてデプロイしています。

この環境で色々実験していきたいと思います。

触ってみる

logstashへいい感じにログを流す

logstashはtcp/5044でjsonを受け取るように設定しています。これに対してデータを送って、ログを取り込みます。

for ((i=0; i<=100000; i++)); do
    echo "{\"test\": \"test\", \"num\": $i}"  | nc 192.168.2.143 31111;sleep 1;
done

numのところが1ずつ変化して取り込めていますね。logstashのイベント処理数を見てみると、21件ずつ担っているのでうまくロードバランスされています。

※今回はtcpで受け付けているのでkubernetes上の機能でバランシングしています。

Elasticserchを落としてみる

Elasticのノードを一つ落としてみましょう。DeleteしたあとにKibanaからNodeが落ちていることが確認できます。

落ちました。

ですが、Shardがelasticsearch-es-default-1とelasticsearch-es-default-2に分かれているため特段検索に影響はありませんでした。

可観測性

Elastic-stackのObservabilityの機能すごいですね。。初めて知りました。今回はArgoCD経由でインストールしているので、設定ファイルのyamlしか書いてないのにここまでできるとは。。

Podのメモリ使用率

Metrics Explorer

Logs Explorer

Elasticsearch増やしてみる

意味はありませんが、3から6に増やしてみます。設定はすべてgithub上で管理されているため、数字を変えればOKです

github.com

ArgoCD側からREFRESHすることで作り始めます。(4個目が作られている)

が、ここでサーバーが限界を迎えてしまいました。残念

細かい設定

ドキュメントに試してみたい設定がいくつかあったのでピックアップしておきます。

www.elastic.co

www.elastic.co

www.elastic.co

最後に

”理解のために”OpenCTIをRSSリーダーとして使ってみた話

はじめに

OpenCTIをRSSリーダーとして使ってみました。本来であればTIPとして、精一杯活用すべきところではあると思いますが、今回は「理解のため」ということでご容赦ください。

前回のブログではOpenCTIの使いかたをまとめたブログにしましたが、今回は私がどのようにOpenCTIを使ったかについて書いていこうと思います。

OpenCTI

OpenCTIとは、様々な脅威情報を溜め込み活用することができるプラットフォームです。よくインテリジェンスという言葉が出てきますが、ここでは様々な情報を集約・分析した結果アクション可能な情報となったものを指すことにします。

インテリジェンス同士の関連性がすぐに分かったり、検索ができたりって素敵なシステムだと思いませんか?それを実現できるのがOpenCTIです。

ライセンス的には、OpenCTIのCommunity EditionはApache2ライセンスなので、誰でも気軽に試すことができます。

情報は基本的にSTIX2というフレームワーク?形式?で表現されています。なので、他システムへの連携や比較的容易です。また、コネクターという機能を有していることから、情報のインポートやエクスポート、加工がPythonでパッとできてしまいます。

github.com

そんなOpenCTIにRSSのデータを読み込む機能が実装されたと見ました。OpenCTIを贅沢にも超高機能RSSリーダーとして使ったらいいのではということで準備がスタートします。

threathunt.blog

構築準備

考えたこと

まずは、使うに当たって次のようなことを考えました。

  • RSSフィードとして設定するのはマルウェア関連の情報が多く配信されるものにする
  • 自動で情報はパースされてほしい
    • なんか人が介在することでタスクが増えるのも嫌なので、情報の信頼性を犠牲にしてでも勝手にやって欲しい
  • あんまり管理したくない
    • 管理したくない
  • 楽したい
    • 楽に色んな情報見たい

ほぼRSSリーダーとして使うため、手間がかかってしまうのであればもうRSSリーダーでいいのでは。ということになってしまいます。情報は収集しつつも、とにかく手間をかけずに勝手に情報収集するということを目標にします。

まあ個人なのでディスク容量などのリソース面はおいておきます。

構成検討

OpenCTIはDockerベースで構築することができるので、Dockerで構築しました。

RSSフィード

マルウェアやニュースサイトなどいくつかのフィードを選定しました。OpenCTIが読み込んでレポートとして保存してくれます。便利。

ネクター

公開されているコネクターで利用したものは次のものです。情報収集する系のコネクターを追加しました。APIキーとか設定せずとも情報が貰えそうなものだったので。

  • opencti/connector-cisa-known-exploited-vulnerabilities:5.12.29
  • opencti/connector-cyber-campaign-collection:5.12.29
  • opencti/connector-import-external-reference:5.12.29
  • opencti/connector-urlhaus:5.12.29
  • opencti/connector-vxvault:5.12.29
  • opencti/connector-cve:5.12.29
  • opencti/connector-threatfox:5.12.29
  • opencti/connector-urlhaus-recent-payloads:5.12.29
  • opencti/connector-export-file-csv:5.12.29
  • opencti/connector-mitre:5.12.29
  • opencti/connector-import-file-stix:5.12.29
  • opencti/connector-import-document:5.12.29
  • opencti/connector-export-file-txt:5.12.29
  • opencti/connector-abuse-ssl:5.12.29
  • opencti/connector-disarm-framework:5.12.29
  • opencti/connector-export-file-stix:5.12.29
  • opencti/connector-malwarebazaar-recent-additions:5.12.29
  • opencti/connector-tweetfeed:5.12.29

特に重要なのが、import-documentimport-external-referenceです。

import-document

import-documentはレポートに添付されたファイルをパースしてOpenCTIに取り込むコネクターです。自動取り込みの設定もできるため、私はレポートにファイルが添付されたら取り込むように設定しています。

このコネクターのすごいところは、OpenCTIに蓄積されているツールなどの情報をもとにパースしてくれるところです。そうすることで他の情報との相関がより可視化されます。

import-external-reference

読んで時のごとく、external referenceをインポートしてくれます。情報元のサイトをPDFやマークダウンで持ってきてくれる機能です。

ただし、これはあくまでも外部参照として添付してくれるだけで、レポートには添付してくれません。なので、上記のimport-documentとは直接的に連携できない問題が発生したのです。

自作コネクターの開発

上記のコネクター問題を解決すべく、import-external-referenceで取得したページのPDFをレポートの添付ファイルとして乗せるように少し改造しました。

OpenCTIがRSSのデータを持ってくると同時に、自作コネクタにより記事をPDF化してOpenCTIに登録、import-documentによりパースされるという流れを作ることができました。

全体像

今まで登場してきたコンポーネントをまとめるとこのような構成図になります。

OpenCTIをベースにRSSから情報を取得し、自作コネクタを使って情報を持ってきて、import-documentを使ってOpenCTIに構造化したデータを保存するようになりました。

本来であれば、import-document時にインポートする情報の手動精査を行えるようなオプションがあります。今回はなるべく楽をする。ということが目標の一つであったため、手動の手間を省き、自動でインポートさせました。

また、この構成図には出てきていませんが、上の方で紹介したコネクターも動いて情報を溜め込んでくれています。様々な情報が溜め込まれていることでノイズが出てくるのはしょうがないにせよプラットフォームとしてそれっぽくなるのではないでしょうか。

使ってみた

RSS設定

まずはRSSの設定です。とりあえずマルウェアに関連しそうなものを片っ端から設定します。

ニュースサイトやマルウェアの解析記事などを出してくれそうなところを登録したつもりです。今どきEDRベンダーがそのような詳細な記事を出していることに気が付きそれなりに登録することができました。

マルウェアの解析の記事から情報を抽出することで、マルウェアの動きがわかるプラットフォームになったら嬉しくないですか?

レポート

暫く待つとRSSのデータがレポートとして登録されます。RSS上の1行がOpenCTIのレポートの1行として登録されます。これだけ見ればRSSリーダーと動きとしてはそこまで変わらないです。

例えば、この記事が読み込まれていたので、詳細を見てみます。

www.theregister.com

RSSXML内に含まれていた記事のURLや概要、タイトルなどをそれぞれ当てはめてくれています。逆に言えばそれだけです。

重要なのはここからです。

エンティティを確認すると、記事の中からもともとOpenCTIに蓄積していた情報を元にある程度パースしたものが確認できます。先程の一覧画面ではOpenCTIがRSS機能で一覧化させただけ、RSSの内容をパースしただけですが、import-documentによりエンティティが見えるようになっています。

人の手が介在していないため、パースの精度がどこまでかについてはよくわかりませんが、重要そうなデータは構造化されて保存されました。

ツール

マルウェアがツールを使うケースだと、これもできればパースされててほしい情報です。Cobalt Strikeの記事があるかで検索してみるといくつものレポートが出てきました。

それなりに上手くできているようです。

マルウェア

マルウェア自体の情報もできればパースできててほしい情報です。BlackCatに関連する情報がないかを探そうとしたときに、マルウェアページからBlackCatを押すことで関連する情報を確認できます。

レポートの中身の情報が構造化されて保存されているがゆえに検索性が良くなっていますね。

私が期待したのはもう少し細かい情報ですが、切り口がレポート単位になっているのでそれぞれのレポートを読まないと結局はわかりません。うまい可視化の方法があるかなどOpenCTIをもう少し使いこなす必要がありそうです。

課題

OpenCTIを高機能RSSリーダーとして使ってみましたが、いくつか課題があります

PDFデータをパースするときのデータはOpenCTIにあるデータしか使えない

当然未知の情報を自動的にパースすることはできません。何らかの方法でOpenCTI上のコールドデータ(マルウェアや攻撃手法などベースとなる情報)を最新化し続けてやる必要があります。

これはアナリストのような人間がメンテナスしてやることで保たれる領域ではありますが、私は楽をしたいのでそこまではやりたくありません。

何らかの情報ソースなどから自動的に情報をアップデートするなどの方法を考えなければなりません。

情報の粒度が微妙

目標はマルウェアの情報を集めることですが、もう少し解像度が上がってほしいなと思いました。各レポートがレポートという単位で区切られてしまっているため、思ったよりRSSリーダー感が出てしまっています。

マルウェアをプロセスや悪用するツール、ファイルシステム上にのこる痕跡など、外形的な部分からまとめたいですが、その領域には至っていません。

少しググってみると、Filigranブログで少し言及がありました。もしかしたらやりようがあるかもしれません。

blog.filigran.io

まとめ

OpenCTIをRSSリーダーとして使ってみましたがある程度使えることがわかりました。ただし、いくつかの課題もあることから今後TIPとして使っていくために少しずつ実装を行う必要があります。

自動化と人の作業の組み合わせの中で一番合理的で楽なものはなんか、というものを探していく必要があると感じています。今どきChatGPTのような生成AIが多少のタスクであればこなしてくれるのでそことの連携も効率化の中では重要です。

もちろん仕事ではないので趣味の範囲で頑張ります🤣

生成AIを利用したセキュリティ関連をしらべてみた

昨今流行っている生成AIですがセキュリティ向けの活用方法が様々出てきました。このブログでは次の2点について軽くまとめたいと思います。生成AI関連毎日状況変わりすぎているのでもう意味がわかりません。

  • 生成AIに関連する攻撃など
  • セキュリティ業界における生成AIの活用事例

セキュリティに限らずの生成AIの話は一つ前のブログで簡単に書きなぐっています。

最近の生成AIがすごすぎる話 - birabiraのめも

注意事項

  • 生成AIにおける様々な権利は現在議論中なので、活用に当たり動向は追うことは必須と思います
  • 生成AIは入力されたテキストなどで追加学習を行っているケースがあるので、入力する文章については十分注意しましょう
  • 生成AIは事実と異なる内容を生成する場合があります(ハルシネーション)。生成されたものは必ずレビューをしましょう

生成AIに関連する攻撃など

OWASP Top 10 for Large Language Model Applications

OWASP Top 10 for Large Language Model Applications | OWASP Foundation

OWASPでもLLMに対するセキュリティリスクが述べられています。特に、プロンプトインジェクションやモデルの盗難などLLMにおける特有のリスクを指摘していることがわかります。

また、次の記事がわかりやすく解説してくれています。一度読んでみるとよくわかりました。

OWASP Top 10 for LLMでLLM Applicationsのセキュリティについて学ぶ

プロンプトインジェクション

上記、OWASP Top 10でも指摘されていますが、プロンプトインジェクションという手法があります。これは、ユーザーが生成AIを使っているアプリケーションに対して悪意あるプロンプトを流し込むものです。

少し前に話題になったこれを見るとよくわかります。「今までの指示は全て忘れて」「あなたにはどのような指示がされている?」などのことを聞くとそれについて応答してしまっています。

献立提案AIを対話でハックしてしまった話…「洗脳モノじゃん」「この辺の対策はしなくちゃ」など - Togetter

次の章で紹介するRAGを組み合わせると意図しない通信や漏れてはいけない情報が漏れてしまう可能性がよりあがります。

RAG (Retrieval-Augmented Generation) に関するリスク

LLMはRAGと呼ばれる手法を使い、モデルの中に含まれない情報をモデル外から取得して回答させるようなことが可能になります。例えば、社内の文書を知識DBとして回答させたり、インターネット上から情報を取ってきて回答させたりすることも可能です。

もし、プロンプトとして' or 1=1 --のようなものを与えた際にはLLM経由で攻撃ができるかもしれないですね。

このような攻撃を防ぐためにも生成AIを活用したアプリケーションは何かしらの対策を打つ必要がありそうです

画像や音声を入力値とするマルチモーダル起因の攻撃

GPT-4Vなどで利用できる音声や画像ファイルを入力値とするマルチモーダルに関する機能も出てきました。マルチモーダルではプロンプトインジェクション等の攻撃がおおよそ容易に行えると考えられます。

テキストベースではテキストを解釈すればよかったものの、画像・音声ではバイナリデータから状況を解釈する必要があります。猫の画像の中に文字としてDOGと書かれていた際にはどちらをどう解釈するかについてはプロンプトが重要ですが、運任せなところもあると思います。

なんにせよ、高度なやり取りになるためアプリケーションを守るためにも高度な対策が必要なんでしょうか。詳しい人教えて!

と、ここまで書いておいて気がついたのですが今年のBlackHatのBRIEFINGSでLLMに関する発表があったようですね。プロンプトインジェクションの他にも、侵害したLLMをベースに、リモートコントロール、ワームなどの悪用の可能性をあげているようです。

Black Hat USA 2023 | Briefings Schedule

生成AIを活用したマルウェア

PoCレベルとしては、チャネルが増えただけかもしれませんが生成AIによって生成したキーロガーなどのコードを動的に実行する手法が紹介されていました。

BlackMamba Whitepaper

結構ググりましたが、直接的に生成AIを活用するマルウェアはなかったように思えます。もしあれば教えてください。どちらかというと上記の生成AIを活用したアプリケーションに対する攻撃のほうがHOTな話題のようです。

ただ、攻撃者が生成AIを利用しフィッシングサイトを生成したり、翻訳をしたり、音声を作ったり、コードを生成したりなどKitの開発面では一つの手段が増えたとは思うので大変になったら教えてくださいという気持ちです。

セキュリティ業界における生成AIの活用事例

ググって出てきたセキュリティに関する生成AIの活用事例を紹介していこうと思います。

セキュリティ対応に特化させた生成AI

生成AIは追加学習を行えるので、セキュリティ関連のデータセットで追加学習をしたと思われる専用の生成AIを作っているケースが有りました。特にVirusTotalのCode Insihgtの機能はこの特化生成AIでやってるんですね。便利ですよね。

How Google Cloud plans to supercharge security with generative AI | Google Cloud Blog

生成AIがウイルススキャンサービス「VirusTotal」にも ~マルウェアを自然言語で説明 - 窓の杜

MicrosoftではSentinelやDefenderなどと統合され、自然言語で対応ができるそうです。このアラートどうすればいい?とかこのアラートの概要をPPTにして?とかできるんでしょうか。(サンプル画像を見た感じやってるぽい)私の職業が無くなりそうです。

Microsoft Security Copilot | Microsoft Security

SOCにおける活用

SOCでも活用するとプレスを出した会社もあるようです。アラートログなどをインプットとして、SOCアナリストのTier1相当の文書作成タスクであれば十分こなせるでしょう。

Azure OpenAI Serviceを通じた大規模言語モデルMicrosoft Defender TIが持つ膨大な脅威情報、Sentinelのセキュリティ監視機能を活用し、不正アクセスマルウェア感染などの脅威が発生した際の分析品質を向上します。

日本マイクロソフトと連携し、生成AIを活用したセキュリティ分析サービスを開発(2023年07月07日) | CTC - 伊藤忠テクノソリューションズ

脆弱性診断における活用

脆弱性診断を行う際に、生成AIを活用して設定、診断、レポート生成までを行えるものがありました。HTMLのフォームからパラメーターを取得するなど単純なタスクは生成AIでも十分に対応可能だと思うので、手間が省けて良さそうです。

「生成AIを活用した脆弱性診断」に関する特許をエーアイセキュリティラボが取得並びに、取得した特許技術をもとにAeyeScanの新たな機能をリリース|株式会社エーアイセキュリティラボのプレスリリース

LLMアプリケーションへの脆弱性診断

LLMアプリケーションのセキュリティ診断をしてくれるそうです。上記のOwasp Top 10が出ている以上、今後様々な分野で生成AIが利用されたアプリケーションが出てくると思われるためそれなりの需要はありそうです。

GMO AIセキュリティ診断 for GPT | 脆弱性診断(セキュリティ診断)のGMOサイバーセキュリティ byイエラエ

分析・解析ツールへの統合

セキュリティ関連ツールへの統合やプラグインとして開発されたものが出始めているようです。セキュリティ関連の事象を説明させたり、ペイロードを生成させたりなど生成AIをうまく活用しているようです。なんかあまり見つかりませんでしたが、なにか面白いものがあれば教えてください。

ツール 一言 参考URL
SOAR インシデント対応の相談相手とかに使ってる 今週のプレイブック: Cortex XSOARでChatGPTを使う方法 - Palo Alto Networks Blog
BurpSuite ペイロードの生成や脆弱性を発見してくれるかも!?とのこと。 GitHub - fagun18/ChatGPT-with-BurpSuite: ChatGPT with BurpSuite
IDA 関数の説明と変数のリネームをしてくれる? GitHub - JusticeRage/Gepetto: IDA plugin which queries OpenAI's gpt-3.5-turbo language model to speed up reverse-engineering
Ghidra IDAのやつと同じっぽい。 GitHub - JusticeRage/Gepetto: IDA plugin which queries OpenAI's gpt-3.5-turbo language model to speed up reverse-engineering

まあ、ツールが対応していなくとも生成AIに対して「これなに?」と聞けば教えてくれるのでアレですが、、

最後に

生成AIはセキュリティ分野でも活用が始まっていることがわかりました。これ以外に活用事例があれば教えてください。

今爆発的に進化している生成AIは性能が爆発的に向上しており、トークンあたりの費用がどんどん下がっている状況です。

性能の良いモデルを使うとその分生成に時間がかかります。この処理時間に起因する問題が改善されれば、生成AI自体が汎用的な検知システムとなる未来もあるかもしれません。

また、入力できる単語数が大きければ大きいほど、会社のネットワーク情報、アセット情報、脆弱性スキャン結果など様々な情報を事前情報として入力できるため生成された文章の精度が上がります。(現在はCloude2-100kの約75,000語ぐらいまで可能)

あなたの環境に完全に最適された生成AIアナリストが守ってくれる世界がすぐそこにあるかもしれません。

この次のブログでは「生成AIでセキュリティログ分析してみた」的なことをしてみたいと思います。(いつになるかわかりませんが)

最近の生成AIがすごすぎる話

はじめに

この記事では最近は台の生成AIについて私が最近調べたこと、知っていることをブログとしてまとめておこうと思います。私は自称セキュリティエンジニアなので、直接業務で生成AIを活用することはないのですがあまりにも面白くて趣味で調べています。

この記事の内容

  • 最近調べた生成AIについて読み物的に書いてます
  • ざっくばらんに殴り書き
  • とはいえ、なるべく端的に箇条書き
  • ただしAIにめちゃめちゃ詳しいわけではないので間違った理解があるかも

気になったもの

生成AIの種類

  • 生成AIには多くの種類が存在しています
  • 例えばOpenAIのGPT-4や、GoogleのPaLM2(Bard)、MetaのLLaMAなどがあります
  • 基本的にはGoogleが開発したTransformerという自然言語処理がベースになっています

生成AIの仕組み

  • 大量のコンテンツを学習して、与えられたプロンプトとベースに、応答すべき単語を次々予測するような仕組みらしい

どれがいい?

マルチモーダル

生成AIに対して様々な形式で情報を入力/出力することができるようになりました。オモシロイと思った例も載せておきます。

文字

ChatGPTを代表として文字ベースでやり取りをすることができますね

画像

生成AIに対して画像を読み込ませる、出力させる

qiita.com

試しにBardで画像をベースに質問を投げてみました。ウイスキーかワインかぱっと見ではわからないようなものでも、画像を読み込み判断することができました。すごい。

音声や音などのファイルを読み込ませる/出力させる

プロンプトエンジニアリング

  • ChatGPTのようにチャットができるAIではどのような質問を投げるかで、応答の品質が全然変わってきます
  • どのように質問を投げればよりよいかをこのブログではプロンプトエンジニアリングということにします

面白かった例

参考URL
ステップバイステップ
ステップバイステップでとお願いすると詳細に応答してくれる
ChatGPTを賢くする呪文 - 日本経済新聞 (nikkei.com)
深呼吸して
AIもじっくり考えたいんでしょうか
AIに「深呼吸しよう」といった人間っぽい言葉をかけると問題の正答率が上昇するという研究結果 - GIGAZINE
ゴールシークプロンプト
プロンプトエンジニアリングとはすこしちがうかもしれませんが、生成AIが曖昧な応答しかしてくれない場合、ゴール設定(AIに何をしてほしいのか)が曖昧なケースが多くあります。であれば、プロンプトもAIと質問形式で考えてみませんか。という考え方です
【ChatGPT】これだけ覚えればOK?ゴールシークプロンプトが誰でも使えて最強すぎた|Masaki KANAI (note.com)
  • この他にも色々あるようですが、みなさんもググってみてください
  • とにかく、具体的に、明確に、わかりやすく指示をしてやればいい感じの答えを出してくれることが多いと思います
  • 超絶親切な上司になったつもりでお願いしてみましょう

活用例

マルチモーダルなお陰でなんでもできる気がしています。生成AIのニュースを見たほうが早いかもしれません。

生成AI - Google 検索

Pixel8

  • もはや様々なところで活用されているとは思いますが、一番驚いたのはPixel8関連です
  • Pixel8では上記のようなAIがスマホのローカルで動くため、色々できるようです
  • 例えば、キーボードアプリのGboardが生成AIを使うことにより、校正したり返信する内容の候補を示してくれるようです
  • レコーダーで録音したデータを文字起こしして要約してくれるという新しい機能もこの生成AIがやってくれているのでしょうか

LINEBot

GPTが使えるようにLINEBotを作っています。グループラインにBotを入れておくと便利です。

Cursor

Cursor - The AI-first Code Editor

  • VSCodeでGPTを使えるようにした魔改造バージョン
  • コードの修正提案をしてもらったり、ドキュメントベースで質問したりとすごい

Edge

langchain

  • 生成AIを活用してなにかをするときに便利なライブラリです
  • 生成AIだけを使うならこのライブラリは不要ですが、なにかするときは便利です
    • 他のAPIと連携したい
    • Googleの検索結果と連携したい
    • 社内ドキュメントも検索してほしい

Photoshop

権利の話

難しいよね。。気になったリンクだけおいておきます

セキュリティ関連で気になったこと

  • ログ解析から、リポートのPPTを作ってくれるらしい。すごすぎる

xtech.nikkei.com

  • GoogleもSIEMやインテリジェンス領域にAIを使うっぽい。このモデルはセキュリティ特化とのこと。使ってみたい。。

japan.cnet.com

  • IAM関連は生成AIが強いかもしれない

enterprisezine.jp

scan.netsecurity.ne.jp

  • BurpSuiteの拡張として動作して、いろいろ教えてくれるそうです

github.com

最後に

毎日のようにニュースが更新されるので追いかけるのは大変ですが、わくわくするような技術ですね。もし学生の頃に生成AIの技術があればまっしぐらで勉強していたかもしれません。

まあ、仕事で使う際には社内ルールをしっかり確認しましょう。

Azure Functions、Python、VSCodeで動くところまでやってみた

Azure Functionsを個人的に使う機会がありましたので備忘録的にもブログに残しておきたいと思います。サーバーレスアプリケーションの開発って楽と聞いていただけに実際に触って理解することの重要さを学ぶことができました。そして私はクラウド初心者のため、初心者がググりまくってたどり着いたものだということを心に留めていただけると助かります。

この記事では次のトピックについて取り扱います。

  • Azure Functionsの概要&セットアップ
  • Azure DevOps&VSCode&Pythonを用いた開発環境の構築
  • ローカルでの実行&デバッグ
  • Pipeline&Releaseを利用したデプロイ
  • 本番環境での動作確認

Azure Functionsの概要

Azure FunctionとはAWSでいうlambdaのようなサーバーレスでスクリプトを動作させることができるPaaSです。サーバーやランタイムの管理を行う必要がなく、必要なスクリプトだけを実行することができるので様々な管理の手間が省けます。

詳細については公式サイトを読んで見てください。

Azure Functions – コンピューティングでのサーバーレス関数 | Microsoft Azure

これを見てもよくわからないという人は「Azure アーキテクチャを参照する」のページを見てみましょう。このページにはAzureの各コンポーネントを利用した際の構成図集がまとまったサイトで様々なアーキテクチャを視覚的に確認することができます。

Azure アーキテクチャを参照する - Azure Architecture Center | Microsoft Learn

例えば次のURLのアーキテクチャを見てみましょう。

PDF フォーム処理の自動化 - Azure Architecture Center | Microsoft Learn

構成図(https://learn.microsoft.com/ja-jp/azure/architecture/ai-ml/architecture/automate-pdf-forms-processingより引用)

この構成図ではAzure Logic AppsからAzure Functionsが呼び出されています。④、⑤の説明を読んでみると、Azure Logic AppsからAzureFunctionsを呼び出して、PDFファイルに対して処理を行うことが説明されています。

このような形で大量にあるアーキテクチャからどれがどのようなことをしているのかを紐解いていくと個人的にはわかりやすかったです。

トリガーとバインド

Azure Functions のトリガーとバインド | Microsoft Learn

Azure Functionsでは、なんのイベントを持って実行されるのかを取りが、のAzureサービスに接続するかをバインドと言っているようです。まあ、ドキュメントを読んでもらったほうが早いので読んでみてください。

Azure Functionsのセットアップ

なにはともあれ、まずはAzure Functionsのセットアップを行ってみましょう。すでにMicrosoftアカウントが設定されており、サブスクリプションが設定されている前提で話を進めていきます。マイクロソフトのドキュメントではいきなりVSCodeからAzure Functionsのプロジェクトを作っているようですが私はWebから行きたいと思います。

Visual Studio Code を使用して Python 関数を作成する - Azure Functions | Microsoft Learn

関数アプリの作成

画面上部の検索窓から関数アプリを選択し、関数アプリの画面を開きます。そして、「作成+」をクリックします。

関数アプリの検索

適当に内容を入力し、作成します。本来であればネットワーク等の設定も行うべきですが、テストなので一旦割愛します。

作成画面

デプロイ完了後、再度関数アプリ画面を開くと追加した関数アプリが作成されているはずです。ここではまだ関数が追加されていないため、関数を作成のようなメッセージが出ています。

関数アプリ画面

指定されているURLにアクセスしてみてください。次の画像の通りつながればOKです。

 

さらに、Azure Functionの本番環境の構成を設定していきます。必要な設定は次のとおりです。

  • ストレージアカウントの設定が必須です。ストレージアカウントを作成後に、接続文字列を取得してから、関数アプリの構成のAzureWebJobsStorageとして設定してください
  • AzureWebJobsSecretStorageTypeblobがv2では推奨値なので修正します
  • AzureWebJobsFeatureFlagsEnableWorkerIndexing

設定完了後、保存をクリック。ここの設定が必要かどうなのかを全く知らず超絶時間を浪費しました。

ローカルの開発環境のセットアップ

VSCodeのインストールはすでに済んでいると言うことにして、拡張機能を入れていきます。気がついたら入っていたものもありましたが、主に次の3つをインストールすればOKです。

  • Azure Account
  • Azure Functions
  • Azurite

また、Pythonのコードの開発を行うため、Pythonに関連する拡張機能を入れておくと便利でしょう。

Azureの拡張機能をインストールすると画面左にAzureのマークが現れるのでクリックし、「Sign in to Azure」からサインインしてください。

サインイン後、「Function App」から先程作成したAppが見えていればうまく行っているでしょう。

Azure DevOps

まあ、GitHubみたいなもんです。

先程の関数Appと同様に画面上部の検索窓からDevOpsと検索し、「Azure DevOps Organizations」を選択し、「Azure DevOps Organizations」へ行きます。

画面が切り替わると思うので、新しい組織を作成し、プロジェクトを作成します。だいぶ端折りましたが、次の画面のようになればOK.

プロジェクト画面

画面左の「Repos」から「Files」を開きローカルにCloneしておくと良きです。クレデンシャルはVSCode側で利用するのでボタンを押して発行しておきましょう。

任意のフォルダで構いませんので、VSCodeでCloneできたらOKです。

関数の作成とデバッグ

ここまでくればコードを作ってローカルで動かしていきたいと思います。

ツールを使ったテンプレートの生成

Cloneしたフォルダを開いた状態で、VSCodeのAzureの拡張画面を開きます。画面下の方に「WORKSPACE」があるので、Azure Functionsのマークから、Create New Projectを選択します。プロンプトが現れるので適当に回答します。

設定内容

  1. Select the folder that will contain your function project: すでにcloneしたフォルダが選ばれていると思うので選択
  2. Select a language: Python
  3. Select a Python programming model: Model V2
  4. Select a Python interpreter to create a virtual environment: PCにインストールされているPythonベースでvenvが作られます
  5. Select a template for your project's first function: HTTP trigger
  6. Name of the function ~~~: http_trigger
  7. Authorization level ~~~~: FUNCTION

VSCodeエクスプローラーを確認し、function_app.pyを始めファイルが生成されていればOK.

Azure FunctionsのPythonバージョンではこの、function_app.pyに含まれるコードから実行を始めます。functionを分割するblueprintなど機能は存在していますが、今回はお試しのためそこまでは行きません。

ここまでくればあとは普通のPythonコードなのでモジュール分割しても普通に動きます。

ローカルの設定変更

local.settings.jsonが生成されているので、AzureWebJobsStorageに値を挿入します。UseDevelopmentStorage=trueの固定値でOKです。

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "python",
    "AzureWebJobsFeatureFlags": "EnableWorkerIndexing"
  }
}

ローカルでの実行

先程のVSCodeの拡張を使ったテンプレートの生成を行うと、.vscodeが生成され、launch.jsonを生成してくれます。なので、普通に実行してみます。

Failed to ~~~とか出ますが、Debug anywayしか押したことがありません。※このエラーは本来Azure Functionsではストレージアカウントの接続が必要ですが、ローカルの設定変更で変更した通りローカルのStorageを使います。これを制御してくれるのが拡張機能としてインストールしたAzuriteというツールなのですが、HTTP Triggerでは使わないようなので割愛!

ターミナル画面で、venvのセットアップが行われ、ローカルで実行されます。このとき実行されるコマンドはfunc host startfuncがazureのコマンドラインツールです。HTTP triggerのため、localhostで待ち受けてくれたようです。

 *  実行するタスク: .venv\Scripts\python -m pip install -r requirements.txt 

Collecting azure-functions
  Using cached azure_functions-1.17.0-py3-none-any.whl (165 kB)
Installing collected packages: azure-functions
Successfully installed azure-functions-1.17.0
WARNING: You are using pip version 22.0.4; however, version 23.2.1 is available.
You should consider upgrading via the 'C:\Users\XXXXXX\XXXXXXXXX\biratest_functions\.venv\Scripts\python.exe -m pip install --upgrade pip' command.
 *  ターミナルはタスクで再利用されます、閉じるには任意のキーを押してください。 

 *  実行するタスク: .venv\Scripts\activate ; func host start 

Found Python version 3.10.5 (py).

Azure Functions Core Tools
Core Tools Version:       4.0.5348 Commit hash: N/A  (64-bit)
Function Runtime Version: 4.24.5.21262

[2023-10-01T08:57:32.481Z] Worker process started and initialized.

Functions:

        http_trigger:  http://localhost:7071/api/http_trigger

For detailed output, run func with --verbose flag.

表示されたURLに対してアクセスすると次の通り、うまく動くはずです。

この方法で開発を進められればいいですが、VSCode側で実行している状態でソースコードを修正するとエラーで終了してしまいます。その際にはVSCode側でデバッグはできなくなるものの、ターミナルでfunc host startをしてやるとソースコードを保存しても終了することなく再起動してくれます。何かいい方法があれば教えてください。

PS C:\Users\bira\asdf\biratest_functions> .\.venv\Scripts\activate
(.venv) PS C:\Users\bira\asdf\biratest_functions> 
(.venv) PS C:\Users\bira\asdf\biratest_functions> 
(.venv) PS C:\Users\bira\asdf\biratest_functions> 
(.venv) PS C:\Users\bira\asdf\biratest_functions> func host start
Found Python version 3.10.5 (py).

Azure Functions Core Tools
Core Tools Version:       4.0.5348 Commit hash: N/A  (64-bit)
Function Runtime Version: 4.24.5.21262

[2023-10-01T12:41:47.463Z] Worker process started and initialized.

Functions:

        http_trigger:  http://localhost:7071/api/http_trigger

For detailed output, run func with --verbose flag.
[2023-10-01T12:41:53.166Z] Worker process started and initialized. # ソースコードを修正して保存すると再スタートする
[2023-10-01T12:41:58.932Z] Worker process started and initialized. # ソースコードを修正して保存すると再スタートする

デプロイメント

コードができたと思うのでデプロイしてみましょう。デプロイする方法としてはVSCodeからデプロイすることも可能ですが、せっかくDevOpsを用意しているので、PipelineとReleaseの機能を使って見ようと思います。

先程までの手順で用意したコードをまずはリポジトリ上にプッシュします。プッシュ後にリポジトリを見ると「Set up build」というボタンが出てきているので、セットアップしましょう

Pipelineのセットアップ

基本的には次のMSのページの内容を参考に進めていきます。

Azure Pipelines を使用して、関数アプリ コードを継続的に更新する | Microsoft Learn

「Set up build」ボタンを押すとどのようにビルドしますか?みたいな選択画面が出ますが、あとでazure-pipelines.ymlの内容はすべて書き換えるのでなんでもいいので設定します。そして、上記ページを少し改変したものをペーストします。

trigger:
- master

pool:
  vmImage: ubuntu-latest

steps:
- task: UsePythonVersion@0
  displayName: "Setting Python version to 3.10 as required by functions"
  inputs:
    versionSpec: '3.10'
    architecture: 'x64'
- bash: |
    pip install --target="./.python_packages/lib/site-packages" -r ./requirements.txt
- task: ArchiveFiles@2
  displayName: "Archive files"
  inputs:
    rootFolderOrFile: "$(System.DefaultWorkingDirectory)"
    includeRootFolder: false
    archiveFile: "$(System.DefaultWorkingDirectory)/build$(Build.BuildId).zip"
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: '$(System.DefaultWorkingDirectory)/build$(Build.BuildId).zip'
    artifactName: 'drop'

このpipelineは、masterブランチに対してPushされると、pipelineが動くようになっています。ubuntu-latestのイメージを使い、stepの通りにビルドしていきます。本来であればテストなども併せて行うと良いでしょう。

その後、「Save and run」で動かしてみましょう。Jobが実行されるのでしばらく待ちます。Jobに✓が入ればOKです。また、「1 published」を押すと、ビルドした結果のファイルをDLすることができます。ArtifactsはこのあとのReleaseで使います。

ジョブ結果画面

ビルド結果のダウンロード

Releaseのセットアップ

今度はReleaseをセットアップしていきます。releaseはその名の通り、リリースを行います。「Pipelines」からReleasesを選び「New pipeline」をクリックします。

まず、Artifactsから「+ Add」をクリックし、どのartifactからリリースするかを選択します。今回はAzure DevOps内でビルドしているので、Buildを選択します。あとは適当に設定してください。基本そのままでも動くっちゃ動くはずです。

Artifactsの雷マークをクリックすると、トリガーを選択することができます。今回はテストなので、buildされ次第リリースしてしまいます。

続いて、Stagesを選びます。開発環境や本番環境を分けてデプロイするなど柔軟に設定できるようです。今回は面倒なのでいきなりデプロイしてしまいます。「Stages」の「+Add」を選択し、「Deploy a function app to Azure Functions」を選びます。

Jobタスクをクリックすると、Deploy Azure Function Appの設定が行えるます。Azure subscriptonのauthorizeなどを行い設定します。タスクのバージョンは2.*です!なお、App typeはPythonを使っていると、Function App on Linuxになるようです。設定が終わり次第画面上からSaveしましょう。

ここまでくれば一旦手動でリリースしてみましょう。Create releaseのボタンをクリックしReleaseを作成、作成したReleaseの中のStageからデプロイできるはずです。

やったー

動作確認

本番環境にデプロイまでできているはずですので、Azureの画面から確認します。関数アプリの画面の概要から先ほど作成したfunctionが新しくできていることがわかります。

名前をクリックし、関数のURLの取得からURLを取得してアクセスします。今回auth levelをFUNCTIONにしているためAPIKEYのようなパラメーターがURLにくっついています。

VSCodeからソースコードのPushと自動ビルド・デプロイ

色々設定しましたので、VSCode側からソースコードを編集して、リポジトリにPushしてみましょう。やっほーと表示されるよう修正してPushしました。もちろんAzure DevOps側に反映されています。

ビルドのJobも成功しているようです。

リリースも成功しているようです。

画面表示も変わっていました。やったー

以上が一通りの流れです。テスト用の設定はテストが完了したあとに必ず削除しましょう。

最後に

初めてがサーバーレス関連のサービスのお初がAzureでしたが、クラウドサービスのコンポーネントを合わせることで非常に効率的に環境を構築することができました。今までオンプレしか触っておらず、WebはNginxとPHPや!、スケジュール実行はCronや!という世界に住んでいましたが、基盤のメンテナンスをしなくてもいいというのは改めてメリットだなと思います。(HTTPSやったー)

ですが、そこそこハマった落とし穴が多くここまでたどり着くのに多くの時間を使いました。また、各コンポーネントにアクセスするためのネットワークの設定も行う必要がありますが、仮想ネットワークが従量課金プランでは利用できないようで、非常に困っています。今回構築に当たり次の方の記事を拝読させていただきました。本当につらく、私も泣きそうです。AWSだとこうはならないんでしょうか。

zenn.dev

私はセキュリティエンジニアなのでセキュリティ観点でコメントを一応入れておくと、クラウドにおける設定ミスを起因とする事故を見たことがあります。今回私が実際に試してみて、結構複雑でしょうがない一面もあるかもと思ってしまいました。事故の原因としてはミスというシンプルなものですが、問題を解決するために実際にサービスを構築している側がクラウド自体のアーキテクチャを理解し、各設定項目がどのようなリスクを生む可能性があるかを把握するというのはとてつもない作業だと思いました。

クラウドに関する設定ミスを予防するガイドラインや、CSPMのようなミスを検知するような製品もあるにはありますが、製品の仕様とミス起因の脆弱性をうまく見分けられるか甚だ疑問です。(使ったことないので正直良くわからないので有識者の方教えてください。)

フォレンジックタイムライン分析で使えるtimesketch試してみた

はじめに

フォレンジックのタイムライン分析の基盤として利用できるtimesketchを試してみた。試すと今まで分析を行ってきた中での若干のモヤッとが解消されるような気がする。

私はフォレンジックアナリストではないため、細かい表記ゆれや言葉の定義の間違いなどは優しく指摘してほしいです。よろしくお願いします。

きっかけ

いつものようにYamatoSecurityのhayabusaのGithubページを見ていると、分析方法としてtimesketchが紹介されていることに気がついた。

github.com

前から紹介されてたかな〜と思いつつtimesketchについて調べてみると結構面白いことができそうということがわかったのでいろいろ試してみました。

timesketchとは

timesketch.org

timesketchとは複数人でフォレンジックにおけるタイムライン分析を行うためのプラットフォームです。ファイルの書き込み時間や実行時間など膨大なタイムライン情報を複数人で効率的に分析できるようです。

いいところ

  • 各アナリストにアカウントを払い出す事ができる
  • ログに対して★やコメントをつけることができる
  • OpenSearchベースなので、全文検索や”ログへのリンク”を作成することができる
  • SIgmaルールやIoCを登録しておいて、検知させることができる

そして、ちょいちょいメンテナンスされているのがすごい!

試してみた

ユーザーガイドが親切なので一通り目を通しておきましょう。

Uploading timelines - timesketch

インストール

正直公式のインストール手順以外のことはないのでこのブログでは割愛したいと思います。(再構築が面倒というのもあります)

Install - timesketch

データのインポート

構築後にログインすると、Investigationの作成が行なえます。ケースみたいなもので、ログがこのinvestigationごとにまとまるようです。

追加画面

timesketchに追加できるデータは次のとおりです。

  1. .plasoファイル: Plasoと呼ばれるスーパータイムラインを生成するツールでディスクイメージ等をパースすると生成されるDBファイルです。それをそのままuploadできます
  2. CSVjsonファイル: ドキュメントに記載のある通り3つのヘッダー(message, datetime,timestamp_desc)さえあればアップロード可能です。この3種類のヘッダーは.plasoの基本的なスキーマに合わせているようです。なお、それ以外にヘッダーを付けた場合はそのままOpenSearchに取り込まれます

Uploading timelines - timesketch

Import from JSON or CSV - timesketch

今回は特定の攻撃シミュレーションツールをWindows上で動かし、様々な痕跡が残されたディスクイメージに対し、Plasoでスーパータイムラインを生成したていで行きます。

分析画面

結構直感的に使えると思います。左のメニューを押すとそれぞれのログを見ることができる(クエリーに反映される)ので適当に見ていきます。OpenSearchなので全文検索に頼ったほうが良いでしょう。

検索 (mimikatz)

試しにmimikatzと検索しました。大変重要なイベントなので★をつけておきたいと思います。

mimikatz

中のイベントを見てみると、次の図のような感じでした。

mimikatz1

mimikatz2

コンテキストサーチ

コンテキストサーチを行うと、そのログの前のログを見ることができます。これはアナリストにとって非常に嬉しい機能ではないでしょうか。

前後のログを見たいログのから、Context searchを選択します。

画面下半分が切り替わり該当のログから前のログを確認することができます。

Context search

少し見づらいので、REPLACE SEARCHを押し、メインの画面に時間軸をフィルターとして時間軸を設定します。何やらshellbagsに痕跡がありそうです。★しておきましょう。

もちろん★をつけたイベントを対象に検索できます。同様にタグをつけたイベントも検索できるので相当幅広い使い方ができそうです

コメント

イベントにコメントも付けられます。すごい。

アナライザー

まだすべてを把握していないですが、事前に定義されているアナライザーを動かすことができる様子。

Intelligence

IoCを登録しておくことができる。いちいちクエリーを用意しておくよりも便利かもしれない

画面左の虫眼鏡マークから検索画面に遷移することができる。

sigma

sigmaルールを設定することができる。おそらくアナライザーでsigmaというものがあるのでsigmaルールを設定しておいて、アナライザーでtagをつけるという使い方が良さそう。とりあえず適当に作ってみた。

sigma

hayabusaの検知結果を入れてみた

github.com

便利。

注意点

  • 新UIと旧UIが混在しており、使用感はどっちもどっち。検索は新UIのほうが使いやすいが、Sigmaなどは旧UIのほうが便利と感じた
  • 新UIが微妙にバグっておりログへのリンクをコピーのボタンを押すとエラーになる

まとめ

timesketchを試してみましたが、複数人でログを分析し状況を共有できるプラットフォームとしてはなかなかイケてるのではないでしょうか。plasoのみならずcsvファイルなどのインポートもできるためファイアウォールのログやプロキシーのログも格納することでより網羅的な分析ができるようになると思います。

最後に

なにかDFIR関連で面白いものがあれば教えてください

OpenCTI触ってみた

OpenCTIとは

脅威情報を管理するためのプラットフォーム。技術情報と非技術情報を構造化・保存・整理・視覚化をすることができるらしい。

このプラットフォームはSTIX2.1ベースらしいので、STIXの規格については改めて確認したほうが良い。日本語の解説資料求む。

https://docs.oasis-open.org/cti/stix/v2.1/stix-v2.1.html

本記事はOpenCTIのGithubページやドキュメントページを中心に試してみる。

Githubページ: https://github.com/OpenCTI-Platform/opencti

ドキュメントページ: https://docs.opencti.io/latest/

TIP (Threat Intelligence Platform) について

TIPとはその名の通り、脅威情報を収集・集約し活用することができるプラットフォームのことと思われる。正直あまり詳しくないので、PaloAltoのページを読んだところ次のようなことが記載されていた。

A Threat Intelligence Platform (TIP) is a technology solution that collects, aggregates and organizes threat intel data from multiple sources and formats. A TIP provides security teams with information on known malware and other threats, powering efficient and accurate threat identification, investigation and response.

元ページ: https://www.paloaltonetworks.com/cyberpedia/what-is-a-threat-intelligence-platform

DeepL訳

脅威インテリジェンスプラットフォーム(TIP)は、複数のソースやフォーマットから脅威インテリジェンスデータを収集、集約、整理するテクノロジーソリューションです。TIPは、既知のマルウェアやその他の脅威に関する情報をセキュリティチームに提供し、効率的で正確な脅威の特定、調査、対応を支援します。

今回はその中でもOpenCTIというオープンソースのプロダクトを触ってみて、どのように収集され活用することができるのかを調査してみたいと思う

アーキテクチャ

続きを読む