Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
ubuntils — Ubuntuシステムのフォレンジックトリアージ用Python CLI/TUI — アーティファクト収集、タイムライン相関、Wazuh統合により、永続化メカニズムを検出して修復します。 | Kitploit
ツール/GitHubGitHub/asmitdesai/ubuntils
防御ツール侵害指標 (IOC) 管理永続化メカニズム脆弱性分析スクリプトと自動化構成監査フォレンジックデジタルフォレンジックインシデントレスポンスログ分析
GitHubasmitdesai/ubuntils

ubuntils

1483日前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

Ubuntuシステムのフォレンジックトリアージ用Python CLI/TUI — アーティファクト収集、タイムライン相関、Wazuh統合により、永続化メカニズムを検出して修復します。

リポジトリを見る

ubuntils

ライブな Ubuntu システム向けのフォレンジックトリアージ — 5 秒未満で自動化されたアーティファクト収集、永続化検出、ガイド付き修復。

CI Python Tests Coverage License Arch Ubuntu Offline analysis Detection rules SIEM


問題点

Linux システムが侵害された疑いがある場合、最初の 30〜40 分は通常、同じ 10 個のコマンドを順番に実行するのに費やされます。実行中のプロセスを確認し、怪しい cron ジョブを探し、LD_PRELOAD を grep し、authorized_keys に新しいエントリがないかスキャンし、sudoers を監査する。各ステップは手動で、コンテキストスイッチが発生し、プレッシャーの中でミスをしやすいものです。1 つのソースを見落とすと — 例えば /etc/sudoers だけでなく /etc/sudoers.d/ を、あるいは /etc/cron.d/ に加えてユーザーの crontab を — 不完全な全体像しか得られません。

既存の選択肢はこれをきれいに解決しません。lynis はハードニング監査ツールであり、トリアージツールではありません — クリーンなシステムでは設定の弱点を報告し、侵害されたシステムではノイズを生成します。chkrootkit と rkhunter は既知のルートキットシグネチャをチェックしますが、悪用された systemd タイマーや正規に見える cron エントリのような新規の永続化手法には盲目です。汎用の SIEM クエリは、調査対象のシステムに存在しない可能性のあるログ基盤を必要とします。そして Volatility のようなフォレンジックスイートはメモリイメージを対象としており、稼働中のホスト上のライブシェルではありません。

このギャップを埋めるのは、今すぐライブシステム上で動作し、最も一般的な永続化ベクターをカバーし、複数のログソースにまたがるアクティビティをタイムラインに相関させ、外部エージェント、データベース、インターネット接続を必要とせずに、何を調べるべきかを正確に教えてくれるツールです。


ubuntils が行うこと

ubuntils は 4 つの連続したステージで動作します:

  1. 収集 — 11 個のコレクターが /proc、cron テーブル、systemd ユニット、SSH 鍵、sudoers ファイル、環境定義、パッケージ整合性 (dpkg --verify)、PAM/NSS 設定、ロード済みカーネルモジュールからフォレンジックアーティファクトを並行して収集します。一般的なシステムで約 2.5 秒かかります。
  2. 検出 — 検出エンジンが 16 個の組み込みルールすべて — さらに --rules で読み込まれたカスタムルール — を収集されたアーティファクトに対して実行し、約 1 秒でランク付けされた信頼度スコア付きの検出事項リストを生成します。
  3. タイムライン — タイムラインビルダーが syslog、journald、auditd を並行して読み取り、イベントを時系列で相関させ、約 0.3 秒を追加します。その後、各検出事項はタイムラインに対して自動相関され、関連する近傍のイベントを保持します。
  4. 出力 — 結果はインタラクティブな 4 タブ TUI (デフォルト) または stdout 上の構造化 JSON (--json) として表示されます。

ubuntils 自体はネットワーク呼び出しを行わず、すべての機能 — カスタムルールと相関を含む — はローカルに収集されたアーティファクトに対して実行されます。検出事項がホストから出る唯一の方法は Wazuh 統合 です: Wazuh エージェントがインストールされている場合、ライブの scan は検出事項をローカルファイルに書き込み、エージェント がそれをマネージャーに送信します。実行ごとにこれをオフにするには --no-wazuh を渡します。

ubuntils scan は以下のすべてによって変更されていません — 依然として 100% ライブ、単一ホストであり、既存のすべてのフラグは同一に動作します。2 つの追加コマンド collect と analyze は、同じ検出/タイムラインパイプラインを、調査対象のホスト上で直接検出を実行できない (または実行したくない) 場合のためのオフライン対応の取得後分析ワークフローに分割します — 検出カバレッジの注意事項を含め、以下の オフライン分析: collect と analyze を参照してください。


インストール

Ubuntu 22.04+ および PEP 668 を採用する任意のシステム (推奨):

Ubuntu 22.04+ はシステム全体への pip install をブロックします。pipx を使用してください — 環境を透過的に処理するので、意識する必要はありません:```bash sudo apt install pipx -y cd ubuntils pipx install -e . ubuntils scan

root@kitploit:~
**古いシステム / 手動インストール:**```bash
git clone https://github.com/asmitdesai/ubuntils.git
cd ubuntils
pip install -r requirements.txt -e .
ubuntils scan

ubuntils は完全なアーティファクトアクセスに root を必要とします。非 root ユーザーとして ubuntils scan を実行すると、同じ Python インタプリタ(絶対パス指定)を使って自動的に sudo で自身を再起動するため、PATH を root プロセスに引き継ぐことなく正しい環境が使用されます。すべての外部コマンド(ss、dpkg、systemctl など)は、固定された root 所有の検索パスで解決され、あなたの PATH は決して使用されません。root なしで実行すると、/etc/shadow、一部の /proc エントリ、保護された cron ファイルがスキップされ、それぞれについて警告がログに記録されます。


クイックスタート

検出のみ — インタラクティブ TUI:```bash sudo ubuntils scan

root@kitploit:~
**JSON出力をファイルに保存して検出:**```bash
sudo ubuntils scan --json > /tmp/triage-$(hostname)-$(date +%Y%m%d).json

CLIによる修復プレビュー付き検出(ドライラン — 変更は適用されません):```bash sudo ubuntils scan --remediate

root@kitploit:~
**CLI 修復を適用した状態での検出:**```bash
sudo ubuntils scan --remediate --confirm

印刷バージョン:```bash ubuntils version

root@kitploit:~
**改ざん検知可能なバンドルを後で、またはオフラインで分析するために収集する:**```bash
sudo ubuntils collect --output /path/to/bundle.tar.gz

以前に収集したバンドルを分析する(root 権限不要):```bash ubuntils analyze /path/to/bundle.tar.gz --json

root@kitploit:~
**バンドルの代わりに、マウントされたフォレンジックイメージまたは抽出されたファイルシステムツリーを分析する:**```bash
ubuntils analyze --root /mnt/forensic-image --json

バンドル形式と、さらに重要な点として、ライブ scan と比較してオフライン分析では検出できないものについては、オフライン分析: 収集と分析 を参照してください。


フラグと設定```

ubuntils scan [OPTIONS] --json Output JSON to stdout instead of launching the TUI --output FILE Write the JSON report to FILE (implies --json) --remediate Run the remediation engine after detection --confirm Required with --remediate to actually apply changes (else dry-run) --min-confidence N Only auto-remediate findings with confidence >= N (default 40) --no-wazuh Never forward findings to a local Wazuh agent --config FILE YAML allowlist of findings to suppress (see below) --baseline FILE YAML baseline of environment-specific known-good fingerprints to suppress (see below) --since TIME Limit the timeline to events since TIME (e.g. '24h', '7d', '2026-05-20') --rules FILE YAML file of custom detection rules to add (see below) --verbose Verbose structlog output

ubuntils collect [OPTIONS] --output FILE Bundle path to write (default ./ubuntils-bundle-.tar.gz) --verbose Verbose structlog output

ubuntils analyze (BUNDLE | --root PATH) [OPTIONS] --root PATH Analyze a mounted image / artifact tree instead of a bundle --json Output JSON instead of launching the TUI --output FILE Write the JSON report to FILE (implies --json) --config FILE YAML allowlist of findings to suppress (same format as scan) --baseline FILE YAML baseline of environment-specific known-good fingerprints to suppress (same format as scan) --rules FILE YAML file of custom detection rules to add (same format as scan) --since TIME Limit the timeline to events since TIME (e.g. '24h', '7d', '2026-05-20') --verbose Verbose structlog output

ubuntils version Print version string and exit

root@kitploit:~
### 誤検知の許可リスト登録(`--config`)

新しくプロビジョニングされたホストや CI 管理のホストでは、デプロイキー、プロビジョニング用 crontab、組み込みのシェル初期化など、想定内のノイズが発生します。対応担当者にそれを頭の中でフィルタリングするよう教える代わりに、YAML の許可リストで明示的に抑制します:```yaml
# allowlist.yaml
allowlist:
  rules:
    - SHELL_RC_MODIFICATION          # suppress this rule entirely
  paths:
    - /home/ci/.ssh/authorized_keys  # suppress any finding on this exact path

I'm ready to translate the content. Please provide the source text for chunk 25 of 90.```bash sudo ubuntils scan --json --config allowlist.yaml

root@kitploit:~
抑制は常に明示的です — ルールIDおよび/または正確なアーティファクトパスによって行われます。包括的な「すべてを無視する」スイッチはありません。サンプルは [`examples/allowlist.yaml`](https://github.com/asmitdesai/ubuntils/blob/main/examples/allowlist.yaml) にあります。

### 既知の正常なベースライン化 (`--baseline`)

`--config` は、*このコードベースに対して ubuntils を実行する誰に対しても、どこでも* ルールまたはパスを抑制します。`--baseline` はより狭く、環境固有です。つまり、「*この* 環境では、この正確なアーティファクト — この SSH キー、この RC ファイル — は既知の正常である」と述べるもので、同じツールでスキャンする他のすべてのホストに対してルールやパスをミュートすることはありません。`--config` とは別のファイルとして保持されるのは、`--rules` が別であるのと同じ理由です。抑制とルール全体の許可リスト化は、1つのファイルに同居すべきではない異なる関心事です。```yaml
# baseline.yaml
baseline:
  - rule_id: SSH_UNAUTHORIZED_KEY
    fingerprint: ci@ci-runner          # substring match against the finding's raw_value
  - rule_id: SHELL_RC_MODIFICATION
    fingerprint: /home/deploy/.bashrc  # exact match against the finding's artifact_path

I'll analyze the request and provide the translation. However, I notice that the actual content to translate was not included in your message — the INPUT section is empty.

Please provide the Markdown content (chunk 29 of 90) that you'd like me to translate from English to Japanese, and I'll return only the translated text following all the rules you've specified.```bash sudo ubuntils scan --json --baseline baseline.yaml

root@kitploit:~
ベースラインエントリは、`rule_id` と、検出結果の `raw_value` に対する部分文字列として、またはその `artifact_path` に対する完全一致としてテストされる `fingerprint` によって照合されます。一致した検出結果はレポートから完全に除外されますが、抑制が黙って行われることはありません。ベースラインによって削除された検出結果の数は常に `scan_metadata.suppressed_by_baseline` で確認できます。Allowlist (`--config`) による抑制は、ベースライン抑制の上にさらに適用されます。`scan` と `analyze` で同じように動作します。サンプルは [`examples/baseline.yaml`](https://github.com/asmitdesai/ubuntils/blob/main/examples/baseline.yaml) にあります。

### カスタム検出ルール (`--rules`)

`--config` は検出結果を*抑制*し、`--rules` は検出結果を*追加*します。これらは相反する関心事であるため、意図的に別々のファイルになっています。

ルールファイルはパターンマッチのみです。式も条件分岐もコード実行もないため、読み込んでも攻撃者が提供したロジックが実行されることは決してありません。各ルールはアーティファクトの `source`、`match` モード、および `pattern` を指定します:```yaml
# custom_rules.yaml
rules:
  - id: CUSTOM_KNOWN_MINER
    severity: HIGH                     # HIGH | MEDIUM | LOW
    title: Known cryptominer in process cmdline
    description: A running process command line matches a known miner.
    source: process                    # cron | environment | ssh | process | network
    match: substring                   # regex | substring | glob
    pattern: xmrig
  • -p, --port - Port to listen on (default: 8080)
  • -t, --target - Target URL to proxy to (default: http://localhost:80)
  • -c, --config - Path to config file (default: config.yaml)
  • -v, --verbose - Enable verbose logging
  • -h, --help - Show help message```bash sudo ubuntils scan --json --rules custom_rules.yaml
root@kitploit:~
| `source` | 照合対象 |
|---|---|
| `cron` | cron コマンド(path: crontab ファイル) |
| `environment` | 生の環境変数/シェル初期化行(path: 定義ファイル) |
| `ssh` | 鍵の種類、鍵データ、コメント(path: `authorized_keys` ファイル) |
| `process` | プロセスのコマンドライン(path: exe のパス) |
| `network` | 接続の説明(path: `remote_addr:remote_port`) |

`regex` と `substring` はテキスト列にマッチし、`glob` はパス列にマッチします。したがって `203.0.113.*:*` のような `network` の glob はリモートエンドポイントを対象とします。カスタムルールによる検出結果はフラグのみ(自動修復は決して行われない)であり、引き続き `--config` による抑制の対象となります。サンプルは [`examples/custom_rules.yaml`](https://github.com/asmitdesai/ubuntils/blob/main/examples/custom_rules.yaml) にあります。

### レポートの完全性

すべての `--json` レポートには `report_sha256` フィールドが含まれます。これは正規化されたレポート内容に対する SHA-256 です。これにより、収集されたトリアージ成果物が改ざん検知可能になり、ケースファイル内で特定のスキャンをダイジェストで参照できるようになります。レポートはまた、`scan_metadata` の下に `tool_version`、`hostname`、および UTC の `generated_at` タイムスタンプを記録します。`scan` の場合、`hostname`/`ubuntu_version` は `ubuntils` が実行されているマシンを表します。`analyze --root` の場合は、イメージ自身の `/etc/hostname` と `/etc/os-release` から読み取られます。`analyze BUNDLE` の場合は、代わりにバンドル自身のマニフェストから取得されます。つまり、`analyze` を実行しているホストではなく、*収集された*ホストを表し、`collection_run_id` および収集の `collected_at_utc_start`/`collected_at_utc_end` も含まれるため、レポートの保管連鎖記録はアナリストのワークステーションではなく証拠に従います。

**レポートの検証。** レポートは正規形式(キーがソートされ、2 スペースのインデント)で出力され、ダイジェストは `report_sha256` 自体を除くすべてを対象とします:```python
import hashlib, json
doc = json.load(open("report.json"))
claimed = doc.pop("report_sha256")
assert hashlib.sha256(json.dumps(doc, indent=2, sort_keys=True).encode()).hexdigest() == claimed

オフライン分析: 収集と分析

ubuntils scan は、収集、検出、タイムラインをライブホストに対してまとめて実行します。collect と analyze はそのパイプラインを2つに分割します。collect はホストから改ざん検知可能なバンドルを取得し(検出は実行しません)、analyze は scan が使用するのと同じ検出/タイムラインパイプラインを、バンドルに対して、または --root を介してマウントされたイメージに対して実行します。root は不要で、元のホストに再度触れることもありません。これは、アーティファクトを一度取得して、後で、別の場所で、または繰り返し分析したい場合や、稼働中のシステムではなくディスクイメージをトリアージする場合に適しています。

`ubuntils collect````bash

sudo ubuntils collect --output /path/to/bundle.tar.gz

root@kitploit:~
root が必要です。`scan` と同様です。固定のファイルリスト(`/etc/passwd`、`/etc/group`、`/etc/shadow`、`/etc/sudoers`、`/etc/ld.so.preload`、`/etc/environment`、`/etc/crontab`、`/etc/profile`、`/var/log/syslog`、`/var/log/messages`、`/var/log/audit/audit.log`)を読み取り、固定のコマンドリスト(`ss -tunap`、`netstat -tunap`、JSON 形式とテキスト形式の両方での `systemctl list-timers`、および過去 7 日間の `journalctl -o json`)を実行し、キャプチャした各項目をハッシュ化し、すべての内容と `manifest.json` を `.tar.gz` バンドルに書き込みます。キャプチャされたログファイルと journalctl の出力により、`analyze BUNDLE` がオフラインで実際のタイムラインを構築できます。`--output` を省略した場合、バンドルはカレントディレクトリの `./ubuntils-bundle-<UTC timestamp>.tar.gz` に書き込まれます。

### `ubuntils analyze````bash
ubuntils analyze BUNDLE.tar.gz [--json] [--output FILE] [--config FILE] [--baseline FILE] [--rules FILE] [--since TIME]
ubuntils analyze --root /mnt/forensic-image [--json] [--output FILE] [--config FILE] [--baseline FILE] [--rules FILE] [--since TIME]

位置引数としてバンドルパスを取るか、マウントされたイメージ/展開済みファイルシステムツリーを指す --root PATH を取る — 両方は不可。scan で使用されるものと同一の検出エンジン、カスタムルール、許可リスト、ベースラインロジックを実行する。root 権限は不要。バンドルはプライベートな一時ディレクトリに展開され、分析が完了するとすぐに削除される(/etc/shadow を含む可能性がある)。

2つのオフラインモードではカバレッジが異なる。バンドルは collect 時点でキャプチャされた状態をリプレイしたものを保持するのに対し、--root にはマウントされたファイルシステム上に存在するものしかないためである:

  • analyze BUNDLE は collect 時にキャプチャされた実際の ss/systemctl list-timers/journalctl コマンド出力をリプレイするため、NetworkCollector と SystemdCollector はそのスナップショットから本物の検出結果を生成する — スキップされない。タイムラインはバンドルがキャプチャした syslog/messages/audit.log/journalctl から構築されるため、完全に populate され、検出結果は実際の related_events 相関を得る。
  • analyze --root PATH は、クエリ対象となるライブプロセスやカーネル状態が存在しない、停止したマウント済みイメージを指すため、コマンド実行は完全に無効化される:NetworkCollector と SystemdCollector はスキップされ、scan_metadata.command_collectors_skipped に記録される。タイムラインは依然として構築されるが、イメージ上に存在する静的ログファイル(/var/log/syslog、、)から構築される — 停止したイメージをクエリするライブな が存在しないため、ここでは journald リプレイは利用できない。

オフライン検出カバレッジのギャップの完全なリストについては、オフライン分析: collect と analyze を参照。

バンドル形式

バンドルは、すべてが bundle/ プレフィックスの下に置かれた gzip 圧縮された tarball である:``` bundle/ ├── manifest.json ├── files/ │ ├── etc/passwd │ ├── etc/shadow │ ├── var/log/syslog │ └── ... # every captured file, path-flattened under files/ └── commands/ ├── ss.txt ├── netstat.txt ├── systemctl_list_timers_json.txt ├── systemctl_list_timers_text.txt └── journalctl.txt

root@kitploit:~
`manifest.json` スキーマ:

| フィールド | 型 | 説明 |
|---|---|---|
| `run_id` | string | `collect` 実行ごとに新規生成される UUID |
| `host_id` | string | 将来のマルチホスト相関用に予約済み。現在は空 |
| `hostname` | string | 収集時点の `socket.gethostname()` |
| `ubuntu_version` | string | 検出された Ubuntu リリース文字列 |
| `collected_at_utc_start` / `collected_at_utc_end` | string (ISO 8601) | 収集実行の実時間範囲 |
| `tool_version` | string | バンドルを生成した ubuntils のバージョン |
| `files[]` | array | キャプチャしたファイルごとのエントリ: `source_path`、`bundle_path`、`sha256`、`size`、`mtime`、`ctime`(ソースホスト上に存在しない、または読み取り不能なファイルは、収集を中断するのではなく `sha256: ""`、`size: -1` として記録される) |
| `commands[]` | array | キャプチャしたコマンドごとのエントリ: `name`、`argv`、`bundle_path`、`sha256`、`exit_code` |
| `bundle_sha256` | string | マニフェストの残り部分(上記すべてを正規シリアライズしたもの)に対する SHA-256 — バンドル全体の改ざん検知アンカー |

### JSON 出力におけるバンドル整合性

`analyze` の `scan_metadata.bundle_integrity` は次の 3 つの値のいずれかを報告します:

- `"live"` — `scan` および `analyze --root` がこれを報告します。検証すべきバンドルが存在しません。
- `"ok"` — `analyze BUNDLE` が `bundle_sha256` をマニフェストと照合し、さらにキャプチャした各ファイルの SHA-256 をバンドル内の内容と照合して検証しました。`collect` が書き込んで以降、何も改変されていません。
- `"mismatch"` — マニフェストのダイジェスト、キャプチャしたファイルのハッシュ、またはキャプチャしたコマンド出力のハッシュが一致しませんでした。バンドル内の何かが収集後に改変、切り詰め、または破損しており、そこから派生したものはチェーン・オブ・カストディがクリーンであるとして信頼すべきではありません。`analyze` は引き続きレポートを生成しますが、stderr に赤い警告を出力し、TUI の Summary タブの上部に整合性バナーを表示し、**ステータス 3 で終了**します。これにより、スクリプトが改ざんされたバンドルの結果を権威あるものと誤認することがなくなります。

### ⚠️ オフライン解析には実際の検出ギャップがあります — 依存する前にこれを読んでください

**バンドルまたは `--root` をソースとする `analyze` 実行は、ライブの `scan` と検出の同等性を持ちません。** これらはエッジケースではなく、静的でオフラインの取得に伴う構造的な制約であり、影響を受けるルールではエラーではなく、より少ない(またはゼロの)検出結果を生み出します。コレクターが*見られなかったことを認識している*場合(失敗したコマンド、読み取り不能なファイル)、それは `scan_metadata.collectors_degraded` に記録され、TUI の Summary タブでフラグが立てられます — しかし、単にキャプチャされなかったファイルは、存在しないファイルと同じに見えます。(タイムライン自体はもはやこれらのギャップの一つでは*ありません*: `analyze BUNDLE` は `collect` 時点でキャプチャした syslog/messages/audit.log/journalctl を再生し、`analyze --root` はマウントされたイメージ上に存在する静的ログファイルを読み取るため、どちらも実際のタイムラインと実際の `related_events` 相関を生成します — 上記の [`ubuntils analyze`](#ubuntils-analyze) を参照してください。)

- **`PROCESS_MASQUERADE` と `PROCESS_SUSPICIOUS_CONNECTION` は、オフラインモードでは常にゼロ件の検出結果を報告します。** どちらのルールもプロセスの `exe` フィールドに基づいており、これはアーティファクトソースを通じて `/proc/<pid>/exe` シンボリックリンクのターゲットを読み取ることで設定されます(アナリスト自身の `/proc` を読むことは決してありません)。バンドルには読み取るべきライブの `/proc` がなく、`--root` は `/proc` を持たないマウントされたファイルシステムツリーを指します — 現在、解決済みの exe シンボリックリンクターゲットをオフラインでキャプチャまたは再構築するメカニズムは存在しないため、`exe` は常に空となり、ホスト上で実際に何が起きていようと両方のルールは決して発火しません。
- **オフラインではプロセス列挙がまったく行われません。** `collect` には PID ごとのキャプチャステップ(`/proc/*/status`、`/proc/*/cmdline`)がないため、そもそもバンドル内に解析すべきプロセスが存在しません — これは取得側から見た上記の点と同じ根本原因です。
- **`CRON_TMP_PATH`、`SUDOERS_NOPASSWD`、`SSH_UNAUTHORIZED_KEY` は、バンドルをソースとする解析では制限されるか存在しません。** `collect` のファイルリストは静的であり、`/etc/cron.d/*`、`/etc/sudoers.d/*`、`/etc/profile.d/*`、またはユーザーごとの `~/.ssh/authorized_keys` をグロブ展開できません — キャプチャされるのは `/etc/crontab`、`/etc/sudoers`、および `/etc/environment`/`/etc/profile` のみです。(完全にマウントされたファイルシステムツリーに対する `--root` にはこのギャップはありません。実際のディレクトリがディスク上に存在するためです。)`SSH_UNAUTHORIZED_KEY` または `SHELL_RC_MODIFICATION` が*実際に*発火する場合(ライブスキャン、または実際のユーザーごとのディレクトリが存在する状態での `--root`)、これらは mtime だけでなく ctime とファイル内容からも信頼度をスコアリングするようになりました — 下記の [信頼度スコアリング](#json-output) を参照してください。これは発火した検出結果をどれだけ信頼すべきかを改善しますが、オフラインでそもそもルールが発火するかどうかは変わりません。
- **`SUSPICIOUS_SYSTEMD_TIMER` の検出はバンドルでは弱体化します。** サービスユニットはユニットディレクトリ(`/etc/systemd/system`、`/usr/lib/systemd/system`、ユーザーごとの `~/.config/systemd/user` など)から直接読み取られるため、`--root` は完全なサービスカバレッジを得ます。しかしバンドルはこれらのディレクトリをキャプチャしません: タイマーはキャプチャされた `systemctl list-timers` 出力から現れますが、各タイマーの `ExecStart` は `collect` が実行しないユニットごとの `systemctl show` 呼び出しから取得されるため、ルールはバンドルされたタイマーが何を実行するかを評価できません。

**これが重要となる場面:** ライブで到達可能なホストをトリアージする場合は、`sudo ubuntils scan` を使用してください — 完全な検出カバレッジがあります。`collect`/`analyze` は、一度取得して別の場所で解析する必要がある場合、root なしで解析する必要がある場合、または `scan` がまったく選択肢にならないディスクイメージから作業する場合に使用してください — そして上記のルールに対するクリーンな `analyze` 結果は「チェック済みでクリーン」ではなく「未チェック」として扱ってください。

---

## TUI

`sudo ubuntils scan` を実行すると(`--json` なしで)、フルターミナルのインタラクティブ TUI が起動します。

### スキャン画面

コレクターの実行中、ubuntils はライブチェックリストを表示します — コレクターごとに 1 行です。各行はコレクターの完了に合わせてリアルタイムで更新されます:```
Scanning system…

  ✓  Process
  ✓  Network
  ✓  Users
  ⠹  Cron
     Systemd
     SSH
     Sudoers
     Environment

✓ は成功、✗ は失敗、スピナーは実行中のコレクターを示し、空の行は保留中です。すべてのコレクターが完了し、検出とタイムラインが完了すると、TUI は自動的に結果画面に切り替わります。

結果画面

結果画面には 4 つのタブがあり、数字キーで移動します:

q または Ctrl+C を押して終了します。

サマリータブ (キー 1)

スキャンメタデータと主要な検出事項を 1 つの画面に表示します:``` Collectors: 8 run · 0 failed Findings: 2 HIGH · 1 MEDIUM · 0 LOW Timeline: 47 events Duration: 2.8s

● HIGH CRON_TMP_PATH /etc/cron.d/cleanup ● HIGH LD_PRELOAD_INJECT /home/alice/.bashrc ○ MED SSH_UNAUTHORIZED_KEY /home/bob/.ssh/authorized_keys

root@kitploit:~
クリーンなシステムでは、このタブには `System appears clean.` と表示されます。

### Findings タブ(キー `2`)

すべての検出結果を HIGH → MEDIUM → LOW の順に並べたスクロール可能なリストです。検出結果を選択する(Enter キーまたは矢印キー)と、下部に詳細ペインが展開され、完全な説明、アーティファクトのパス、生のトリガー値、および修復情報が表示されます。```
HIGH  CRON_TMP_PATH           /etc/cron.d/cleanup
HIGH  LD_PRELOAD_INJECT       /home/alice/.bashrc
MED   SSH_UNAUTHORIZED_KEY    /home/bob/.ssh/authorized_keys
───────────────────────────────────────────────────────
A cron job was found referencing /tmp, /var/tmp, or /dev/shm.
These directories are world-writable and commonly used as
attacker staging grounds.

Artifact:  /etc/cron.d/cleanup
Raw:       0 * * * * root /tmp/.update
Fix:       Will remove the offending cron entry from
           /etc/cron.d/cleanup after creating a timestamped backup.

R: remediate

TUI 内での修復

自動修復が利用可能な検出結果については、その検出結果を選択した状態で R を押します。確認モーダルが表示されます:``` ┌─────────────────────────────────────────────────┐ │ Remediate CRON_TMP_PATH? │ │ │ │ Will remove the offending cron entry from │ │ /etc/cron.d/cleanup after creating a backup. │ │ Backup will be created at /var/backups/ubuntils/…│ │ │ │ Y: confirm Esc: cancel │ └─────────────────────────────────────────────────┘

root@kitploit:~
`Y` を押して確定します。修復ツールはバックグラウンドスレッドで実行されます。完了すると、リスト内の検出結果の行が `[fixed]` に更新され、詳細ペインに結果が表示されます:```
✓ Remediated
Backup:    /var/backups/ubuntils/20260115_142201/etc_cron.d_cleanup
Rollback:  cp /var/backups/ubuntils/20260115_142201/etc_cron.d_cleanup /etc/cron.d/cleanup

失敗時、詳細ペインにエラーが表示される。バックアップは変更を試みる前に必ず作成される。

Esc を押すと詳細ペインが折りたたまれる。

タイムラインタブ(キー 3)

相関付けられたログイベントのスクロール可能な時系列リスト。各行にはタイムスタンプ、ソース、説明が表示される。イベントは syslog、journald、auditd から取得され、重複排除される。

統計タブ(キー 4)

スキャンのサマリービュー: 検出された Ubuntu バージョン、アーキテクチャ、スキャン所要時間、コレクター数と失敗数、重大度ごとの検出件数、およびタイムラインイベントの総数。


検出する内容

各ルールが存在する理由

CRON_ROOT_EXEC — ユーザーの crontab は crontab の所有者として実行される。sudo や root 所有のインタープリターを呼び出すエントリは、ユーザーが永続的な sudo アクセスを必要とせずに、スケジュールに従って root 権限でコードを実行するよう仕組んだことを意味する。これはパスワード変更後も存続する。

検出例:``` [HIGH] CRON_ROOT_EXEC Title: User crontab executing with sudo Artifact: /var/spool/cron/crontabs/alice Raw value: */5 * * * * sudo /usr/bin/python3 /tmp/beacon.py Remediation: available

root@kitploit:~
**CRON_TMP_PATH** — /tmp や /dev/shm のような誰でも書き込み可能なディレクトリは、攻撃者にとって標準的な足掛かりとなる場所です。そこを指す cron ジョブがあるということは、永続的なパスに一切触れることなく、実行の合間にペイロードを差し替えられることを意味します。これは `@reboot`/`@daily` 形式のエントリや `/etc/cron.{hourly,daily,weekly,monthly}` 内のスクリプトを対象としますが、それらのスクリプトに関する検出結果はフラグのみとなります。シェルスクリプトから 1 行削除することは安全な自動修正ではないためです。

*検出結果の例:*```
[HIGH] CRON_TMP_PATH
Title:         Cron job references writable temp directory
Artifact:      /etc/cron.d/cleanup
Raw value:     0 * * * * root /tmp/.update
Remediation:   available

LD_PRELOAD_INJECT — LD_PRELOAD は、動的リンカに対して指定された共有ライブラリを他のすべてのライブラリより先にロードさせるもので、動的リンクされた任意のバイナリ内で任意の関数をインターセプトできるようにします。標準ライブラリのパス外を指す値は、ほぼ確実にユーザー空間ルートキットの指標です。スペースまたはコロンで区切られたリスト内のすべてのライブラリがチェックされます。/etc/ld.so.preload はすべてのプロセスに注入され、標準の Ubuntu では空であるため、そこにエントリがあれば報告されます — たとえ /lib 内に仕込まれたものであってもです。これはよくあるルートキットの手口です。修復では、/etc/ld.so.preload のエントリをコメントアウトするのではなく削除します。なぜなら、ローダーにはそのファイル内にコメント構文が存在しないからです。

検出例:``` [HIGH] LD_PRELOAD_INJECT Title: LD_PRELOAD set to non-standard library path Artifact: /home/alice/.bashrc Raw value: export LD_PRELOAD=/tmp/.libssl.so Remediation: available

root@kitploit:~
**SUSPICIOUS_SYSTEMD_TIMER** — systemdタイマーは、ほとんどの対応者にとってcronジョブよりも永続的で目立たない。タイマー、あるいはより一般的な永続化手法でありタイマーを全く必要としない単純な`.service`ユニットのExecStartが一時ディレクトリを参照している、またはroot所有でないバイナリを実行している場合、攻撃者によって作成された永続化の兆候である。サービスユニットはユニットディレクトリから直接読み取られ、ユーザーごとの`~/.config/systemd/user`も含まれる。フラグのみ — systemdユニットの削除には人間の判断が必要である。

*検出例:*```
[HIGH] SUSPICIOUS_SYSTEMD_TIMER
Title:         Systemd timer ExecStart points to suspicious path
Artifact:      /etc/systemd/system/update-check.timer
Raw value:     ExecStart=/tmp/.sys/update
Remediation:   not available

SSH_UNAUTHORIZED_KEY — 新たに追加された SSH キーは、パスワードに依存しない永続的なリモートアクセスを許可します。7日間のウィンドウは、古いシステムでの初期プロビジョニングによるノイズを避けつつ、最近の追加を捕捉します。注: このルールはファイルの mtime を使用しており、これは authorized_keys ファイルへの最終書き込みを反映するもので、個々のキーの挿入タイムスタンプではありません。

検出例:``` [MEDIUM] SSH_UNAUTHORIZED_KEY Title: SSH authorized key added in last 7 days Artifact: /home/bob/.ssh/authorized_keys Raw value: ssh-rsa AAAAB3NzaC1... attacker@evil Remediation: available

root@kitploit:~
**SUDOERS_NOPASSWD** — 人間のユーザーアカウント(ログインシェルを持つ UID ≥ 1000)に対するパスワードなしの sudo は、他の永続化メカニズムを削除しても生き残る権限昇格ベクターです。正当な NOPASSWD 付与は、ほぼ常にログインシェルを持たないサービスアカウントに対するものです。グループルール(`%sudo ALL=(ALL) NOPASSWD:ALL`)はそのメンバーに解決され、`#include`/`@includedir` ファイルも追跡されます。グループに関する検出結果はフラグのみです。`%sudo` のようなルールを削除すると、システム上のすべての sudo 付与が削除される可能性があります。

*検出結果の例:*```
[MEDIUM] SUDOERS_NOPASSWD
Title:         NOPASSWD sudo grant for regular user
Artifact:      /etc/sudoers.d/alice
Raw value:     alice ALL=(ALL) NOPASSWD: ALL
Remediation:   available

PROCESS_MASQUERADE — 悪意のあるバイナリを既知のシステムプロセス(sshd、python3、bash)の名前で命名することは、ps 出力での検出を回避するための基本的な手法です。このルールは、/proc/<pid>/status から取得したプロセス名と、/proc/<pid>/exe から解決された実行ファイルパスを相互参照します。標準的な場所には /usr/local/{bin,sbin}、/usr/lib、/usr/libexec、/snap が含まれるため、systemd(/usr/lib/systemd/systemd)や snap パッケージはこれに引っかかりません。フラグのみ — プロセスの強制終了には人間の判断が必要です。

検出例:``` [MEDIUM] PROCESS_MASQUERADE Title: Process masquerading as system binary Artifact: /proc/1337/exe Raw value: name=sshd, exe=/tmp/.sshd Remediation: not available

root@kitploit:~
**USER_UID_ZERO** — UID 0 を保持すべきは `root` のみです。UID 0 にマッピングされた2つ目のアカウント(CIS Ubuntu Benchmark 6.2.x)は高信頼度のバックドアです。これは root 自身の認証情報を変更することなく完全なスーパーユーザー権限を付与し、root パスワードのリセット後も存続します。偽陽性率はほぼゼロです。フラグのみ — UID 0 アカウントの削除には人間の判断が必要です。

*検出例:*```
[HIGH] USER_UID_ZERO
Title:         Non-root account with UID 0
Artifact:      /etc/passwd
Raw value:     toor:x:0:0:...:/bin/bash
Remediation:   not available

USER_EMPTY_PASSWORD — /etc/shadow のパスワードフィールドが空になっているアカウントはパスワードがまったく設定されておらず、Ubuntu のデフォルト PAM スタック(pam_unix ... nullok)ではパスワードなしでログインできてしまいます。ログインシェルを持つアカウントでは、これは開けっ放しの扉です。フラグのみ — 調査中は passwd -l でロックしてください。

検出例:``` [HIGH] USER_EMPTY_PASSWORD Title: Login account with no password Artifact: /etc/shadow Raw value: eve:: Remediation: not available

root@kitploit:~
**PROCESS_SUSPICIOUS_CONNECTION** — 永続化は全体像の半分にすぎません。何とも通信しない足場は、気にかける対象になることはほとんどありません。このルールは、PID によってプロセスコレクターとネットワークコレクターを結合し、フラグが立てられたプロセスが現在の接続を伴って現れるようにします。`/tmp` に配置された実行ファイルが確立済みのアウトバウンドソケットを保持している場合は HIGH です。正規のバイナリが非標準のリモートポートに到達している場合は MEDIUM であり、確認する価値があります。これは現在の状態のスナップショットであり、継続的な監視ではありません。スキャン時にスリープしているビーコンは現れません。フラグのみです。

*検出例:*```
[HIGH] PROCESS_SUSPICIOUS_CONNECTION
Title:         Process with suspicious outbound connection
Artifact:      /proc/1337/exe
Raw value:     203.0.113.9:4444
Remediation:   not available

SHELL_RC_MODIFICATION — シェル初期化ファイルは、ユーザーログインのたびに実行されるため、信頼性の高い永続化ベクターです。このルールは、最近の変更を人間によるレビューのために表面化します。フラグのみ — シェルRCの内容は、それに基づいて行動する前に読む必要があります。

検出例:``` [LOW] SHELL_RC_MODIFICATION Title: Shell init file recently modified Artifact: /root/.bashrc Raw value: mtime=2024-01-15 14:22:01 (6 hours ago) Remediation: not available

root@kitploit:~
**PACKAGE_TAMPERED** — システム所有のバイナリと設定ファイルは信頼の基盤です。このルールは、`dpkg --verify` を使用して、パッケージ所有のファイルが変更、削除されたり、内容/モード/サイズの不一致があることを検出します。Conffile のみの編集(想定されるローカル設定変更)は、ノイズを避けるため報告から除外されます。フラグのみ — 改ざんは正当(ローカルのカスタム編集)または悪意(ファイル置換)である可能性があり、判断には人間の判断が必要です。

*検出例:*```
[HIGH] PACKAGE_TAMPERED
Title:         Package-owned file modified since installation
Artifact:      /usr/bin/sshd
Raw value:     ....5..T. (content and mtime differ)
Remediation:   not available

IMMUTABLE_FLAG_SET — 攻撃者は、rootによるものも含め、変更や削除を防ぐために、また改ざんをさらなる編集やログローテーションから隠蔽するために、ファイルにimmutableフラグ(i)やappend-onlyフラグ(a)を設定することがよくあります。/etc/passwd、/etc/sudoers、/etc/pam.d/*、あるいはauth/syslog/wtmp/btmpログファイルなどの機密性の高いシステムファイルにこれらのフラグを設定することは、攻撃者による堅牢化の強い指標となります。このルールは、lsattrを用いて、その固定された機密パスのリストに対してimmutableフラグとappend-onlyフラグを検出します。フラグのみ — フラグの変更には人によるレビューが必要です。

検出例:``` [MEDIUM] IMMUTABLE_FLAG_SET Title: Sensitive file has an unexpected chattr flag Artifact: /etc/ld.so.preload Raw value: ----i--------e--- Remediation: not available

root@kitploit:~
**PAM_BACKDOOR** — PAM(Pluggable Authentication Modules)と NSS(Name Service Switch)は、Linux における中核的な認証およびアイデンティティシステムです。このルールは mtime ベースの「このファイルが変更されたか」という検出は行いません — ファイルの*内容*をパターンマッチします:(1) 任意の /etc/pam.d/* ファイル内のリテラルな `pam_permit.so` 行(このモジュールは常に成功し、古典的な認証バイパスバックドアです)、または (2) /etc/nsswitch.conf にリストされている NSS モジュールで、ubuntils の組み込み許可リストに含まれていないもの。**注記:** NSS チェックは、組み込み許可リスト外のモジュールを使用しているドメイン参加/SSSD/LDAP/Winbind ホストで誤検知します — この理由により、pam_permit.so の一致よりも意図的に低い信頼度でスコアリングされています;環境に合わせて認識されないモジュール名を許可リストに追加するには `--config` を使用してください。フラグのみ — 認証設定の変更には慎重な検証が必要です。

*検出例:*```
[HIGH] PAM_BACKDOOR
Title:         PAM config unconditionally permits authentication
Artifact:      /etc/pam.d/sshd
Raw value:     auth required pam_permit.so
Remediation:   not available
root@kitploit:~
[HIGH] PAM_BACKDOOR
Title:         Unexpected NSS module in nsswitch.conf
Artifact:      /etc/nsswitch.conf
Raw value:     passwd: files evilmod
Remediation:   not available

KERNEL_MODULE_SUSPICIOUS — カーネルモジュールはリング0で無制限のアクセス権を持って動作します。攻撃者はrootkit、パケットスニッフィング、プロセス隠蔽のためにカスタムカーネルモジュールを頻繁にロードします。このルールは、現在ロードされているモジュールを、想定される組み込みモジュール(ほとんどのシステムに共通)の小さな許可リストと比較します。この許可リストは意図的に狭く設定されているため、重要度はLOWです。注: GPUドライバー、Wi-Fiカード、プロプライエタリドライバーを搭載したハードウェア重視のホストでは、誤検知が発生します。対応担当者は、--configを介してホストで想定されるモジュールを追加し、モジュール名(artifact_pathとして使用)で許可リストに登録する必要があります。フラグのみ — カーネルモジュールの調査にはフォレンジックツールと人間の専門知識が必要です。

検出例:``` [LOW] KERNEL_MODULE_SUSPICIOUS Title: Loaded kernel module not in the expected set Artifact: implant_rootkit Raw value: {'name': 'implant_rootkit', 'size': '12288', 'used_by': []} Remediation: not available

root@kitploit:~
**SETUID_INVENTORY** — setuid および setgid バイナリは、実行時に自動的に権限を昇格させます。攻撃者は、権限昇格を永続化するためにカスタムの setuid/setgid バイナリを作成します。ほとんどの場合、標準のシステムバイナリディレクトリの外側(/opt のような一般的なインストールパス、ユーザー自身の /home、/srv、または誰でも書き込み可能な一時ディレクトリ)に作成されます。このルールは、`find -perm -4000 -o -perm -2000` を使用して `/usr /bin /sbin /opt /home /srv /tmp /var/tmp /dev/shm` 全体で setuid/setgid バイナリをインベントリし、正当なシステムユーティリティの既知のベースラインセットに含まれないものを検出します。フラグのみ — 予期しない setuid/setgid バイナリは調査が必要ですが、アプリケーションがインストールした正当なバイナリである可能性もあります。

*検出例:*```
[LOW] SETUID_INVENTORY
Title:         Unexpected setuid binary
Artifact:      /tmp/.hidden/backdoor
Raw value:     setuid
Remediation:   not available

JSON 出力

--json は単一の JSON オブジェクトを stdout に書き出します。それ以外は何も出力されません。```json { "scan_metadata": { "tool_version": "2.1.0", "hostname": "web-01", "generated_at": "2026-06-10T08:22:03.114523+00:00", "ubuntu_version": "Ubuntu 22.04.3 LTS", "architecture": "x86_64", "duration_s": 2.84, "collector_failures": 0, "bundle_integrity": "live", "command_collectors_skipped": [], "collectors_degraded": {}, "rules_failed": [], "timeline_error": null, "suppressed_by_baseline": 1 }, "artifact_counts": { "ProcessCollector": 142, "NetworkCollector": 23, "UserCollector": 4, "CronCollector": 7, "SystemdCollector": 12, "SSHCollector": 3, "SudoersCollector": 5, "EnvironmentCollector": 18 }, "findings": [ { "rule_id": "CRON_TMP_PATH", "severity": "HIGH", "title": "Cron job references writable temp directory", "description": "A cron job was found referencing /tmp, /var/tmp, or /dev/shm. These directories are world-writable and commonly used as attacker staging grounds.", "artifact_path": "/etc/cron.d/cleanup", "raw_value": "0 * * * * root /tmp/.update", "remediation_available": true, "remediation_description": "Will remove the offending cron entry from /etc/cron.d/cleanup after creating a timestamped backup.", "related_events": [ { "timestamp": "2024-01-15T08:20:00+00:00", "source": "syslog", "description": "CRON[2841]: (root) CMD (/tmp/.update)" } ], "confidence": 75, "confidence_band": "HIGH", "signals": [ {"name": "timeline_corroboration", "weight": 25, "detail": "1 nearby timeline event(s)"} ] }, { "rule_id": "PROCESS_MASQUERADE", "severity": "MEDIUM", "title": "Process masquerading as system binary", "description": "Process 'sshd' (pid=1337) has exe path outside standard binary directories: /tmp/.sshd", "artifact_path": "/proc/1337/exe", "raw_value": "/tmp/.sshd", "remediation_available": false, "guided_remediation": "Confirm pid 1337 is malicious (ls -l /proc/1337/exe, cat /proc/1337/cmdline), then terminate it: kill -9 1337.", "confidence": 50, "confidence_band": "MEDIUM", "signals": [] } ], "timeline": [ { "timestamp": "2024-01-15T08:22:01+00:00", "source": "syslog", "description": "sshd: Accepted publickey for alice from 10.0.0.42 port 52341" } ], "report_sha256": "a3f1c9…(64 hex chars)" }

root@kitploit:~
`remediation_results` は `--remediate` が渡されたときにのみ、追加のトップレベルキーとして現れる。`report_sha256` は常に存在し、ドキュメントの残りの部分に対して計算される。`scan_metadata.bundle_integrity` は `scan` および `analyze --root` では `"live"`、`analyze` に渡された検証済みバンドルでは `"ok"`、バンドルの内容がマニフェストと一致しない場合は `"mismatch"` となる — [Bundle integrity in JSON output](#bundle-integrity-in-json-output) を参照。`scan_metadata.command_collectors_skipped` は `--root` 実行でスキップされたコマンドベースのコレクター(`NetworkCollector`、`SystemdCollector`、`PackageCollector`、`KernelCollector`)を列挙する — `scan` および `analyze BUNDLE` では常に空。`scan_metadata.suppressed_by_baseline` は `--baseline` ファイルがこのレポートから除去した検出結果の数である — [Known-good baselining](#known-good-baselining---baseline) を参照。`scan_metadata.collectors_degraded` はコレクター名をそのデータが不完全である理由(失敗またはタイムアウトしたコマンド、読み取り不能なファイル、スキップされた不正な行)にマッピングし、`rules_failed` はクラッシュした検出ルールを列挙し、`timeline_error` はタイムラインを構築できなかった場合に設定される。健全な実行ではこれら3つはすべて空である。空の検出結果リストを「クリーン」と読む前に、これらを確認すること。

`related_events` と `guided_remediation` は、内容がある場合にのみ検出結果に現れる。`related_events` は、アーティファクトパスとルールキーワードによって検出結果にマッチした最大5件のタイムラインイベントを、最新順に保持する — これは表面化の補助であり、因果関係の主張ではない。`guided_remediation` は手動で実行するためのレビュー済みコマンドシーケンスであり、ubuntils がそれを実行することは決してない。

### Confidence scoring

すべての検出結果は `confidence` スコア(0〜100、デフォルト50)と `confidence_band`(`HIGH` ≥ 75、`MEDIUM` ≥ 40、それ未満は `LOW`)、さらにそのスコアがどのように算出されたかを正確に示す `signals` リストを持つ — 各エントリは `{"name", "weight", "detail"}` であり、スコアは常に説明可能で、決してブラックボックスではない。シグナルはベース信頼度50に加算され、それを生成したルールまたはパイプラインステージによって適用される:

- 検出ルールは検出時に独自のシグナルを適用する — 例えば `SSH_UNAUTHORIZED_KEY` と `SHELL_RC_MODIFICATION` は、アーティファクトの内容が既知の危険なパターン(危険な SSH キーオプション、シェル RC ファイル内の curl/wget-to-shell 行または base64-decode 行)に一致する場合に `content_match`(+30)を、ファイルの ctime も検出ウィンドウ内にある場合(mtime 単独より偽造が難しい)に `ctime_corroborates_mtime`(+20)を、または新しさが*唯一の*シグナルで ctime がそれを裏付けない場合に `mtime_only`(−20)を追加する — これは mtime が遡って改変された可能性があるという手がかりである。
- パイプラインは、検出結果↔タイムラインの相関の後、検出結果に1つ以上の `related_events` がある場合に `timeline_corroboration`(+25)を適用する。

`LOW` バンドの検出結果は却下されたり隠されたりしない — 他の検出結果とまったく同様に検出結果リストと JSON 出力に現れる — ただし、さらに調査する前にそれにどれだけの重みを置くべきかをバンドが示す。これは `SSH_UNAUTHORIZED_KEY`/`SHELL_RC_MODIFICATION` に対する旧来の mtime のみのヒューリスティックを置き換えるもので、そこでは古いが正当に触れられたファイル(例えば実行のたびに `.bashrc` を書き換える構成管理ツール)が、真に新しいバックドアと同一に見えていた。

**既知の制限:** 現在有効なのはコンテンツパターンと ctime のシグナルのみである。所有権/フィンガープリントベースのシグナル — 未知の SSH キーフィンガープリント、キーの `from=` 制限オプション、または RC ファイルの所有者/モードの不一致(`ownership_anomaly` シグナル)— はまだ実装されていない。これは将来のリリースに向けて追跡されている延期されたカバレッジギャップであり、現在の信頼度スコアが考慮しているものではない。

---

## Remediation

16の検出ルールのうち5つが自動修復を持つ:`CRON_ROOT_EXEC`、`CRON_TMP_PATH`、`LD_PRELOAD_INJECT`、`SSH_UNAUTHORIZED_KEY`、`SUDOERS_NOPASSWD`。残りはフラグのみで、自動修復されることは決してない。なぜなら、それらに安全に対処するには人間がまず確認する必要があるからである。

### Guided remediation

`SUSPICIOUS_SYSTEMD_TIMER`、`PROCESS_MASQUERADE`、`SHELL_RC_MODIFICATION` は `guided_remediation` 文字列を持つ:検出結果を確認した後に実行すべき正確なコマンド — `systemctl disable --now <unit>`、`kill -9 <pid>`、または RC ファイルのレビューと復元。これは TUI の詳細ペインと JSON に表示される。ubuntils があなたの代わりにそれを実行することは決してない;これらのルールは設計上 `--remediate --confirm` の一括処理から除外されている。

### In the TUI

Findings タブで修復を持つ任意の検出結果を選択し、`R` を押す。確認モーダルが計画されたアクションをプレビューする。`Y` を押して適用する — 修復ツールはバックグラウンドスレッドで実行されるため、TUI は応答性を保つ。完了すると検出結果の行が `[fixed]` に更新され、バックアップパスと正確なロールバックコマンドがインラインで表示される。

### From the CLI

`--confirm` なしの `--remediate` は安全なドライランである:バックアップが作成され検証が実行されるが、変更は適用されない。実際に変更を加えるには両方のフラグを渡す。このモードではパイプラインは TUI の起動前に実行され、Summary タブにすべての修復結果がそのバックアップパスとロールバックコマンドとともに一覧表示される。

`--remediate --confirm` は信頼度スコアが少なくとも40(MEDIUM バンド)の検出結果にのみ作用する — 低信頼度で mtime のみの `SSH_UNAUTHORIZED_KEY` は、そのキーを削除されるのではなく `SKIPPED` として報告される。ゲートは `--min-confidence N` で調整する。```bash
sudo ubuntils scan --remediate          # dry run
sudo ubuntils scan --remediate --confirm # apply changes, then open TUI
sudo ubuntils scan --remediate --confirm --min-confidence 75  # only HIGH-confidence findings

セーフガード

すべての修復は、どのようにトリガーされたかに関係なく同じパターンに従います。

  1. アーティファクトパスがシンボリックリンクかどうかを検出し、そうであれば拒否する(攻撃者が制御するシンボリックリンクを介した root による書き込みを防ぐ)
  2. /var/backups/ubuntils/YYYYMMDD_HHMMSS/ にモード 0700 でタイムスタンプ付きバックアップを作成する
  3. 現在の状態を検証する(該当行がまだ存在している必要がある)
  4. 最小限の変更のみを適用する — cron エントリとキーは 1 行ずつ削除、シェル初期化ファイル内の LD_PRELOAD 行はコメントアウト、/etc/ld.so.preload 内のエントリは削除(ローダーにはそこにコメント構文がないため、コメントアウトされたエントリでも読み込まれてしまう)。sudoers については、編集後の内容が実際のファイルに触れる前に一時コピーに対して visudo -cf でチェックされる
  5. アトミックに書き込む — 新しい内容は元のファイルの隣の一時ファイルに書き込まれ(同じモードと所有者)、fsync された後に元のファイルにリネームされるため、書き込み途中でクラッシュしても切り詰められた /etc/sudoers が残ることはない
  6. 該当行が消えたことを検証する

いずれかのステップが失敗した場合、修復は即座に停止し、システムは変更されないまま、バックアップパスとロールバックコマンドを含む完全なエラーが報告されます。sudo アクセスは 2 つの方法で保護されています。%group NOPASSWD ルール(%sudo など)はフラグのみで自動削除されることはなく、sudoers 修復機能はメインの sudoers ファイルから最後のルールを削除することを拒否します。


Wazuh 連携

ubuntils は単一ホスト、特定時点のトリアージ用に作られています — 何かおかしいとすでに疑っているときに実行するもので、外部に通信したり、スキャン終了後も監視を続けたりすることはありません。これは意図的な設計ですが、つまり ubuntils の検出結果は、何かが引き継がない限りその 1 つのレポートの中にしか存在しないということでもあります。ある程度の規模で Ubuntu を運用しているチームのほとんどは、検出の継続的な側面を担う SIEM をすでに導入しているため、ubuntils を独自の長時間稼働する監視エージェントとして作り込むのではなく、おそらくすでに運用しているであろうもの、つまり Wazuh に検出結果を引き渡します。

ホスト上に Wazuh エージェントが存在する場合(/var/ossec/bin/wazuh-agentd または /var/ossec/etc/ossec.conf が存在する)、ubuntils scan(--no-wazuh を付けて実行しない限り)は各検出結果を 1 行の JSON として /var/log/ubuntils/wazuh-alerts.json に追記し、エージェントがそれを取得します — これは純粋なフォワーダーであり、Wazuh モジュールではありません。ネットワーク呼び出しも API キーもなく、ubuntils がすでに行っているのと同じローカルアーティファクトの書き込みだけです — ただし、エージェントは当然それらの行をホスト外のマネージャーへ送信します。それが目的です。フラグは不要で自動検出されます(実行をオプトアウトするには --no-wazuh を使用)。そのため、エージェント登録済みホストのフリート上でスクリプトまたはスケジュールされた ubuntils scan を実行すると、追加の配線なしで即座に SIEM へ供給され始めます。これはオフラインの ubuntils analyze(バンドルまたは --root)では決して発生しません。これらの検出結果は、ローカルの Wazuh エージェントを実行しているホストとは別のホストを記述しているためです — バンドルの検出結果をアナリスト自身のエージェントに転送すると、誤ったマシンに帰属させてしまいます。

意図は、ubuntils を既存のアラート/エスカレーションパイプラインに組み込むことであり、対応担当者に 2 つ目のツールの面倒を見させることではありません。以下のサンプルルールを読み込めば、HIGH 重大度の ubuntils 検出結果(新しい UID-0 アカウント、LD_PRELOAD ルートキット、PAM バックドア)は通常の Wazuh アラートとして表示され、マネージャーがすでに設定している通知ルーティングを継承し、誰かが確認するのを忘れないようにしなければならない独立した JSON ファイルではなく、同じタイムライン上の他のすべてのシグナルと並んで存在します。

Wazuh にこれらの検出結果を解析させアラートを出させるには、examples/wazuh/ のサンプルルールを Wazuh マネージャーにコピーし、examples/wazuh/ossec_localfile_snippet.xml の <localfile> ブロックをエージェントの /var/ossec/etc/ossec.conf に追加します。カスタムデコーダーのインストールは不要です。localfile は log_format json で設定されているため、Wazuh の組み込み JSON デコーダーが各行を解析し、すべてのトップレベル JSON キー k を data.k にマッピングし、local_rules.xml がそれを直接マッチさせます。

  1. examples/wazuh/local_rules.xml → マネージャーの /var/ossec/etc/rules/
  2. examples/wazuh/ossec_localfile_snippet.xml の <localfile> ブロック → エージェントの /var/ossec/etc/ossec.conf
  3. 両方を再起動: systemctl restart wazuh-manager(マネージャー)、systemctl restart wazuh-agent(エージェントホスト)

これらは出発点として提供されるサンプルテンプレートにすぎません — 実際の Wazuh マネージャーに対してテストされておらず、依存する前に非本番環境で検証する必要があります。

1 行あたりの JSON スキーマ:


コレクター

コレクターの依存関係

PackageCollector はライブホスト上に 3 つの標準 Ubuntu ツール(dpkg、lsattr、find — いずれも標準の Ubuntu インストールに存在)を必要とします。いずれかのコマンドが利用できない場合、PackageCollector はクラッシュせずにその部分について空のデータを生成します。オフライン分析(analyze BUNDLE)は collect 時にキャプチャされたコマンド出力を再生するため、アナライザーのホスト上でのコマンドの可用性は必要ありません。

setuid/setgid の find スキャンは -xdev を渡して範囲を限定します — 別々にマウントされたファイルシステム(/opt 配下の別個のマウント、NFS マウントされた /home など)には降りていきません。これは意図的な実行時間とカバレッジのトレードオフです。-xdev がないと、スキャンがネットワークマウントや仮想ファイルシステムのスキャンでハングする可能性があります。環境がこれらのパスを別々のファイルシステムにマウントしている場合、それらがスキャンされないことに注意してください。

dpkg --verify と setuid/setgid の find スキャンは、寛大な非デフォルトのタイムアウト(それぞれ 10 分と 5 分、ubuntils/collectors/packages.py を参照)を使用します。これは、大規模なパッケージデータベースやファイルシステムツリーを持つ実際のホストでは、どちらもライブラリのデフォルトである 30 秒を正当に超えて実行される可能性があるためです。ubuntils collect は、これらのコマンドをバンドルにキャプチャする際に同じタイムアウトを使用します。


互換性

サポート対象
Ubuntu20.04、22.04、24.04
アーキテクチャamd64、arm64
Python3.9+
権限完全なアーティファクトアクセスには root が必要

root なしで実行すると、警告付きの部分的なスキャンになります。/etc/shadow、保護された crontab ディレクトリ、一部の /proc エントリなどの重要なパスはスキップされます。


ロードマップ

v1.0.0

  • 全 8 コレクター
  • 全 8 検出ルール
  • タイムラインビルダー(syslog、journald、auditd)
  • コレクターごとの ✓/✗ を表示するライブスキャン進捗画面
  • インタラクティブな 4 タブ TUI(Summary / Findings / Timeline / Stats)
  • 確認モーダルとバックグラウンドワーカーを備えた TUI 内修復
  • JSON 出力モード
  • バックアップ、ロールバック、シンボリックリンクガードを備えた 5 ルールの CLI 修復
  • Ubuntu 20.04/22.04/24.04 サポート
  • 90% カバレッジで 240 テスト

v1.1.0

  • ルール ID またはパスによる誤検出の許可リスト登録(--config)
  • レポートを直接書き込む --output FILE
  • --since によるタイムラインの時間枠指定
  • 改ざん検知可能なレポート(report_sha256、hostname、timestamp)
  • USER_UID_ZERO 検出ルール

v1.5.0

  • YAML によるカスタムパターンマッチ検出ルール(--rules)
  • PROCESS_SUSPICIOUS_CONNECTION — PID によるプロセス↔ネットワークの相関
  • 検出結果↔タイムラインの自動相関(related_events)
  • 判断を要する 3 つのルールに対するガイド付き修復
  • 92% カバレッジで 282 テスト

VirusTotal のハッシュ検索と MISP IOC エクスポートはこのリリースから削除されました。VirusTotal は既知のハッシュにしか答えません — これは rkhunter がすでにカバーしているケースであり、ubuntils が狙う新規技術のギャップとは正反対です — そして両機能とも、ネットワーク呼び出しを一切行わないことに価値があるツール内にネットワーク呼び出しを持ち込むことになっていました。ubuntils 自体は依然としてネットワーク呼び出しを行いません(検出結果がホストを離れる唯一のオプトアウト可能な方法については、Wazuh 連携を参照してください。これはローカルエージェント経由です)。

v2.0.0 — オフライン collect/analyze 分割

  • ubuntils collect — ライブホストから改ざん検知可能なバンドル(manifest.json + ハッシュ化されたファイル/コマンド)を取得、検出は行わない
  • ubuntils analyze (BUNDLE | --root PATH) — バンドルまたはマウントされたイメージに対して scan と同じ検出/タイムラインパイプラインを実行、root 不要
  • bundle_integrity(live/ok/mismatch)を scan_metadata に表示
  • オフラインモードでの検出カバレッジのギャップを文書化(PROCESS_MASQUERADE、PROCESS_SUSPICIOUS_CONNECTION、および cron/sudoers/SSH の glob パスと systemd タイマーの のカバレッジ低下)

v2.1.0 — SIEM 転送

  • ライブ ubuntils scan の検出結果をローカル Wazuh エージェントへ JSONL として転送、自動検出(フラグ不要)
  • サンプル Wazuh デコーダー/ルールと ossec.conf の <localfile> スニペット(examples/wazuh/)
  • 転送は意図的にライブ scan のみに限定 — オフライン analyze 中には決して発火しない。バンドルやイメージはエージェントを実行しているホストとは別のホストを記述しているため
  • スキャンを転送からオプトアウトする --no-wazuh

v2.1.0 — ハードニング(コードベース全体の監査)

  • セキュリティ: sudo 再実行が呼び出し元の PATH を転送しなくなり、コマンドは固定された安全なパスで解決される。sudoers の編集はファイルに触れる前に visudo でチェックされる。アトミックな修復書き込み。シンボリックリンク安全なレポート/バンドル出力。analyze 後に展開されたバンドルを削除
  • 検出カバレッジ: /etc/ld.so.preload の解析、@reboot/@daily cron エントリと /etc/cron.{hourly,daily,weekly,monthly} スクリプト、systemd .service ユニットと非 root 所有の ExecStart バイナリ、%group sudoers ルールと #include/@includedir、LD_PRELOAD リストのすべての要素
  • 新しい ルール(パスワードのないログインアカウント)

v3.0.0 / v4.0.0(探索的)

  • マルチホストトリアージ用の Web ダッシュボード
  • macOS サポート

コントリビューション

現在最も有用なコントリビューションは、新しい検出ルール(detectors/rules.py にスタンドアロン関数として追加し、対応するテストを付ける)、まだカバーされていないアーティファクトタイプ用の追加コレクター、SUSPICIOUS_SYSTEMD_TIMER と SHELL_RC_MODIFICATION 用の修復モジュール(どちらも現在は設計上フラグのみですが、安全な自動修復パスが存在する可能性があります)、特定の Ubuntu 構成におけるエッジケースのテストケース、およびドキュメントの改善です。

大規模なコントリビューションを始める前に、作業の重複を避けるために issue を開いてください。


ライセンス

MIT


作者

Asmit によって作成 — BTech Computer Science、PES University、ベンガルール。このツールは、手動の Ubuntu トリアージにかかる時間が、適切にスコープされたスクリプトで自動化できるものと比べてどれほど長いかというフラストレーションから生まれました。

ツールをダウンロード
/var/log/messages
/var/log/audit/audit.log
journalctl
キータブ内容
1サマリースキャン統計 + 主要な検出事項の概要
2検出事項インライン詳細と修復手順を含む完全な検出事項リスト
3タイムライン時系列で相関付けられたログイベント
4統計Ubuntu バージョン、アーキテクチャ、所要時間、コレクター数
ルール ID重大度修復可能チェック内容
CRON_ROOT_EXECHIGHはいroot 所有のパスでコマンドを実行する、または sudo をインライン化している非 root ユーザーの crontab
CRON_TMP_PATHHIGHはい*/tmp、/var/tmp、/dev/shm を参照する任意の cron ジョブ(@reboot/@daily エントリや /etc/cron.{hourly,daily,weekly,monthly} 内のスクリプトを含む)。*スクリプト行はフラグのみ
LD_PRELOAD_INJECTHIGHはい/etc/ld.so.preload 内の任意のエントリ(素の Ubuntu では空)、または任意のシェル初期化ファイル内の LD_PRELOAD で、/lib、/usr/lib、/lib64、/usr/lib64 外のライブラリを列挙しているもの
SUSPICIOUS_SYSTEMD_TIMERHIGHいいえExecStart が誰でも書き込み可能なディレクトリを参照している、または root 所有でないバイナリを実行している systemd タイマーおよびサービスユニット
SSH_UNAUTHORIZED_KEYMEDIUMはい過去 7 日以内に変更された authorized_keys ファイル
USER_UID_ZEROHIGHいいえroot 以外で UID 0 のアカウント(隠された 2 人目のスーパーユーザー)
USER_EMPTY_PASSWORDHIGHいいえ/etc/shadow のパスワードフィールドが空のログインシェルアカウント(Ubuntu のデフォルト PAM nullok によりパスワードなしでログインできる)
SUDOERS_NOPASSWDMEDIUMはい*UID ≥ 1000 かつログインシェルを持つユーザーに対する NOPASSWD sudoers 許可(直接または %group ルール経由)。インクルードされたファイルも追跡される。*グループルールはフラグのみ(%sudo を削除するとすべての sudo アクセスが失われる可能性がある)
PROCESS_MASQUERADEMEDIUMいいえ名前が既知のシステムバイナリと一致するが、実行ファイルが標準システムディレクトリ(/usr/bin、/usr/sbin、/bin、/sbin、/usr/local/{bin,sbin}、/usr/lib、/usr/libexec、/lib、/snap)外にあるプロセス
PROCESS_SUSPICIOUS_CONNECTIONHIGH / MEDIUMいいえ実行ファイルが誰でも書き込み可能な一時ディレクトリにある、またはディスクから削除されている(HIGH)、あるいは標準システムディレクトリ外にある、または非標準のリモートポートと通信している(MEDIUM)アウトバウンド接続を保持するプロセス
SHELL_RC_MODIFICATIONLOWいいえログインシェルを持つ任意のユーザーのシェル初期化ファイル(bashrc、profile、zshrc など)が過去 48 時間以内に変更されている
PACKAGE_TAMPEREDHIGHいいえシステム所有のパッケージファイルが変更、欠落、または内容/モード/サイズがパッケージマニフェストと一致しない(dpkg --verify 経由)
IMMUTABLE_FLAG_SETMEDIUMいいえ/etc/passwd、/etc/sudoers、/etc/pam.d/* などの機密ファイルに設定された immutable(i)または append-only(a)フラグ(lsattr 経由で検出)
PAM_BACKDOORHIGHいいえ任意の /etc/pam.d/* ファイル内のリテラルな pam_permit.so 行、または /etc/nsswitch.conf 内の許可リスト(files/sss/ldap/winbind/...)外の NSS モジュール
KERNEL_MODULE_SUSPICIOUSLOWいいえ一般的な組み込みモジュールの許可リスト外のロード済みカーネルモジュール — 注意: ハードウェアの多いホスト(GPU、Wi-Fi カード、プロプライエタリドライバー)では誤検知が発生する。--config で期待されるモジュールを追加すること
SETUID_INVENTORYLOWいいえ既知のベースラインセット外の予期しない setuid または setgid バイナリ(2 つのビットは個別にチェックおよび報告される)
フィールド型説明
timestampstring (ISO 8601)検出結果が転送された時刻
hostnamestringスキャンされたホスト
rule_idstringubuntils の検出ルール ID と一致(上記の検出ルール表を参照)
severitystringHIGH | MEDIUM | LOW
titlestring短い人間が読めるタイトル
descriptionstring検出結果の完全な説明
artifact_pathstring問題が見つかったファイル/リソースのパス
raw_valuestringルールをトリガーした生の行/値
remediation_availableboolubuntils にこのルールの修復機能があるかどうか
related_eventsarray (optional)相関付けられたタイムラインイベント(存在する場合)
コレクター収集するアーティファクト
ProcessCollector/proc および ps 出力からの実行中プロセス
NetworkCollectorss/netstat からの開いている接続とリスナー
UserCollector/etc/passwd、/etc/shadow、/etc/group
CronCollector/etc/cron* ディレクトリと /var/spool/cron/crontabs/*
SystemdCollectorsystemctl list-timers および list-units 出力
SSHCollector全ユーザーの ~/.ssh/authorized_keys
SudoersCollector/etc/sudoers と /etc/sudoers.d/ 配下のすべてのファイル
EnvironmentCollector/etc/environment、/etc/profile.d/*、ユーザーのシェル初期化ファイル
PackageCollectordpkg --verify によるシステムパッケージの整合性、lsattr による immutable フラグ属性、find による setuid/setgid バイナリ
PamCollector/etc/pam.d/* ファイルと /etc/nsswitch.conf
KernelCollectorlsmod によるロード済みカーネルモジュール
ExecStart
  • 信頼できる検出: 信頼度スコアリング(confidence/confidence_band/signals)、--baseline 抑制、SSH_UNAUTHORIZED_KEY/SHELL_RC_MODIFICATION における mtime のみのヒューリスティックを ctime + コンテンツシグナルに置き換え、analyze BUNDLE と analyze --root の両方に対する実際のオフラインタイムライン
  • カバレッジパック: PACKAGE_TAMPERED、IMMUTABLE_FLAG_SET、PAM_BACKDOOR、KERNEL_MODULE_SUSPICIOUS、SETUID_INVENTORY(PackageCollector、PamCollector、KernelCollector 経由、すべて設計上フラグのみ)
  • 93.79% カバレッジで 400 テスト
  • USER_EMPTY_PASSWORD
  • 誤検出の削減: 区切り文字で境界付けられたパスチェック、setuid と setgid の区別、snap//usr/lib デーモンを標準として扱う、KERNEL_MODULE_SUSPICIOUS を LOW に降格、モジュールごとに 1 つの NSS 検出結果
  • 誠実なレポート: 失敗したルールと劣化したコレクターを scan_metadata と TUI に記録。タイムラインの失敗が検出結果を破棄しなくなった。改ざんされたバンドルは警告して終了コード 3。syslog の年/タイムゾーンを正しく処理
  • より安全な修復: --min-confidence ゲート(デフォルト 40)、scan --remediate 後に TUI に結果を表示
  • 94.29% カバレッジで 444 テスト