
End-to-end: a guest stores a serialized PHP object through the public application form, the admin opens the applicants list, and the gadget chain drops a webshell.
Unauthenticated PHP Object Injection in the Simple Job Board WordPress plugin (PressTigers). A guest stores a serialized PHP object through the public application form; when an admin later opens the applicants list, the plugin unserializes it and a third-party gadget chain turns it into remote code execution.
| CVE | CVE-2024-1813 |
| Plugin | Simple Job Board (PressTigers) |
| Vulnerable | ≤ 2.11.0 |
| Patched | 2.11.1 |
| Type | PHP Object Injection (insecure deserialization) |
| Auth | None (pre-auth injection) |
| Trigger | Admin opens the applicants list (normal workflow) |
| CVSS | 9.8 |
📖 Full technical write-up: https://mobeta.fr/blog/
This repository is the companion lab and PoC. The detailed analysis (root cause, the double
unserialize, building the POP chain, WAF bypass) lives in the blog post.
.
├── sjb_cve_2024_1813.py # the PoC (builds + sends the payload)
├── LICENSE
└── lab/
├── docker-compose.yml # WordPress + MariaDB + vulnerable plugins
├── setup/setup.sh # one-shot provisioning (wp-cli)
└── trigger_exploit.sh # simulates the admin opening the applicants list
Reproduces the vulnerable stack: WordPress 6.9.4 / PHP 8.3 / MariaDB 10.11 with Simple Job Board 2.10.8 (source + sink) and All In One SEO 4.5.6 (the gadget chain).
cd lab
docker compose up -d # boot + auto-provision
docker compose logs setup # prints the site URL, admin creds and job_id
Lab defaults: http://localhost:8081, admin admin / admin123!.
# 1. Store the payload (pre-auth). Replace 4 with the job_id from the setup logs.
python3 sjb_cve_2024_1813.py http://localhost:8081 4 'id > /tmp/RCE_PROOF.txt'
# 2. Fire the sink (plays the admin opening the applicants list).
cd lab && ./trigger_exploit.sh
# 3. Check the result.
docker exec sjb_lab_wp cat /tmp/RCE_PROOF.txt
Useful PoC flags:
--print-only - build and print the wire payload, no network traffic.--field - POST field name (must contain name; default jobapp_full_name).--int-prefix '+' - WAF-evasion variant of the serialized length prefix.--proxy http://127.0.0.1:8080 - route through Burp.unserialize() / maybe_unserialize() on post_meta;
prefer unserialize($data, ['allowed_classes' => false]).vendor/composer/installed.json so scoped library
versions cannot be fingerprinted.For authorized security testing and education only. Never run this against any system without explicit written permission from its owner.
MIT - see LICENSE.