
Douglas-042 HEADQUARTERSコレクター用の中央コンソール。フリートを一括スキャンし、ホスト間で結果を相関させ、IOCフィードとSIEM配信を一元管理します。
WindowsおよびLinuxホストのフリートを侵害の兆候についてスイープし、実際に重要なものを判断し、それに対処する — 1つのコンソールから、ホストごとに1つのコマンドで。
ハントはスキャンではない。Douglasはアナリストが手作業で収集するであろうアーティファクト — プロセス、サービス、スケジュールタスク、オートラン、接続、アカウント、ドライバー、イベントログ、cron、systemd、シェル履歴、Webルート — を収集し、それらに対して201の組み込み検知を実行する。さらに独自のSigma、YARA、カスタムルールも適用できる。
そして、ほとんどのツールがユーザーに任せてしまう部分を担う。どの検知結果がまだ判断を必要としているか、60件の外部アドレスのうちどれを最初に見るべきかを示し、RDPセッションを開くことなくそれに対処できるようにする。
コマンドを1つデプロイ ──▶ ハント ──▶ 検知結果がライブで表示
│
┌──────────────────────┼──────────────────────┐
▼ ▼ ▼
IOCフィード一致 レピュテーションスコア 対応アクション
「これは既知のC2」 「92/100、340件の報告」 隔離 · キル · 収集
最もハンティングを必要とする環境は、しばしばEDRを持たない環境である。数十台のサーバー、エージェントの予算なし、そして3日前に始まったインシデント。選択肢は通常、誰も承認していない商用プラットフォームか、誰かが手作業で実行するPowerShellスクリプトのフォルダかのどちらかだ。
Douglasはその間に位置する。調査対象のホストには何もインストールされない — コレクターは一度実行されて終了する — そしてすべての結果は、次にインシデントを引き継ぐ人に渡せる1つのコンソールに集約される。
検知結果を出すのは簡単だが、読むのは高コストだ。この画面は、3回目のパスでも誰かがまだ読んでいる程度にキューを短く保つために存在する。
3つの結果があり、その違いは6か月後に重要になる:
| 判断 | 動作 |
|---|---|
| 確認済み | 本物。リスクスコアに残り、ホストは赤のまま。 |
| 誤検知 | そのホストのみスコアから除外される。 |
| 抑制 | 今後のすべてのスキャンで同じ検知結果を非表示にする常設ルール。 |
何も削除されることはない。抑制を解除すれば、それが隠していたものすべてが戻ってくる。最もノイズの多いルールが下部にあるのは、それらをチューニングする方が、検知結果を1つずつ処理するよりも速くキューを片付けられるからだ。
201の検知はすべて15のカテゴリにグループ化されている — 1つずつ、またはカテゴリ全体をまとめて切り替えられる。任意のルールをクリックすると、何をチェックするか、正当にどう発火するか、次に何をすべきかが読める。
この画面が明示している区別は、間違えやすいからこそ重要だ:
ルールをオフにすることは、抑制することとは違う。 オフとは、コレクターがそのチェックを実行しないということ — 何も生成されず、レビューするものもない。抑制は検知結果を記録し、誰かが下した判断として理由を添えてマークする。
受け入れたノイズのカテゴリにはオフを使う。特定のホスト上の特定のパターンには抑制を使う。
発火の下のダッシュは通常、健全な答えだ。DGL-014はログがクリアされたように見えるときだけ発火する。このリストはツールがチェックするものであり、何が問題かを示すものではない。
フォームは最初のルールには速く、20番目のルールには遅い。だからルールはテキストとしても書ける — 入力しながら11のアーティファクトテーブルと13のオペレーターに対して検証される。
下のボックスは2つの役割を果たす。ルールが間違っているときは、ルールではなく行を名指しする:
line 7: Condition 1: 'is_maybe' is not an operator.
正しいときは、そのルールが実際に何にマッチするかを告げる — なぜなら、検証は通るのに作者の意図とは別のものにマッチするルールこそ、捕まえる価値のある失敗だからだ:
Valid — ACME-001 Servicesを読み取り、Signedがfalseで、PathNameに'Program Files'が含まれず、PathNameに'System32'が含まれないときにマッチする
JSON、YAML、CSVでインポート・エクスポートできる。ラウンドトリップは保証されている — 私たち自身のエクスポートは、3形式すべてで私たち自身のバリデーターを通過する。
| 問い | タイミング | 結果 | |
|---|---|---|---|
| IOCフィード | このC2リストの何かが私のホスト上にあるか? | ハント中 | DGL-IOC — スコアではなく確認済みの一致 |
15のフィードソースがすぐに使える状態で同梱されている — Feodo、ThreatFox、URLhaus、TweetFeed、USOM、SSL Blacklist、Emerging Threats、OpenPhish、MISP — さらに、インジケーター形式のデータを返す任意のURLを読み取るカスタムフィードも。
4つのレピュテーションプロバイダー: AbuseIPDB、VirusTotal、ThreatFox(無料枠)およびGreyNoise(有料、デフォルトでオフ)。判定が1つの数値に混ぜられることは決してない — AbuseIPDBは苦情を数え、VirusTotalはエンジンを数え、ThreatFoxはインフラを知っており、それらの平均はどれも擁護しない数値だ。バッジは、それを与えたプロバイダーとともに最悪の判定を表示する。
無料枠は保護されている: 結果は12時間キャッシュされ、1回の実行で40アドレス、そしてプロバイダーが止める前に停止する日次カウンター。プライベートアドレスは決して送信されない。
3つのグループに分かれた11のアクション — 見る、行動する、封じ込める。読み取り専用の5つは、ホストを変更する6つとは別にマークされ、すべての変更アクションには書面による理由が必要だ。
隔離は意図的にコンソールへの到達性を保つ: 自身のエージェントから切り離されたホストはリモートで解除できず、誰かがそこまで歩いていかなければならなくなる。侵入を封じ込めるのではなくマシンを壊してしまうターゲット — lsass.exe、systemd、pid 1、Administrator、/bin/bash — は、警告ではなく拒否される。なぜなら、これが使われる瞬間とは、誰も警告を読んでいない瞬間だからだ。
出力はターミナルダンプではなく構造化カードとして返り、行は操作可能だ: プロセスリストには行ごとのKillボタンがあり、アドレスにはReputationがある。
| Windows | Linux | |
|---|---|---|
| Sigma | Event Log + Sysmon | auditd execve + auth/cron/syslog |
| YARA | ファイル内容 | ファイル内容 |
ログソースを読み取れないLinux Sigmaルールは、読み込まれて決して発火しないままにされるのではなく、理由を添えてアップロード時に拒否される — 実行できなかったルールからの空の結果は、クリーンなホストとまったく同じに見えるからだ。
Linuxエージェントは、auditdがインストールされ、実行中で、かつルールが読み込まれているかをチェックし、何が欠けているか、それが何を犠牲にするかを告げる:
Detection capabilities on this host
auditd : NOT RUNNING
Nothing records what executes on this host, so execution
rules cannot fire and a clean result only means the sweep
could not look. Install it:
apt install auditd && systemctl enable --now auditd
3つのグループに分かれた11の送信先:
チャットおよびページングの送信先は、レコードではなく文章をレンダリングし、1つのメッセージに入る検知結果の数を制限する: 100行を貼り付けられるチャネルは、人々がミュートするチャネルだ。
git clone https://github.com/YOURNAME/douglas-042.git
cd douglas-042
pip install -r requirements.txt
uvicorn app.main:app --host 0.0.0.0 --port 8000
またはDockerで:
docker compose up -d
デフォルトのログイン
ユーザー名:
adminパスワード:douglasコンソールは初回サインイン時にパスワード変更を強制する — パッケージに焼き込まれたデフォルトが気づかれずに生き残ってはならない。自分で選びたい場合は、初回起動前に
.envでDOUGLAS_CONSOLE_PASSWORDを設定する。
.envはデータベースが空の間だけ読み込まれる。初回起動後は、python3 -m app.manage passwd adminでリセットする。
起動時に、次のステップのための登録トークンが得られる:
Created the initial admin account: admin
The default password is still in use. Change it at first sign-in.
Enrollment token ready: dgl-enroll-xBAk8...
Douglas-042 console 1.0 ready
Deploy → プラットフォームを選択 → コマンドを1つコピー。
Windows — 管理者権限のPowerShell:
iex (irm 'http://console:8000/api/v1/reports/deploy/script?token=YOUR_TOKEN')
Linux — rootとして:
curl -sSL 'http://console:8000/api/v1/reports/deploy/script?token=YOUR_TOKEN&platform=linux' | sudo bash
6つのステップがターミナルにストリーム表示される: ダウンロード、登録、コレクターの取得、サービスのインストール、稼働確認、初回チェックイン。登録が失敗した場合、何もインストールされず、その旨が表示される。
┌──────────────────────────────────────────────────────────┐
│ Console — FastAPI + SQLite, one process, no queue │
│ triage · findings · graph · rules · response · reports │
└───────────────▲──────────────────────────────────────────┘
│ agents poll: heartbeat 20s, actions 5s
┌───────────────┴──────────────────────────────────────────┐
│ Agent (PowerShell / shell) │
│ └── Collector — runs, reports, exits │
│ 201 built-in rules + Sigma + YARA + your rules │
└──────────────────────────────────────────────────────────┘
Dashboard · Cases · Fleet · Hunts · Response · Findings · Triage · Frequency · Graph · MITRE matrix · Timeline · Diff · Built-in rules · My rules · Sigma · YARA · IOC feeds · Threat intel · Integrations · Schedules · Users · Deploy · Logs & events
Collection integrity · Autoruns and startup · Processes and network · Services and tasks · Persistence mechanisms · Security posture · Drivers and kernel · Execution evidence · Authentication and accounts · Remote access · Sysmon, Kerberos and AD · Files, webshells and exfiltration · User activity and trust · Rootkit and memory · Indicator matches
両方: ローカルアカウントとグループ · 署名とハッシュ付きの実行中プロセス · TCP接続と外部エンドポイント · サービス · 最近書き込まれたファイル · メモリ内コード · Webルートとwebshellパターン
Windows: イベントログ · スケジュールタスク · オートラン · レジストリ永続化 · WMIサブスクリプション · ドライバー · SMB共有 · Prefetch · 証明書ストア
Linux: cron · systemdユニット · シェル起動ファイル · LD_PRELOAD · setuidバイナリ · authorized_keysとsshd設定 · シェル履歴 · 認証ログ · カーネルtaint · WordPress
コンソール: Python 3.11+、6つの依存関係(FastAPI、uvicorn、SQLAlchemy、pydantic、python-multipart、PyYAML)。1 GBのVMで動作する。
Windowsホスト: PowerShell 5.1+、管理者。それ以外は何も不要。
Linuxホスト: bashとcurl。python3でライブ進捗とファイル内容ルールが有効になる。auditdで実行検知が有効になる。どのホストでどれが欠けているかはコンソールが教えてくれる。
0600権限で生成される — パッケージに同梱された固定キーは、ダウンロードした全員に共有されてしまう。📄 テクニカルレポート (PDF) — アーキテクチャ、すべてのコンソール画面、37のコレクターモジュールすべて、検知モデル、対応アクション、セキュリティモデルを網羅する14ページ。
MIT Licenseの下でライセンスされている。LICENSEを参照。
| このホストは60のアドレスと通信した — どれを最初に? |
| ハント後 |
| 92/100、340件の報告、既知のCobalt Strike C2 |
| # | 画面 | これをやる | 得られるもの |
|---|
| 1 | IOC feeds | Feodo Trackerを追加し、Refreshを押す | C2検知 — 書くルールはなし |
| 2 | Threat intel | 無料のAbuseIPDBキーを貼り付け、Testを押す | グラフ上のトリアージ順序 |
| 3 | Fleet | ホストを選択し、Launch hunt | 検知結果、ライブで |
| 4 | Logs & events | モジュールエラーを探す | スイープが実際に見られたかどうか |
| 5 | Triage | キューを処理し、最もノイズの多いルールをチューニング | 誰かがまだ読むリスト |
| 6 | My rules | 6つの例を読み込み、1つを開く | 独自ルールの書き方 |
| 7 | Integrations | Slack webhook、下限をHIGHに | 監視しなくても気づける |