2026 年 5 月の同じ週に、こんな組み合わせを見た。
- The Hacker News の xlabs_v1 ボットネット記事 → ELK で確認したら、まったく同じサブネットから 11,000 件超の攻撃を観測済みだった
- Copy.Fail と Dirty Flag という Linux kernel のローカル特権昇格脆弱性が立て続けに公開
- 後者にはまだ CVE 番号すら付いていない
リモートからの侵入観測と、侵入後の権限昇格対策は、本来なら別々の話に見える。けれど自分のように VPS にハニーポットを置いている側からすると、入口(攻撃の流入)と出口(侵入されたら何が起きるか)は地続きに見える。
今回は 「公式パッチを待つ間に kernel LPE を modprobe blacklist で塞ぐ」 というシンプルな手順のメモを書く。ついでに、その動機になった xlabs_v1 の話も軽くだけ触れる。
1. 入口の話:xlabs_v1 を ELK で照合してみた
5/7、The Hacker News が xlabs_v1 という Mirai 派生ボットネットの記事を出した。ADB(Android Debug Bridge、5555/tcp)経由で IoT デバイスを乗っ取り、DDoS-for-hire(Minecraft 等のゲームサーバを標的にした 21 種のフラッド変種を備える)として運用されるやつだ。
C2 は 176.65.139[.]44(AS51396 Pfcloud, ルクセンブルク)。
「あ、これ前にも見たことあるサブネットじゃん」となった。
ローカル ELK で同サブネット 176.65.139[.]0/24 を引いてみたら、こんな感じだった。
全期間ヒット数 : 11,028+ hits
active な IP : 15+
標的ポート Top : 22/tcp (3,143) > 8080 > 80 > 5555 > 23
主犯級 : 176.65.139[.]95 (5,350 hits)
176.65.139[.]111 (2,480 hits)
honeypot 内訳 : suricata 5,892 / cowrie 4,799 / adbhoney 119 ...
主犯級 2 IP(176.65.139[.]95 / .111)に絞って Cowrie ヒットを 20 日分引いてみるとこう。

Mirai 系の 22 / 23 / 5555 三点セットが綺麗に出てる。記事に出ていないペイロード名(zyre.arm7 / zyre.x86 等)も並行で観測した。
サブネット全体(過去 2 週間)のダッシュボード抜粋。

ただ、今回の主題はここではない。ここで言いたいのは、公開サーバを運用していると、「もし侵入されたら何が起きるか」を考える時間が増える、ということ。今回 LPE の話を書く動機の半分はここにある。
2. 出口の話:kernel LPE が二発来た
同じ週、Linux kernel のローカル特権昇格脆弱性が立て続けに二発公開された。
| 通称 | CVE | 影響対象 | 発火条件 |
|---|---|---|---|
| Copy.Fail | CVE-2026-31431 (CVSS 7.8) | algif_aead (AF_ALG) | 非特権ローカルユーザ |
| Dirty Flag | 未アサイン | xfrm-ESP (esp4/esp6) / RxRPC | xfrm-ESP は CAP_NET_ADMIN + userns / RxRPC は特権不要 |
どちらも、ローカルにシェルが取れた攻撃者が root に化けるためのものだ。リモート脆弱性とは違うレイヤーの話。
普通のサーバなら「ローカルにシェル取られた時点で詰みじゃね」と言える。けれどハニーポット運用は逆で、(疑似的な)シェルを取らせるのが仕事だ。Cowrie や Dionaea が攻撃者にコンテナ内シェルを与え、その挙動を観察する。コンテナ内シェルから kernel LPE 経由でホスト権限を奪われる、というのは現実的な脅威になる。
コンテナ運用ではあるがエスケープされると即死につながるし、即時対応の範囲ととらえた。
だから LPE 対策は、ハニーポットを自宅で置いてる側からすると他人事では済まない。
3. 塞ぐ前に確認すること
公式パッチが出る前に preventive にやるなら、確認は 2 方向ある。自環境のロード状況と、そのモジュールが業務で使われていないかだ。後者を飛ばすとサービスが死ぬので、塞ぐ前にひと呼吸入れる。
筆者の場合、という前置きで読んでいただき確認は各自行っていただきたい。
3-1. ディストリ・カーネルとモジュールロード状況
# (1) ディストリ・カーネル
uname -r
cat /etc/os-release
# (2) 該当モジュールが既にロードされてないか
lsmod | grep -E "esp4|esp6|rxrpc|af_alg|algif"
# (3) 過去にロードされた形跡(/sys/module 配下)
ls /sys/module/ | grep -E "esp4|esp6|rxrpc|af_alg|algif"
ロードされている → 依存関係を確認してから rmmod を検討する。 ロードされていない → preventive blacklist で塞いで終わり。
筆者の環境は Ubuntu 24.04.4 LTS / Linux 6.8.0-106-generic で、esp4/esp6/rxrpc は未ロード。af_alg は別途対策済みだった。
3-2. 該当モジュールを業務で使っていないか
blacklist は「使っていないモジュールを塞ぐから安全」という前提に立っている。逆に言えば、業務で使っているモジュールを塞いだ瞬間にサービスが死ぬ。
雑な目安で恐縮ではあるが、事前確認が必要。
IPsec / VPN → esp4 / esp6 が必須
- StrongSwan / Libreswan で IPsec トンネルを張っている場合、
esp4/esp6のブロックは厳禁 - WireGuard は kernel-side で esp を使わないので影響なし
- SSL VPN(Cisco AnyConnect、OpenVPN 等)も esp 系不要
ip xfrm state | head # 出力があれば IPsec 稼働中
systemctl is-active strongswan strongswan-starter strongswan-swanctl 2>/dev/null
systemctl is-active ipsec 2>/dev/null # Libreswan (RHEL系) 用
AFS(Andrew File System)クライアント → rxrpc が必須
- OpenAFS / kafs を使う環境では
rxrpcモジュールが必要 - 大学・研究機関のホームディレクトリ共有で稀に残っている
- 一般的なエンタープライズではほぼ使われていない
mount | grep -E "afs|kafs"
lsmod | grep -E "rxrpc|kafs"
AF_ALG(algif_aead 等)→ 念のため確認
- LUKS フルディスク暗号化は通常
dm-cryptを直接使うので AF_ALG 不要 - ただし一部の古い暗号化ライブラリや、kernel keyring 経由の暗号化アクセラレーションが AF_ALG socket を使うケースがある
wpa_supplicantやcryptsetupの設定次第で有効化されている可能性
# AF_ALG socket を使ってるプロセスがいるか
sudo ss -xa | grep -i alg
# 既存プロセスの memory map から AF_ALG 利用を見つける
sudo grep -l "if_alg\|AF_ALG" /proc/*/maps 2>/dev/null
筆者の VPS(T-Pot ハニーポット)は IPsec も AFS も AF_ALG 利用ライブラリも使っていなかったので、全部 blacklist で塞いで問題なかった。が、エンタープライズの本番サーバや SOC のテナントノードでは、上のどれかが普通に動いている可能性がある。塞ぐ前にひと呼吸入れる、という話。
4. blacklist に何を追加するか
/etc/modprobe.d/ 配下に .conf を作る。中身は blacklist + install トラップの二段構え。
なぜ二段構えなのか。図にするとこう。
[攻撃者・あるいは syscall がモジュールロードを誘発]
↓
modprobe esp4
↓
┌────────────────────────────┐
│ 1段目: blacklist │ ← 名前一致でロード拒否
└────────────────────────────┘
↓ alias 経由でバイパスされる場合あり
┌────────────────────────────┐
│ 2段目: install /bin/true │ ← 代わりに /bin/true を実行
└────────────────────────────┘
↓
本体はロードされず終了
blacklist 単体では、alias 経由(例: socket(AF_ALG, ...) での auto-load)で抜けられるケースがある。install <module> /bin/true を併記すると、modprobe はモジュール本体ではなく /bin/true を実行するので、確実にブロックできる。
Copy.Fail (CVE-2026-31431) 用
sudo tee /etc/modprobe.d/blacklist-algif_aead.conf <<'EOF'
blacklist algif_aead
blacklist algif_skcipher
blacklist algif_hash
blacklist algif_rng
blacklist af_alg
install af_alg /bin/false
install algif_aead /bin/false
install algif_skcipher /bin/false
install algif_hash /bin/false
install algif_rng /bin/false
EOF
ここで /bin/false を使っているのは、ロード試行時に exit 1 で帰したいから(後述の検証で違いが出る)。
Dirty Flag 用
sudo tee /etc/modprobe.d/dirtyfrag.conf <<'EOF'
blacklist esp4
blacklist esp6
blacklist rxrpc
install esp4 /bin/true
install esp6 /bin/true
install rxrpc /bin/true
EOF
こちらは /bin/true を使った。検証時の挙動が変わるだけで、防御効果は同じだ。
反映
sudo update-initramfs -u
これで再起動後も効くようになる。
5. 簡易検証
設定が効いているかは、強制ロードしてみて確かめる。
sudo modprobe esp4 ; echo "exit: $?"
sudo modprobe rxrpc ; echo "exit: $?"
# 実際にロードされていないかを確認
lsmod | grep -E "esp4|esp6|rxrpc"
注意:exit code に騙されない
install <module> /bin/true を使った場合、modprobe は /bin/true を実行して exit 0 を返す。つまりコマンドラインからは「ロード成功」に見えてしまう。
正しい確認指標は lsmod の方だ。
modprobe esp4 → exit 0 (install /bin/true の挙動)
lsmod | grep esp4 → 何も返らない (実際にはロードされていない)
↑
これが真の成功の証
/bin/false を使った場合は exit 1 で帰るので分かりやすい。が、どちらでも防御効果は同じ。気分の問題に近い。
auto-load 経路もテストする
カーネルは特定の syscall(例: socket(AF_ALG, ...) や socket(AF_INET, SOCK_RAW, IPPROTO_ESP))で、関連モジュールを自動ロードしようとする。これがブロックされているかも見ておく。
# AF_ALG 経路(Copy.Fail 側)
sudo python3 -c "
import socket
try:
s = socket.socket(38, 5, 0) # AF_ALG=38
print('NG: socket created (auto-load 経路が生きている)')
except OSError as e:
print(f'OK: blocked - {e}')
"
# IPPROTO_ESP 経路(Dirty Flag 側)
sudo python3 -c "
import socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, 50) # IPPROTO_ESP=50
print('socket created')
s.close()
except Exception as e:
print(f'Error: {e}')
"
# socket 試行後のロード状況再確認
lsmod | grep -E "esp4|esp6|rxrpc|af_alg|algif" || echo "OK: still blocked"
OK: still blocked が出れば、auto-load 経路も死んでいることが確認できる。
なお IPPROTO_ESP の SOCK_RAW socket は root で実行すると作成自体は通る(SOCK_RAW は本来 CAP_NET_RAW 必要、非特権で同経路を試したいときは unshare -Ur 経由で)。ただし lsmod に esp4 が出てこなければ、脆弱コードパス(ESP モジュール本体)には到達していないので問題ない。
6. ロールバック
公式パッチが当たった後、blacklist を解除したい場合:
sudo rm /etc/modprobe.d/dirtyfrag.conf
sudo update-initramfs -u
sudo modprobe esp4 esp6 rxrpc
reboot は不要。即時で戻る。
おわりに
雑記なので感想で締める。
正直、こんな対策を毎週手動でやらなくていい世界のほうが良い。というか倫理って世界共通だと思ってるけど違うんだろうか。
ただ現実には、CVE 番号すら付いていない(Dirty Flag は2026/05/08もそう)状態で PoC が公開され、攻撃者の手元にだけツールが先に届くタイミングがある。そのギャップを埋める手段として、/etc/modprobe.d/ は地味に強い。アプリケーション層を一切触らず、必要最小限の攻撃面を削るだけで済む。というか緩和策以外の方法が無い。
自宅にハニーポットを置いている側からすると、xlabs_v1 のような感染試行を ELK で照合する機会があり、攻撃の入口と出口は地続きに見える。「侵入されたとして、その先で何が起きるか」を仮定せずには、防御の境界線を引けない。今回の LPE 対策は、その仮定の話だ。
まぁしっかりアウトバウンドは閉めてますけどね。
そして私はまだGWなう。
参考: Linux Kernel LPE 脆弱性情報 (Dirty Flag) - SIOS Security
参考: Mirai-Based xlabs_v1 Botnet Exploits ADB to Hijack IoT Devices for DDoS Attacks - The Hacker News
参考: CVE-2026-31431 - NVD
T-Pot: Deutsche Telekom Security GmbH / https://github.com/telekom-security/tpotce / GPL v3.0