面試的時候碰到了Redis未授權通路的利用方式,當時記不清了,最近又重新複現了一遍,順便做了下總結!
一、漏洞簡介及影響
Redis安裝後,預設情況下,會綁定在 <code>0.0.0.0:6379</code>,如果沒有進行采用相關的政策,比如添加防火牆規則避免其他非信任來源 ip 通路等,這樣将會将 Redis 服務暴露到公網上,如果在沒有設定密碼認證(一般為空)的情況下,會導緻任意使用者在可以通路目标伺服器的情況下未授權通路 Redis 以及讀取 Redis 的資料。攻擊者在未授權通路 Redis 的情況下,利用 Redis 自身的提供的<code>config</code> 指令,可以進行寫檔案操作,攻擊者可以成功将自己的<code>ssh公鑰</code>寫入目标伺服器的 <code>/root/.ssh</code> 檔案夾的<code>authotrized_keys</code>檔案中,進而可以使用對應私鑰直接使用ssh服務登入目标伺服器。
總結來說,就是以下兩點:
(1)redis綁定在 0.0.0.0:6379,且沒有進行添加防火牆規則避免其他非信任來源ip通路等相關安全政策,直接暴露在公網; (2)沒有設定密碼認證(一般為空),可以免密碼遠端登入redis服務。
(1)攻擊者無需認證通路到内部資料,可能導緻敏感資訊洩露,黑客也可以惡意執行 <code>flushall</code> 來清空所有資料; (2)攻擊者可通過<code>EVAL</code>執行lua代碼,或通過資料備份功能往磁盤寫入後門檔案; (3)最嚴重的情況,如果 Redis 以 root 身份運作,黑客可以給root賬戶寫入SSH公鑰檔案,直接通過SSH登入受害伺服器
Redis 2.x,3.x,4.x,5.x
二、前期準備工作
在正式複現之前,先說明一下SSH免密登入的原理,因為這個也是危害最大的一個。
SSH提供兩種登入驗證方式:一種是密碼驗證也就是賬号密碼登入,另一種是密鑰驗證,這裡隻簡單說一下密鑰驗證的原理。
所謂密鑰驗證,其實就是一種基于公鑰密碼的認證,使用公鑰加密、私鑰解密,其中公鑰是公開的,放在伺服器端,你可以把同一個公鑰放在所有你想SSH遠端登入的伺服器中,而私鑰是保密的隻有你自己知道,公鑰加密的消息隻有私鑰才能解密,大體過程如下:
(1)用戶端生成私鑰和公鑰,并把公鑰拷貝給伺服器端; (2)用戶端發起公鑰認證請求,發送自己的相關資訊; (3)伺服器端根據用戶端發來的資訊查找是否存有該用戶端的公鑰,若沒有拒絕登入;若有則使用該公鑰對一個随機的256位的字元串進行加密,并發送給用戶端; (4)用戶端收到伺服器發來的加密後的消息後使用私鑰解密,并生成一個MD5值發送給伺服器端; (5)伺服器端根據原始随機字元串生成MD5值進行比對, 确認用戶端身份,若一樣則允許登入,不一樣則拒絕登入。
至此, 雙方互相确認對方身份并建立加密信道, 可以正式進行安全通信。
環境準備 兩台主機:(攻擊機Kali Linux,靶機Ubuntu 16.04.1) 源碼包:redis-3.2.11.tar.gz
(1)從官網下載下傳Redis源碼壓縮包
(2)解壓壓縮包
(3)進入安裝目錄,編譯執行
出現如下則編譯成功。
(4)拷貝<code>redis-server</code>和<code>redis-cli</code>拷貝到<code>/usr/bin</code>目錄
這樣做的目的就是友善以後使用該指令時,不必每次都進入安裝目錄,有點類似于<code>windows</code>下面配置環境變量
(5)啟動服務,修改配置檔案
傳回目錄<code>redis-3.2.11</code>,将<code>redis.conf</code>拷貝到<code>/etc/</code>目錄下
編輯<code>/etc/redis.conf</code>檔案,
在該行前面增加<code>#</code>,注釋ip綁定,允許除本地外的主機遠端登入redis服務
關閉保護模式,将<code>yes</code>改為<code>no</code>,允許遠端連接配接redis服務
(6)使用修改過後的配置檔案啟動<code>Redis</code>服務
由于Ubuntu和Kali Linux已經安裝有ssh服務,但預設沒有啟動,需使用<code>systemctl start sshd</code>指令啟動ssh服務。
最後我們再将上述步驟在kali裡面重新布置一次,使 kali 和 Ubuntu 都安裝redis服務。
至此,我們的準備工作就完成了。此時的redis服務是可以以root使用者身份遠端免密碼登入的。
三、未授權通路漏洞複現
(1)檢視IP位址,設定<code>Kali為攻擊機</code>,<code>Ubuntu</code>為受害機
(2)保證兩台虛拟機能夠互通
接下來,直接使用redis用戶端直接無賬号成功登入redis:
從登入的結果可以看出該redis服務已經對公網開放,且未啟用認證。
利用條件:
目标開啟了web伺服器,并且知道web路徑(可以利用phpinfo或者錯誤暴路徑等) 需要具有讀寫增删改查權限
在這裡,我們直接把shell寫入到網站根目錄下(<code>/var/www/html/</code>)
shell寫入完成,我們去靶機上證明:
成功寫入shell。
注意:
在寫入webshell的時候,可以使用:<code>\r\n</code>來換行,有些redis版本寫檔案會自帶一些版本檔案,可能導緻無法解析。
小技巧:
當資料庫過大時,redis寫shell:
原理:
在資料庫中插入一條資料,将本機的公鑰作為value,key值,然後通過修改資料庫的預設路徑為/root/.ssh和預設的緩沖檔案authorized.keys,把緩沖的資料儲存在檔案裡,這樣就可以在伺服器端的/root/.ssh下生一個授權的key。
(1)在靶機中執行 <code>mkdir /root/.ssh</code> 指令,建立ssh公鑰存放目錄(若是靶機使用過ssh服務,則會自動生成/root/.ssh檔案目錄)
(2)在攻擊機中生成ssh公鑰和私鑰,密碼設定為空:
(3)進入<code>.ssh</code>目錄:<code>cd .ssh/</code>,将生成的公鑰儲存到<code>pub_key.txt</code>:
(4)将儲存的pub_key.txt檔案内容寫入redis。
(5)設定redis的備份路徑為:<code>/root/.ssh/</code>
使用<code>CONFIG GET dir</code>可檢視目前備份路徑。
修改備份路徑為ssh公鑰存放目錄(預設為/root/.ssh/):
(6)設定上傳公鑰的備份檔案名為:<code>authorized_keys</code>。
(7)至此成功寫入ssh公鑰到靶機。測試ssh免密登入。
OK,成功利用私鑰登入redis伺服器!
在權限足夠的情況下,利用redis寫入檔案到<code>計劃任務</code>目錄下執行。
(1)在攻擊機監聽端口(未被占用)
(2)連接配接redis伺服器,寫入反彈shell。
......經過一分鐘左右就可以收到shell
四、修複建議
在<code>redis.conf</code>檔案找到如下配置
把 #bind 127.0.0.1前面的注釋#号去掉,然後把127.0.0.1改成你允許通路你的redis伺服器的ip位址,表示隻允許該ip進行通路,這種情況下,我們在啟動redis伺服器的時候不能再用:redis-server,改為:redis-server path/redis.conf 即在啟動的時候指定需要加載的配置檔案,其中path/是你上面修改的redis配置檔案所在目錄,這個方法有一點不太好,難免有多台機器通路一個redis服務。
打開redis.conf配置檔案,找到requirepass,然後修改如下: