Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
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.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
cve-2026-111497-wordpress-poc — CVE-2026-111497 RCE PoC for one pinned Docker Official Image for WordPress | Kitploit
Tools/GitHubGitHub/caveeroo/cve-2026-111497-wordpress-poc
Container SecurityPayload GenerationVulnerability AnalysisExploitationWeb Application ExploitationCryptography
GitHubcaveeroo/cve-2026-111497-wordpress-poc

cve-2026-111497-wordpress-poc

CVE-2026-111497 RCE PoC for one pinned Docker Official Image for WordPress

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
View Repository
3219h 17m agoNot yet reviewed

CVE-2026-111497: pinned WordPress image RCE PoC

This source-only PoC reproduces unauthenticated command execution against one pinned Docker Official Image for WordPress.

One pingback.ping request makes WordPress fetch an attacker URL twice during the same PHP request. The first response corrupts a PHP handler through Brotli. The retry header starts Bash and returns the lab flag.

The profile is target-specific. It makes no claim about current WordPress images, other digests, or a memory error in WordPress Core.

WARNING: Run this PoC only in the included lab on a system that you own. It contains a working RCE payload.

Result

  • One unauthenticated inbound request causes two outbound requests.
  • Bash reads a fresh /flag.txt, and the flag returns in the XML-RPC response.
  • Linux ASLR mode 2 and the default allocator remain enabled.
  • The chain uses no leak, cross-request grooming, debugger, preload library, plugin, or direct handler seed.
  • The observable mode records the sh to bash to sleep process chain.
  • A one-bit selector control reaches the retry without exposing the flag.

Exact target and mechanism

ItemValue
Targetdocker.io/library/wordpress@sha256:806680ba62232c4c300fb9dcc9f89d08e9e8c2bfc59837a1f58716f8648306d5
Image IDc64dd89c00079939f18d70489e7c3e30cb071e8581824ab2de688f9f4d70d076
PlatformLinux amd64, Debian 13.7
ApplicationWordPress 7.1.3, Apache 2.4.69 prefork
RuntimePHP 8.3.36 NTS
Decoderlibbrotli1:amd64 1.1.0-2+b7

This Linux/amd64 manifest was selected by wordpress:latest when published. The current latest tag no longer selects it.

The lab runs this unmodified Docker Official Image with rootless Podman. It does not inject a Brotli library.

CVE-2026-111497 supplies the decoder corruption. WordPress supplies the unauthenticated fetch path through pingback.ping.

The malformed stream copies six bytes from the live system handler pointer into the strtolower handler. Both pointers use the same ASLR-loaded libphp.so base. Therefore, the profile does not need an absolute address leak.

The profile still depends on the exact Brotli, PHP, glibc, cURL, Requests, Apache, allocator, and request history. The first response uses a 161-byte header and a 23,069,816-byte body. The origin sends 23,069,752 bytes, waits one second, and sends the final 64 bytes.

The decoder returns an error after the corruption. Requests retries without content decoding after CURLE_BAD_CONTENT_ENCODING. Its first header name reaches the modified handler and starts the fixed Bash command.

The application path requires these conditions:

  • /xmlrpc.php is reachable, and pingback.ping is enabled.
  • A post exists and accepts pingbacks.
  • WordPress can fetch an attacker-controlled URL.
  • The cURL transport decodes Brotli responses.

The lab creates these conditions without a plugin or victim-side instrumentation.

Source and requirements

generate_payloads.py is the authoritative payload source. The repository tracks no prebuilt payload binaries.

The generator uses only the Python standard library. It works offline and does not send traffic or execute commands. It defines the profile constants and serialization stages from RFC 7932.

verify.sh regenerates all fragments. It verifies their sizes, hashes, intermediate bit offsets, and one-bit selector relationship.

The tested host used Ubuntu 24.04.4 under WSL2 on amd64. It used rootless Podman 4.9.3, Bash 5.2.21, and Python 3.12.3.

The minimum requirements are Linux amd64, rootless Podman, Bash, Python 3.8 or later, ASLR mode 2, and standard GNU user tools. Keep port 18170 and subnet 93.184.218.0/24 free, or select alternatives. An enforcing SELinux host can reject the bind mounts.

Before you run the lab, pull the immutable images:

podman pull docker.io/library/wordpress@sha256:806680ba62232c4c300fb9dcc9f89d08e9e8c2bfc59837a1f58716f8648306d5
podman pull docker.io/library/wordpress@sha256:65d5f185a6f539803a177ea9cdd5ad632ae24427bea114447e67a6fcd5d8bfe8
podman pull docker.io/library/mariadb@sha256:33a6653ab666774f48818120045f9367a81cd4c54c027412fe294a7d1274e2dc

Run the proof

Make the scripts executable, then verify the source package:

chmod +x generate_payloads.py verify.sh run.sh
./verify.sh

Run each mode with a new tag:

ModeCommandRequired result
Positive./run.sh standardReturns the flag and prints PoC positive:
Observable./run.sh observableAlso records visible bash and sleep processes
Selector./run.sh selectorRetries but keeps the flag out of the response

The selector changes one bit at byte offset 1066. It is a same-image causal control, not a fixed-decoder control.

The optional arguments are the mode, tag, host port, and third network octet:

./run.sh standard trial2 18171 219

The runner writes evidence to runs/<tag>/. The main files are:

  • VERDICT.txt: result and request counts
  • client-request.raw and client-response.raw: inbound wire data
  • origin-evidence/origin-events.json: both outbound requests and retry headers
  • oracle-match.txt: the flag match in the response
  • payloads/identity.json: generated profile metadata
  • MANIFEST.sha256: hashes for all evidence files

Safety and limits

The runner uses an internal Podman network and publishes WordPress only on 127.0.0.1. The client accepts no target address. The origin accepts no command input. The fixed command reads only the synthetic flag.

The runner removes the flag value from the Apache environment before Apache starts. It also creates fresh credentials and removes only resources from the current run.

The response split and process history are exploit inputs. If a run fails, repeat the unchanged profile with a new tag. Do not tune addresses or payload bytes after a failed run.

This package does not establish portability across image digests, PHP builds, architectures, allocators, or response schedules. A different target can stop execution or cause only a crash.

Mitigation

  • Replace the affected Brotli package or image with a vendor-fixed build.
  • Restart or redeploy every process that loaded the old decoder.
  • Until the update is complete, remove untrusted Brotli decoding paths and disable unused XML-RPC pingbacks.

Upstream fixed the maintained Brotli branches in 1.0.10, 1.1.1, and 1.2.1. Distribution vendors can backport the fix. Use the vendor advisory and package changelog, not only the displayed version.

References

  • GitHub advisory GHSA-9v8h-qqgm-4m35
  • Google Brotli 1.2.1 security release
  • Upstream decoder fix
  • WordPress pingback_ping() reference
  • WordPress wp_safe_remote_get() reference
  • dimasma0305/CVE-2026-111497-POC (prior public PoC)
Download Tool