rmdir 刪除空目錄失敗
我在刪除空目錄時遇到問題,strace 顯示錯誤:
rmdir("empty_dir") = -1 ENOTEMPTY (Directory not empty)
並且
ls -la empty_dir
什麼也不顯示。所以我用 debugfs 連接到 fs (ext4) 並看到這個目錄中的隱藏文件:# ls -lia empty_dir/ total 8 44574010 drwxr-xr-x 2 2686 2681 4096 Jan 13 17:59 . 44573990 drwxr-xr-x 3 2686 2681 4096 Jan 13 18:36 .. debugfs: ls empty_dir 44574010 (12) . 44573990 (316) .. 26808797 (3768) _-----------------------------------------------------------.jpg
為什麼會發生這種情況?有沒有機會在不解除安裝和全面檢查 fs 的情況下解決這個問題?
附加資訊:
“隱藏”文件只是一個普通的 jpg 文件,可以通過圖像查看器打開:
debugfs: dump empty_dir/_-----------------------------------------------------------.jpg /root/hidden_file # file /root/hidden_file /root/hidden_file: JPEG image data, JFIF standard 1.02
rm -rf empty_dir
沒有出現同樣的錯誤:unlinkat(AT_FDCWD, "empty_dir", AT_REMOVEDIR) = -1 ENOTEMPTY (Directory not empty)
find empty_dir/ -inum 26808797
什麼都不顯示。
我跟踪
ls
並獲得了更多資訊來探勘(剝離了不重要的系統呼叫):open("empty_dir", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 getdents(3, /* 3 entries */, 32768) = 80 write(1, ".\n", 2.) = 2 write(1, "..\n", 3..) = 3
嗯,我們看到系統呼叫
getdents
正常工作並返回了所有 3 個條目(’.’、’..’ 和 ‘_—*’),但ls
只寫了 ‘.’ 和 ‘..’。這意味著我們對getdents
coreutils 使用的包裝器有一些問題。並且 coreutils 使用readdir
glibc 包裝器用於getdents
.getdents
還要證明我從 getdents手冊頁的範例部分測試了小程序沒有問題。該編顯示了所有文件。也許我們剛剛在 glibc 中發現了一個錯誤?所以我將 glibc 包更新到我的發行版中的最後一個版本,但沒有得到任何好的結果。我也沒有在 bugzilla 中找到任何相關資訊。
所以讓我們更深入:
# gdb ls (gdb) break readdir (gdb) run Breakpoint 1, 0x00007ffff7dfa820 in readdir () from /lib64/libncom.so.4.0.1 (gdb) info symbol readdir readdir in section .text of /lib64/libncom.so.4.0.1
等等,什麼?libncom.so.4.0.1?不是libc?是的,我們只是看到了一個帶有 libc 函式的惡意共享庫,用於隱藏惡意活動:
# LD_PRELOAD=/lib64/libc.so.6 find / > good_find # find / > injected_find # diff good_find injected_find 10310d10305 < /lib64/libncom.so.4.0.1 73306d73300 < /usr/bin/_-config 73508d73501 < /usr/bin/_-pud 73714d73706 < /usr/bin/_-minerd 86854d86845 < /etc/ld.so.preload
刪除 rootkit 文件,檢查所有包的文件(
rpm -Va
在我的例子中),自動啟動腳本,預載入/預連結配置,系統文件(在我的例子中是find /
+rpm -qf
),更改受影響的密碼,查找和殺死 rootkit 的程序:# for i in /proc/[1-9]*; do name=$(</proc/${i##*/}/comm); ps -p ${i##*/} > /dev/null || echo $name; done _-minerd
最後完整系統更新,重新啟動並解決問題。黑客成功的原因:ipmi 介面帶有非常舊的韌體,突然可以從公共網路獲得。