做一次"黑客",入侵一次自己的服務(wù)器
前言
前兩天剛買了個騰訊服務(wù)器(CVM),這次登陸上去的時候特別卡,通過top發(fā)現(xiàn)負載特別高,因為是剛搭建的環(huán)境,也沒有運行什么應(yīng)用程序,所以我覺得這有點不正常。
我就想著把docker、mysql的后臺服務(wù)停了,然后再觀察一下負載能不能降下來,結(jié)果我發(fā)現(xiàn)常用的命令都無法使用了。
后來發(fā)現(xiàn)是docker遠程服務(wù)入侵,所以就利用docker遠程服務(wù)和redis服務(wù),模擬入侵了一次自己的服務(wù)器。
問題還原
又是平平淡淡似往常的一天,當(dāng)我使用systemctl命令想停掉后臺服務(wù)的時候,才發(fā)現(xiàn)我居然沒有執(zhí)行權(quán)限。

之前從沒遇到過這種情況,在我的認知里,root就是最高的存在。
先求助了一波客服,客服說是被入侵了,讓我重裝系統(tǒng)。在重裝前,又求助了我親愛的大學(xué)舍友,一安全大佬:馮胖,不!是馮佬。

問題分析
我:馮啊,我這個systemctl不能用了,咋回事???
馮:我上去給你看看也。
A few moments later....
馮:你這個2375端口是啥服務(wù),有沒有開啟遠程服務(wù)之類的。。。

我:這,這不是我前兩天剛開的docker遠程服務(wù)么。。。

馮:那就對了,通過docker遠程服務(wù)器入侵了你的服務(wù)器, 然后在利用masscan掃描其他服務(wù)器的docker遠程服務(wù)服務(wù),然后進行入侵。你這是「被遠程入侵當(dāng)做礦機了」,具體信息去/usr/share目錄看看就知道了
接著我去這個目錄看了一下。

打開config_background.json文件看了一下,果不其然,monero:門羅幣。

我:他是怎么登錄我的服務(wù)器呢?
馮:你忘了docker可以掛載主機目錄么,掛載.ssh目錄,然后把他的「主機公鑰直接放到authorized_keys中,不就可以免密登錄了嗎」!
恍然大悟!??!我去看了看,果然多了一個puppet的公鑰,

同時,home下也多了一個用戶目錄。

我:最后一個問題,我用root用戶,為什么很多命令都無法執(zhí)行?
馮:先用chmod將命令修改為讀寫狀態(tài),這樣就無法執(zhí)行了。再用chattr將命令屬性修改為只讀,這樣chmod就無法修改此命令權(quán)限了。
我:那我去查查資料....
查完資料后,我操作試了試。

如圖,這里拿ls舉例。根據(jù)421規(guī)則,1代表執(zhí)行權(quán)限,我先將ls權(quán)限修改為666,即只有讀寫權(quán)限,沒有執(zhí)行權(quán)限。其中l(wèi)sattr用來查看文件屬性,chattr修改文件屬性,也可以理解為比chmod管理更底層的文件權(quán)限的一個命令。
chattr +i就是讓ls只有只讀屬性,從圖中可以看出這時候ls就已經(jīng)無法執(zhí)行,使用lsattr也看到ls多了個i屬性,這時候我打算用chmod將其修改為755,即可執(zhí)行狀態(tài),這時候卻提示沒有權(quán)限。
接著我使用chattr -i去掉ls只讀屬性,就可以使用chmod將其修改為755可執(zhí)行狀態(tài)了,如圖,ls正常執(zhí)行。
我:可是為什么我連chattr命令都沒有執(zhí)行權(quán)限?
馮:......

我:大哥?。?!

馮:復(fù)制一個chattr,起個別名,然后用新的命令將chattr也修改成只讀,然后刪除命令的不就行了
我:不愧是我馮...
馮:周末去哪吃
我:.....

ssh公鑰注入實現(xiàn)提權(quán)
通過查閱一些資料,原理就是通過一些服務(wù)端口,將自己主機的公鑰寫入到靶機,實現(xiàn)免密登錄,獲取靶機root用戶權(quán)限。
關(guān)于ssh公鑰之前也講過。就是將A主機的公鑰,拷貝到B主機~/.ssh目錄下的authorized_keys文件中,即可建立互信實現(xiàn)免密登錄,即A主機登錄B主機將不需要輸入密碼。
而入侵者通過docker遠程服務(wù)和redis的快照功能,將某臺主機的公鑰寫入到authorized_keys,而免密登錄目標(biāo)主機,獲取root權(quán)限的行為,就是ssh公鑰提權(quán)。
之前只聽過sql注入、DDoS攻擊。對于這種可以直接登錄服務(wù)器進行操作的還是第一次遇見,所以我就拿自己的服務(wù)器實驗一下,反正一會兒都要重裝系統(tǒng)了。
這里準備了兩臺服務(wù)器,A主機用來運行docker的遠程服務(wù)和redis服務(wù),B主機用來遠程連接。
docker遠程服務(wù)入侵
其原理是利用docker的遠程服務(wù),可以遠程在靶機上起一個docker容器,并將靶機.ssh目錄掛載到容器中,然后進入docker的bash,直接將公鑰寫入到authorized_keys中。
開啟遠程端口
默認端口是2375,為了防止被其他機器掃到,所以這里先修改成6666。

遠程連接docker
登錄B主機并執(zhí)行下面命令,即可查看遠程主機運行了哪些容器。
docker -H tcp://47.102.xxx.xxx:6666 ps -a
平時我們都是使用docker ps來查看本機運行的容器,這里使用-H,指定A主機的IP和端口,即可以查看遠程主機的。

接著我們看看這臺主機上有什么鏡像:

遠程運行容器
在B主機上執(zhí)行以下命令,即可在B主機上遠程使用A主機上的鏡像,在A主機上運行一個容器。
# 掛載/etc/ssh目錄是為了修改sshd_config中PermitRootLogin為yes,允許root登錄
# 默認是允許root登錄的,所以沒對/etc/ssh/sshd_config進行修改
docker -H tcp://47.102.xxx.xxx:6666 run -it -v /root:/tmp/root -v /etc/ssh:/tmp/ect/ssh centos bash
通過-v將/root/.ssh目錄掛載到容器中的/tmp/root目錄下,那么在容器中就可以直接修改A主機上的authorized_keys,這里我只要將B主機的公鑰添加進去,B主機就可以免密登錄A主機了。

如圖,創(chuàng)建并運行了一個容器后,直接通過bash進入了容器。
寫入公鑰,實現(xiàn)入侵登陸
在容器中,查看authorized_keys文件的內(nèi)容。

如圖,目前authorized_keys只有一個公鑰,我們通過vi將B主機的公鑰添加進去,wq保存退出。

接著測試一下是否可以免密登錄。

如圖,B主機到A主機成功免密登錄。
redis動態(tài)配置入侵
其原理是利用redis的「RDB快照備份和命名行config命令動態(tài)修改配置功能」,將RDB的保存目錄修改成.ssh,文件名修改成authorized_keys。然后將公鑰作為value寫入redis,并使用bgsave命令開始備份,則將公鑰成功寫入到authorized_keys,實現(xiàn)免密登錄。
前提條件
使用root用戶運行的redis
沒有設(shè)置密碼
使用默認的6379端口
允許遠程IP訪問,即注釋掉bind配置以及將protected mode修改為no
沒有禁止動態(tài)修改配置功能
啟動redis
這里在A主機啟動了redis服務(wù),允許遠程訪問,并將端口修改為6666.
./redis-server ../conf/redis.conf

遠程連接redis
登錄B主機,遠程連接A主機的redis服務(wù)。
./redis-cli -h 47.102.xxx.xxx -p 6666
寫入公鑰,實現(xiàn)入侵登陸

如圖,先拷貝B主機的公鑰,為了在寫到authorized_keys后公鑰能占單獨一行,所以前后都進行了換行。
然后執(zhí)行以下命令,通過redis-cli將B主機公鑰寫入redis中。
cat id_das.pub | ./redis-cli -h 47.102.xxx.xxx -p 6666 -x set ssh-key
其中,-h:指定A主機的IP, -p:指定redis的端口,-x:將標(biāo)準輸入作為后面命令的參數(shù)
將公鑰寫入redis之后,再通過動態(tài)配置來修改RDB的目錄和文件名。
# 修改存儲目錄
config set dir /root/.ssh
# 修改rbd的文件名
config set dbfilename authorized_keys
# 立即將數(shù)據(jù)保存到文件中
bgsave
接著到A主機查看公鑰是否已經(jīng)寫入到authorized_keys中。

如圖,B主機公鑰寫入成功,最后也是成功免密登錄。
這時候可能會有人問,這是啥,authorized_keys中又是問號又是其他字符的,不會影響登陸嗎?
其實,這算是RDB文件的格式,所以為了不影響公鑰,之前我也在公鑰文件中前后都添加了換行,這樣就可以讓公鑰獨占一行,從而不影響免密登錄。
預(yù)防措施
docker
修改2375默認端口
遠程服務(wù)添加認證
或者直接不開放遠程服務(wù)
redis
修改6379默認端口
使用非root用戶運行redis
通過requirepass來設(shè)置密碼
禁止使用動態(tài)配置
# 在redis.conf中添加如下配置
rename-command CONFIG ""
這樣,在命令行就無法使用config命令進行動態(tài)配置。

結(jié)語
上面通過redis和docker來獲取主機權(quán)限的手段,可能真實的場景要更復(fù)雜地多,對安全大佬更是不值一提,但是對于我這種安全零基礎(chǔ)的人來說,遇到還是很新奇的,所以通過文章記錄了一下此次經(jīng)歷,也當(dāng)做一次頗為有趣的體驗。
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號
好文章,我在看??
