
DirtyFrag (CVE-2026-43284) のラボ検出演習 - xfrm-ESP ページキャッシュ破損による Linux カーネル特権昇格。エクスプロイト実行、検出のギャップ、Elastic Stack を使用した修正済み EQL ルールを網羅した完全な解説。
分類: 内部ラボ - CyberLAB
日付: 2026年5月24日
プラットフォーム: Elastic Stack v9.4.1
ステータス: 検出確認済み
DirtyFrag(CVE-2026-43284) を利用した制御されたエクスプロイト演習。これは初期アクセス後の攻撃者がLinuxカーネルの特権昇格脆弱性を悪用するシナリオを模擬したものです。想定される攻撃者シナリオ:フィッシングで入手した資格情報で得た低権限ユーザー(saskia、uid=1001)が社内Linuxホスト上でrootへの昇格を試みる。ラボでは、本番ネットワークから隔離された意図的に脆弱なUbuntuマシン(ubuntu-vuln、カーネル6.0.0-22-generic)を使用しました。
攻撃者はラボ環境内で完全なrootアクセス(uid=0)を達成しました。Elastic Security検出スタックは3件のHIGH重大度アラート(リスクスコア73)を生成し、エクスプロイトチェーンを正しく識別しました。ただし、手動チューニングが必要でした。デフォルト設定では、アラートを見逃すギャップが存在していました。
結論: 未パッチのLinuxホスト(カーネル <= 6.x)は脆弱です。攻撃者がすでに低権限の足掛かりを得ている場合、このエクスプロイトは静かに迅速に完全なrootを提供し、ファイル整合性ツールでは検出できないディスク上の痕跡を残しません。
auditdルールでは証拠が生成されない。 socket、splice、unshareに対する明示的なシステムコールルールがなければ、エクスプロイトは静かに実行される。ログもアラートもなし。デフォルトのElastic Agentデプロイメントでは、これらのルールが自動的に追加されない。process.parent.pidを使用していた。実際には、DirtyFragは中間プロセスをフォークするため、その相関が壊れる。修正策として、auditd.sessionで相関を取ることがこの演習中に特定され、実装された。/etc/shadowを読み取り、SSH認証鍵にアクセスし、永続化マーカー(/root/pwned.txt)を書き込み、ncを介したネットワーク偵察を開始した。これらはすべて初期アクセスから30分以内に発生した。目的: ホームラボSOCにおけるDirtyFragエクスプロイトに対する検出カバレッジを検証し、検出ギャップを特定し、観測された攻撃者の行動に基づいた修正済み検出ルールを作成する。
脅威モデル: フィッシングで入手した低権限ユーザーアカウント(saskia、uid=1001)の資格情報を持つシミュレートされた初期アクセス後の攻撃者。目標:xfrm-ESP受信パスを介したDirtyFragによるrootへの特権昇格。ラボの実行はProxmoxコンソールを介して行われた。機能的にはSSHによるポストアクセスと同等。
2つの攻撃者能力層が考慮された:
今回の演習ではバニラ層をカバーした。
DirtyFragは、関連するLinuxカーネルバグファミリーの3番目であり、すべて同じ根本原因を悪用する:
根本原因: IPv4/IPv6データグラム追加パスでは、skb_splice_from_iter()がページキャッシュページをソケットバッファ(sk_buff)に配置した後、SKBFL_SHARED_FRAGを設定しなかった。ESP入力パスは、攻撃者が制御するページキャッシュページに対してインプレース暗号化を実行し、それらを通常のクローンされていない非線形skbとして扱った。
エクスプロイトプリミティブ: ページキャッシュへの4または8バイトの制御書き込み。決定的。競合条件は不要。
エクスプロイトチェーン:
/usr/bin/su)をページキャッシュに読み込むsplice()を介してパケットを構築し、ファイルのページがstruct sk_buffのfrag[0]に配置されるxfrm-ESP復号パスに配信execve()を含む)はすべて、破損したバイトを返す重要な回避特性: ディスク上のファイルは決して変更されない。ファイル整合性監視ツール(AIDE、Tripwire、ハッシュチェック)はすべて、ターゲットファイルをクリーンと報告する。
脆弱性が確認されたディストリ: Ubuntu 24.04.4、RHEL 10.1、AlmaLinux 10、openSUSE Tumbleweed、CentOS Stream 10、Fedora 44。
演習時点でのアクティブなテレメトリ:
演習前にラボネットワークを隔離。ファイアウォールエイリアスCyber_escape_doorが無効であることを確認 - 他のVLANやインターネットへの横方向の到達を防止。

ubuntu-vuln上で脆弱なカーネルと低権限アカウントを確認:```
saskia@ubuntu-vuln:$ uname -r
6.0.0-22-generic
saskia@ubuntu-vuln:$ whoami
saskia
saskia@ubuntu-vuln:~$ id
uid=1001(saskia) gid=1001(saskia) groups=1001(saskia),27(sudo),100(users)

#### 4.3 スタックヘルスチェック
**Suricata: 実行中かつキャプチャ中 (systemctl status)**

**Kibana/Elasticsearch: グリーン/正常 (APIチェック)**

**変更前のVMスナップショット**



#### 4.4 ネットワークキャプチャ
tcpdumpがSuricataホスト(`emp6s19`、スナップショット長262144バイト)で開始され、`172.66.66.27`のトラフィックを完全パケットキャプチャしました。


---
### 5. フェーズ2 - エクスプロイトの実行
#### 5.1 ステージング
エクスプロイトのソースコード(`exp.c`)が、V4bel/dirtyfragのPoCから被害ホストにステージングされました。```bash
ubuntu-vuln@ubuntu-vuln:~/dirtyfrag$ ls
exp exp.c README.md
ubuntu-vuln@ubuntu-vuln:~/dirtyfrag$ cp exp.c /tmp/exp/
右側のターミナルは、ユーザー saskia から見えるステージングされたコピーを示しています。

root として sudo gcc でコンパイルされています (ユーザー saskia は sudoers に含まれています):```
saskia@ubuntu-vuln:$ sudo gcc -o /tmp/exp/clean_frag /tmp/exp/exp.c
saskia@ubuntu-vuln:$ ls -la /tmp/exp/
-rwxr-xr-x 1 root root 62320 May 24 12:18 clean_frag
-rw-rw-r-- 1 ubuntu-vuln ubuntu-vuln 67803 May 24 12:13 exp.c
saskia@ubuntu-vuln:~$ id
uid=1001(saskia) gid=1001(saskia) groups=1001(saskia),27(sudo),100(users)
Binary: ELF 64-bit LSB executable, x86-64, 動的リンク。

#### 5.3 実行 - ルート取得
エクスプロイトは `saskia` (uid=1001) として実行されました。プロセス (`clean_frag`, pid=4326) は `AF_RXRPC` および `AF_ALG` ソケットを開き、次に `splice()` を呼び出してページキャッシュページをネットワークバッファに植え付けました。ESPパス上のインプレース暗号化により、攻撃者が制御するバイトがページキャッシュに書き込まれました。子プロセス (pid=4327) は `unshare` を `a0=50000000` (CLONE_NEWUSER | CLONE_NEWNET) で呼び出し、名前空間スコープのケーパビリティを取得しました。```
saskia@ubuntu-vuln:~$ /tmp/exp/clean_frag
...
root@ubuntu-vuln:~# id
uid=0(root) gid=0(root) groups=0(root)
root@ubuntu-vuln:~# ls
完全なrootシェルを取得 12:22 CEST (10:22 UTC)、2026年5月24日。
監査ログ(Auditd)のシステムコールシーケンス (UTC):
すべてのイベントは auditd.session=2 を共有しています。

すべてのアクションは、~12:22 CEST以降、ubuntu-vuln上でrootとして実行されました。
root@ubuntu-vuln:# echo "Dirty Frag PoC executed at $(date)" > /root/pwned.txt
root@ubuntu-vuln:# cat /root/pwned.txt
Dirty Frag PoC executed at Sun May 24 12:28:05 PM CEST 2026

#### 6.2 資格情報アクセス```bash
root@ubuntu-vuln:~# cat /etc/shadow | head -2
root:*:19823:0:99999:7:::
daemon:*:19823:0:99999:7:::
root@ubuntu-vuln:~# cat /home/ubuntu-vuln/.ssh/authorized_keys
ssh-ed25519 AAAA[...]
ShadowファイルとSSH authorized keysにアクセスされました。実際の侵害では、これによりオフラインでのパスワードクラッキングと永続的なSSHバックドアアクセスが可能になります。

root@ubuntu-vuln:~# nc -vz 172.66.66.1 100-8000
ラボゲートウェイ(`172.66.66.1`、ポート100-8000)のポートスキャン、12:51 CESTにルートコンテキストから実行。これは、昇格したセッションからの横方向移動能力とネットワークマッピングを示しています。

#### 6.4 Suricataネットワーク可視性
Suricataは、演習ウィンドウ全体で`172.66.66.27`に関連する**105イベント**をキャプチャしました(88 mDNS、17 flow)。スクリーンショットが撮影された時点(ncスキャン中、12:53 CEST頃)で、ダッシュボードには29イベントが表示されていました。
DirtyFragエクスプロイト自体はカーネル内部であり、ネットワークシグネチャを生成しません - 昇格プリミティブはワイヤ上に異常なトラフィックを生成しません。Suricataは、エクスプロイト自体を検出するためではなく、ポストエクスプロイトトラフィックと列挙試行のpcapを収集するために使用されました。
| イベントタイプ | カウント |
| ---------- | ----- |
| mDNS | 88 |
| flow | 17 |
| **合計** | **105** |
フローイベントは、ncポートスキャンウィンドウ(10:50-11:10 UTC / 12:50-13:10 CEST)の周辺に集中しています。

---
### 7. フェーズ4 - 検知エンジニアリング
#### 7.1 デプロイされた検知ルール
Elastic Security Labsの記事に基づいて、Kibana Detection Engineに2つのEQLシーケンスルールが作成されました。
**Rule 1 - AF_RXRPC or AF_ALG Socket with Splice Followed by Execution** (発火しませんでした - 以下のギャップを参照)```eql
sequence with maxspan=60s
[any where host.os.type == "linux" and
(
(event.category == "process" and auditd.data.syscall == "socket"
and auditd.data.a0 in ("26", "21")) or
(event.category == "process" and auditd.data.syscall == "splice") or
(event.category == "network" and event.action == "bound-socket"
and data_stream.dataset == "auditd_manager.auditd"
and auditd.data.socket.family == "38")
)
and user.id != "0"] by process.pid, host.id, user.id with runs=10
[process where host.os.type == "linux" and event.action == "executed" and
(
(user.effective.id == "0" and user.id != "0") or
(process.name in ("bash", "sh", "zsh", "dash", "fish", "ksh", "busybox")
and process.args in ("-c", "--command", "-ic", "-ci", "-cl", "-lc",
"-bash", "-sh", "-zsh", "-dash", "-fish", "-ksh"))
)] by process.parent.pid, host.id, user.id
ルール2 - 名前空間操作後の権限昇格 (修正後に発動)```eql sequence by host.id, auditd.session with maxspan=30s [process where host.os.type == "linux" and auditd.data.syscall == "unshare" and auditd.data.a0 in ("10000000", "50000000", "70000000", "10020000", "50020000", "70020000") and user.id != "0" and user.id != null] [process where host.os.type == "linux" and user.id == "0" and user.id != null and (process.name in ("bash", "sh", "zsh", "dash", "fish", "ksh", "su", "sudo", "pkexec", "busybox", "mksh") or process.name like ("python*", "perl*", "ruby*", "php*", "lua*"))]
#### 7.2 初期検出のギャップ - 不足しているシステムコールのカバレッジ
Rule 1 はゼロ件の結果を返しました。`ubuntu-vuln` 上のデフォルトの auditd 設定は、`write`、`bpf`、`openat`、`unshare` のみをキャプチャしました。
不足: `socket`、`splice`、`bind` - 中核となるエクスプロイトプリミティブ。
**修正:** `/etc/audit/rules.d/dirtyfrag.rules` に追加:```
-a always,exit -F arch=b64 -S socket -k socket_syscall
-a always,exit -F arch=b32 -S socketcall -k socket_syscall
-a always,exit -F arch=b64 -S splice -k splice-syscall
-a always,exit -F arch=b32 -S splice -k splice-syscall
-a always,exit -F arch=b64 -S unshare -k unshare-syscall
-a always,exit -F arch=b32 -S unshare -k unshare-syscall
272 new auditd events landed in Elasticsearch within seconds of the exploit run.
Despite events being captured, Rule 2 returned 0 matches.
Root cause - actual process tree (from Elasticsearch):
The original rule correlated by process.parent.pid. The unshare event had ppid=4326, but the root shell had a different parent - DirtyFrag forks intermediate processes, breaking the correlation.
Fix: Correlate by auditd.session. All events in the exploit chain shared session=2, correctly linking the sequence regardless of fork depth.
3 HIGH-severity alerts, risk score 73, in Kibana Security - Alerts at 2026-05-24T10:25:57Z UTC (12:25:57 CEST).
| Alert | Timestamp (UTC) | Signal |
|---|---|---|
| Sequence match - unshare event | 10:25:57.869 | process=clean_frag, user=saskia (uid=1001) |
| Sequence match - root shell | 10:25:57.881 | process=bash, user=root (uid=0) |
DirtyFrag - Namespace Manipulation Followed by Privilege Escalationubuntu-vuln

All dirtyfrag-related auditd events: event.module:auditd and process.name:dirtyfrag* review, not actual query```kql data_stream.dataset: "auditd_manager.auditd" and auditd.summary.how: dirtyfrag
**非rootユーザーによる名前空間の操作:**```kql
data_stream.dataset: "auditd_manager.auditd" and auditd.data.syscall: "unshare" and auditd.data.a0: "50000000"
同一セッション内の権限昇格後のルート活動:```kql data_stream.dataset: "auditd_manager.auditd" and user.id: "0" and auditd.session: "2"
**エクスプロイトウィンドウ中のすべてのauditdイベント:**```kql
data_stream.dataset: "auditd_manager.auditd" and @timestamp >= "2026-05-24T10:20:00Z" and @timestamp <= "2026-05-24T10:30:00Z"
エクスプロイトプロセスからのソケットおよびspliceシステムコール:```kql data_stream.dataset: "auditd_manager.auditd" and auditd.summary.how: "/tmp/exp/clean_frag"
---
### 9. 主要な発見結果の概要
| # | 発見内容 | 深刻度 | 修正済み |
| - | ------- | -------- | ---------- |
| 1 | デフォルトのauditdルールでは`socket`、`splice`、`unshare`を対象外 – 明示的なルールがないと証拠が取得できない | 重大 | はい – `/etc/audit/rules.d/dirtyfrag.rules`にカスタムルールをデプロイ済み |
| 2 | `process.parent.pid`によるEQL相関がforkされたエクスプロイトチェーンでは機能しない | 高 | はい – `auditd.session`に変更済み |
| 3 | ファイル完全性監視はDirtyFragに対して無効 – ディスク上のファイルは全期間を通じて変更なし | 高 | 適用範囲内での修正なし – 修正はカーネルへのパッチ適用 |
| 4 | 侵害後:シャドウファイル、SSH鍵、およびネットワーク偵察が、アラート駆動型対応の前にすべてrootとして実行される | 高 | auditdログで検出済み。資格情報アクセスや偵察フェーズ専用のルールは未発動 |
---
### 10. 参考文献
- Elastic Security Labs: [Copy Fail and DirtyFrag: Linux Page Bugs in the Wild](https://www.elastic.co/security-labs/copy-fail-dirtyfrag-linux-page-bugs-in-the-wild)
- 公開PoC: [V4bel/dirtyfrag on GitHub](https://github.com/V4bel/dirtyfrag)
- MITRE ATT&CK: [T1068 - 権限昇格のための悪用](https://attack.mitre.org/techniques/T1068/)
- MITRE ATT&CK: [TA0004 - 権限昇格](https://attack.mitre.org/tactics/TA0004/)
- MITRE ATT&CK: [T1003.008 - /etc/passwd と /etc/shadow](https://attack.mitre.org/techniques/T1003/008/)
| 項目 | 詳細 |
|---|
| 脆弱性 | DirtyFrag - CVE-2026-43284(xfrm-ESPパス)、CVE-2026-43500(RxRPCパス) |
| CVSSによる影響 | 完全なローカル特権昇格によるroot取得 |
| 影響を受けるカーネル | Linuxカーネル >= 2017年1月(9年間の寿命) |
| 影響を受けるディストリ | Ubuntu 24.04.4、RHEL 10.1、AlmaLinux 10、openSUSE、CentOS Stream 10、Fedora 44 |
| ファイル整合性バイパス | ディスク上のファイルは変更なし - AIDE、Tripwire、ハッシュ監視はすべてクリーンと報告 |
| 公開PoC | 入手可能(GitHub上のV4bel/dirtyfrag) |
| rootまでの時間 | 低権限足掛かりから10分未満 |
| 優先度 | アクション |
|---|
| 即時 | すべてのホストのLinuxカーネルを修正済みバージョンにパッチ適用。Ubuntu、RHEL、AlmaLinux、openSUSE、CentOS、Fedoraのベンダーセキュリティアドバイザリを適用。 |
| 短期 | Elastic Agentで監視されているすべてのLinuxホストに、socket、splice、unshareに対する明示的なauditdシステムコールルールを展開。 |
| 短期 | EQL検出ルールを更新し、名前空間操作シーケンスに対してprocess.parent.pidではなくauditd.sessionで相関を取るように変更。 |
| 継続的 | リスクスコア73以上の特権昇格アラートを優先度の高いトリアージとして扱う。現在のルールは昇格から数秒以内に発火する。 |
| CVE | ニックネーム | 導入時期 | パス |
|---|
| CVE-2022-0847 | Dirty Pipe | - | pipe |
| CVE-2026-31431 | Copy Fail | - | splice |
| CVE-2026-43284 | DirtyFrag | 2017年1月(コミットcac2661c53f3) | xfrm-ESP |
| CVE-2026-43500 | DirtyFrag | 2023年6月(コミット2dc334f1a63a) | RxRPC |
| コンポーネント | 詳細 |
|---|
| Fleet Server / ELKホスト | ubuntu-tm / elk-docker - 172.66.66.30(ラボ内部) |
| Elastic Stack | v9.4.1(Elasticsearch、Kibana、Logstash - Docker) |
| ターゲット(被害者)ホスト | ubuntu-vuln - 172.66.66.27 |
| 被害者カーネル | 6.0.0-22-generic(脆弱) |
| 被害者ユーザー | saskia - uid=1001、groups=1001(saskia)、27(sudo)、100(users) |
| Elastic Agent | v9.4.1(auditbeat付き) |
| ネットワークIDS | 専用センサー上のSuricata 8.0.5 |
| Kibana | http://172.66.66.30:5601(ラボ内部) |
| データセット | シェア |
|---|
suricata.eve | 75.2% |
elastic_agent.fleet_server | 10.8% |
elastic_agent | 9.1% |
elastic_agent.filebeat | 1.9% |
elastic_agent.auditbeat | 1.4% |
auditd_manager.auditd | 0.5% |
system.auth | 0.2% |
system.syslog | 0.1% |
| タイムスタンプ (UTC) | システムコール | 引数 | プロセス (pid) | ユーザ |
|---|
| 10:21:11.054 | unshare | a0=50000000 | clean_frag (4327) | saskia (1001) |
| 10:21:11.055 | socket | a0=21 (AF_RXRPC) | clean_frag (4326) | saskia (1001) |
| 10:21:17.403 | socket | a0=26 (AF_ALG) | clean_frag (4326) | saskia (1001) |
| 10:21:17.419 | splice | a0=4 | clean_frag (4326) | saskia (1001) |
| 10:21:17.419 | splice | a0=7 | clean_frag (4326) | saskia (1001) |
| Process | PID | PPID | UID | auditd.session |
|---|
| shell (saskia) | 4182 | - | 1001 | 2 |
clean_frag (main) | 4326 | 4182 | 1001 | 2 |
clean_frag (unshare child) | 4327 | 4326 | 1001 | 2 |
bash (root) | - | 4451 | 0 | 2 |
| Composite sequence alert |
| 10:25:57.893 |
| host=ubuntu-vuln |
| Tactic | Technique | ID |
|---|
| Privilege Escalation | Exploitation for Privilege Escalation | T1068 |
| Privilege Escalation | Escape to Host | T1611 |
| Credential Access | OS Credential Dumping: /etc/passwd and /etc/shadow | T1003.008 |
| Discovery | Network Service Discovery | T1046 |
| Syscall | Argument | Meaning |
|---|
unshare | a0=50000000 | CLONE_NEWUSER | CLONE_NEWNET |
socket | a0=26 | AF_ALG (kernel crypto subsystem) |
socket | a0=21 | AF_RXRPC (RxRPC path) |
bind | socket.family=38 | AF_ALG bind |
splice | - | Page injection into network buffers |