Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-34234-Lab — Local Docker lab demonstrating CVE-2026-34234 unauthenticated RCE in CtrlPanel web installer. Includes vulnerable and patched containers, PoC scripts, and root cause analysis for security research and defensive validation. | Kitploit
Tools/GitHubGitHub/rootdirective-sec/cve-2026-34234-lab
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationLabs & Practice
GitHubrootdirective-sec/cve-2026-34234-lab

CVE-2026-34234-Lab

Local Docker lab demonstrating CVE-2026-34234 unauthenticated RCE in CtrlPanel web installer. Includes vulnerable and patched containers, PoC scripts, and root cause analysis for security research and defensive validation.

View Repository
13 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2026-34234 - CtrlPanel Installer RCE Lab

Local Docker lab for demonstrating CVE-2026-34234 in CtrlPanel.

This repository compares:

  • vuln: CtrlPanel 1.1.1 pinned by digest
  • patched: CtrlPanel 1.2.0 pinned by digest

The lab is local-only and binds services to 127.0.0.1.


Summary

CVE-2026-34234 is an unauthenticated RCE in CtrlPanel's web installer.

The issue is caused by two bugs chained together:

  1. Installer form handlers were reachable before the install.lock gate.
  2. Installer input was interpolated into shell command strings.

In this lab, the vulnerable container executes a harmless proof command and writes its output inside the container. The patched container receives the same request but does not create the proof file.

Expected result:

root@kitploit:~
vulnerable => proof file created
patched    => no proof file

Root Cause

1. Vulnerable shell execution in 1.1.1

Original vulnerable file:

root@kitploit:~
public/installer/src/functions/shell.php

Relevant upstream code in 1.1.1:

root@kitploit:~
function run_console(string $command, ...) {
    $path = dirname(__DIR__, 4);
    $handle = proc_open("cd '$path' && bash -c 'exec -a ServerCPP $command'", ...);
}

Problem:

  • run_console() accepts one shell command string.
  • That string is passed into bash -c.
  • User-controlled installer values can become part of that command string.
  • Shell metacharacters can change command structure.

2. Vulnerable installer form path

Original vulnerable file:

root@kitploit:~
public/installer/src/forms/pterodactyl.php

Relevant upstream behavior in 1.1.1:

root@kitploit:~
run_console("php artisan settings:set 'PterodactylSettings' 'panel_url' '$url'", ...);
run_console("php artisan settings:set 'PterodactylSettings' 'admin_token' '$key'", ...);
run_console("php artisan settings:set 'PterodactylSettings' 'user_token' '$clientkey'", ...);

Problem:

  • url, key, and clientkey originate from installer POST data.
  • The values are embedded into shell command strings.
  • The installer endpoint is reachable without authentication.

3. Installer gate order

The advisory states that public/installer/index.php checked install.lock only after loading/executing installer form logic. That made installer handlers reachable even on already-installed instances.


Patch / Fix

1. Early installer lock check

The fix moves the install.lock check before form handlers are loaded.

Patched behavior:

root@kitploit:~
if (file_exists('../../install.lock')) {
    exit("The installation has been completed already. Please delete the File 'install.lock' to re-run");
}

2. Avoid shell string execution

Original patched file:

root@kitploit:~
public/installer/src/functions/shell.php

Relevant upstream code in 1.2.0:

root@kitploit:~
function run_console(array $command, ...): string {
    $cwd = $cwd ?? $path;
    $handle = proc_open($command, $descriptors, $pipes, $cwd, null, $options);
}

Why this fixes the issue:

  • run_console() now accepts an argv-style array.
  • The command is no longer composed as a single shell string.
  • Payload syntax such as $() remains literal input instead of shell syntax.

Patched form behavior in 1.2.0 uses array-style command execution:

root@kitploit:~
run_console(['php', 'artisan', 'settings:set', 'PterodactylSettings', 'panel_url', $url], ...);
run_console(['php', 'artisan', 'settings:set', 'PterodactylSettings', 'admin_token', $key], ...);
run_console(['php', 'artisan', 'settings:set', 'PterodactylSettings', 'user_token', $clientkey], ...);

Lab Design

root@kitploit:~
127.0.0.1:8081 -> vulnerable CtrlPanel 1.1.1
127.0.0.1:8082 -> patched CtrlPanel 1.2.0
127.0.0.1:9100 -> fake Pterodactyl API

Services:

  • vuln: real CtrlPanel 1.1.1
  • patched: real CtrlPanel 1.2.0
  • fake-api: local fake Pterodactyl API used only to satisfy installer checks
  • mysql_vuln / mysql_patched: separate MariaDB instances
  • redis_vuln / redis_patched: separate Redis instances

The lab does not modify CtrlPanel application source code.

The Dockerfiles only wrap the original container entrypoint to normalize Docker Desktop runtime permissions for:

root@kitploit:~
/var/www/html/storage
/var/www/html/bootstrap/cache

After fixing permissions, the wrapper executes the original product entrypoint.


PoC Design

Primary PoC:

root@kitploit:~
poc/poc_http_only.py

Properties:

  • Sends HTTP POST only
  • Does not use docker exec
  • Does not inspect containers
  • Does not start reverse shells
  • Uses harmless commands only: id, whoami, hostname

Helper script:

root@kitploit:~
poc/poc_lab.py

Purpose:

  • Sends the same HTTP request
  • Verifies proof inside containers using docker compose exec
  • Intended for demo and regression testing only

Proof file inside the app container:

root@kitploit:~
/var/www/html/storage/logs/cve_2026_34234_proof.txt

Run

Start from a clean lab state:

root@kitploit:~
docker compose down -v --remove-orphans
docker compose up -d --build

Wait until the app containers are up, then run:

root@kitploit:~
python3 poc/poc_lab.py

Expected output:

root@kitploit:~
== Testing vulnerable ==
proof_exists: True
result: PASS expected_proof=True

== Testing patched ==
proof_exists: False
result: PASS expected_proof=False

[+] Expected result reached:
    vulnerable => proof file created
    patched    => no proof file

Manual HTTP-only Test

Send the HTTP-only PoC to the vulnerable target:

root@kitploit:~
python3 poc/poc_http_only.py --target http://127.0.0.1:8081

Verify proof manually:

root@kitploit:~
docker compose exec vuln sh -lc 'cat /var/www/html/storage/logs/cve_2026_34234_proof.txt'

Expected proof:

root@kitploit:~
uid=1000(laravel) gid=1000(laravel) groups=1000(laravel)
laravel
<container-hostname>

Run the same request against patched:

root@kitploit:~
python3 poc/poc_http_only.py --target http://127.0.0.1:8082

Verify patched behavior:

root@kitploit:~
docker compose exec patched sh -lc 'test -f /var/www/html/storage/logs/cve_2026_34234_proof.txt && cat /var/www/html/storage/logs/cve_2026_34234_proof.txt || echo "no proof file"'

Expected:

root@kitploit:~
no proof file

Cleanup

Remove containers, networks, and lab volumes:

root@kitploit:~
docker compose down -v

Notes

  • This lab is for local security research only.
  • Do not run the PoC against systems you do not own or have permission to test.
  • The proof is intentionally limited to local command output inside the container.
  • The vulnerable and patched services use separate databases and Redis instances.
  • The fake API exists only to emulate the minimum Pterodactyl API responses required by the installer flow.

Disclaimer

This repository is provided for educational security research and defensive validation only.

All demonstrations are intended to run inside the provided local Docker lab environment. The proof-of-concept avoids destructive actions, persistence, credential theft, data exfiltration, and real-world targeting.

Do not use this project against any system without explicit authorization. The author is not responsible for misuse or damage resulting from this material.


References

  • GitHub Security Advisory: https://github.com/Ctrlpanel-gg/panel/security/advisories/GHSA-jmhr-q9q5-fqwh
  • CVE Record / NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-34234
  • Patched release: https://github.com/Ctrlpanel-gg/panel/releases/tag/1.2.0
  • Upstream repository: https://github.com/Ctrlpanel-gg/panel
Download Tool