exploitation php2shell aslr bypass

情報漏洩なしでのASLR完全突破: Linuxディストリビューション別バイナリ堅牢化とfork()共有メモリ攻略

php2shell.run Research Lab •

情報漏洩なしでのASLR完全突破: Linuxディストリビューション別バイナリ堅牢化とfork()共有メモリ攻略

<time datetime="2026-10-23">検証日: 2026年10月23日</time> · 脆弱性工学解析: Linux x86_64 ASLR, PIE, glibc 2.35+

現代のLinuxオペレーティングシステムにおいて、ASLR(Address Space Layout Randomization: アドレス空間配置のランダム化) は、メモリ破壊脆弱性に対する最も基本的かつ強力な防壁とされてきました。従来のエクスプロイト理論では、スタックやヒープのアドレスを事前にリークさせる「情報漏洩脆弱性(Info-Leak)」が伴わない限り、RCE(リモートコード実行)を確実に行うことは不可能に近いと信じられていました。

しかし、PHP2Shell(CVE-2026-109618 / CVE-2026-109619)の実戦兵器化においては、「事前のメモリ情報漏洩を一切要求しない単一リクエストでのASLRバイパス」 が実証されました。本稿では、PHP-FPMのアーキテクチャ特性と主要Linuxディストリビューションのバイナリ保護機構の差異を軸に、その攻撃メカニズムを解説します。


1. 主要Linuxディストリビューションの防御マトリクス

主要ディストリビューションの公式パッケージにおけるバイナリ保護フラグ(Checksec出力)の差異は以下の通りです:

ディストリビューションPIE (位置独立実行ファイル)Stack CanaryNX Bit (実行不可スタック)RELRO (Relocation Read-Only)PHP2Shell単発RCEの成立性
Ubuntu 22.04 / 24.04 LTS有効 (Full PIE)有効有効Full RELRO条件付き成立 (fork構造悪用)
Debian 11 / 12有効 (Full PIE)有効有効Full RELRO条件付き成立 (fork構造悪用)
RHEL 8 / 9 (Rocky/Alma)有効 (Full PIE)有効有効Full RELRO条件付き成立 (fork構造悪用)
Alpine Linux (musl libc)有効 (Full PIE)有効有効Full RELRO困難 (muslヒープ構造の違い)
自前コンパイル環境 (一部)無効 (No PIE)有効有効Partial RELRO即時完全成立 (高リスク)

2. なぜASLRが突破されるのか: Linux fork() の構造的盲点

ASLRは、プログラムが execve() システムコールによって新規に起動された際にのみ、ベースアドレスをランダム化します。

しかし、PHP-FPM(FastCGI Process Manager)のプロセスモデルは以下のようになっています:

 [ PHP-FPM Master Process ] (root権限で起動)
        │
        │── ASLRによりライブラリやコードのアドレス空間が決定 (例: 0x7f8000000000)
        │
        ├── fork() ──> [ Worker Process 1 (PID: 101) ] (同一のアドレス配置を完全複製)
        ├── fork() ──> [ Worker Process 2 (PID: 102) ] (同一のアドレス配置を完全複製)
        └── fork() ──> [ Worker Process 3 (PID: 103) ] (同一のアドレス配置を完全複製)

Linuxの fork() は親プロセスのページテーブルをコピーオンライト(Copy-on-Write)で複製するため、全ての子ワーカープロセスは、マスタープロセスと100%同一の仮想メモリアドレスレイアウトを共有します。

クラッシュ耐性とオフセットの不変性

仮に攻撃者がアドレス推測に失敗してワーカープロセスが SIGSEGV(セグメンテーション違反)で異常終了したとしても:

  1. マスタープロセスは何事もなかったかのように直ちに新しいワーカーを fork() します。
  2. 新しく起動したワーカーのアドレス空間は、直前で死んだワーカーと全く同一です(マスタープロセスが再起動されない限り、ベースアドレスは再ランダム化されません)。

攻撃者はブルートフォースや既知のオフセットテーブルを用いて、マスタープロセスが再起動されない限り、確実に標的アドレスを特定することが可能です。


3. PIE無効化環境における致命的リスク

特に注意を要するのが、レンタルサーバー、レガシーコンテナイメージ、あるいは管理者がソースコードから独自ビルドしたPHP環境です。

コンパイル時に -fPIE -pie オプションを付与し忘れたバイナリでは、PHPのメイン実行ファイルのコードセグメントが固定アドレス(例: 0x00400000)に配置されます。この場合、glibcのアドレスすら推測する必要がなく、バイナリ内に静的に配置された zif_system やROPガジェットのアドレスを直書きするだけで、単発1リクエストでのシェル奪取が物理的に成功します。


4. 防御策: プロセス単位のクラッシュ制限とSeccomp

この攻撃モデルを無力化するためのシステム管理者向け対抗策:

① PHP-FPM緊急クラッシュスロットリングの設定

短時間に一定回数以上のワーカー異常終了が発生した場合、マスタープロセスごと再起動させてASLRを再生成(またはサービスを安全停止)させます。

/etc/php/8.3/fpm/php-fpm.conf:

; 60秒間に10回以上のワーカークラッシュが発生したらマスターを安全停止
emergency_restart_threshold = 10
emergency_restart_interval = 60s
process_control_timeout = 10s

② カーネルレベルでのPtrace及びCore Dump無効化

echo "kernel.core_pattern=|/bin/false" | sudo tee /etc/sysctl.d/50-security.conf
echo "kernel.yama.ptrace_scope=2" | sudo tee -a /etc/sysctl.d/50-security.conf
sudo sysctl --system