rmdir konnte das leere Verzeichnis nicht entfernen

7

Ich habe ein Problem beim Entfernen des leeren Verzeichnisses. Strace zeigt einen Fehler an:

rmdir("empty_dir") = -1 ENOTEMPTY (Directory not empty)

Und ls -la empty_dirzeigt nichts. Also habe ich mich mit debugfs mit dem fs (ext4) verbunden und sehe die versteckte Datei in diesem Verzeichnis:

# 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  

Warum könnte das passieren? Und eine Chance, dieses Problem zu lösen, ohne die Fs abzunehmen und vollständig zu überprüfen?

Zusätzliche Information:

Die "versteckte" Datei ist nur eine normale JPG-Datei und kann vom Bildbetrachter geöffnet werden:

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 funktioniert nicht mit dem gleichen Fehler:

unlinkat(AT_FDCWD, "empty_dir", AT_REMOVEDIR) = -1 ENOTEMPTY (Directory not empty)

find empty_dir/ -inum 26808797 zeigt nichts.

Jo Kin
quelle
3
Haben Sie ein Rootkit auf Kernel-Ebene installiert? Das würde alle Arten von Chaos so machen.
Mukesh Sai Kumar
Es kann an Sonderzeichen in einem Dateinamen liegen, wenn die guten Methoden die Datei umbenennen, wenn dies von den Platzhaltern aus möglich ist ... oder wenn Sie Glück haben und nur das Verzeichnis entfernen möchten, das die rm -rf thatdirectorymeiste Zeit versucht Job. Andernfalls besteht die letzte Methode darin, die Datei von ihrer Inode-Nummer zu löschen. find . -inum [inode-number] -exec rm -i {} \;zum Beispiel
Francois P
debufs eine Datei zeigt noch als bestätigt registriert durch @Hauke Laging
francois P
1
@MukeshSaiKumar Dies ist ein Sicherungsserver mit einer minimalen Anzahl von Prozessen und ohne öffentlichen Netzwerkzugriff. Es gibt keine unbekannten Prozesse, Kernelmodule oder böswilligen Aktivitäten. Ich habe die Frage mit zusätzlichen Informationen bearbeitet.
Jo Kin
1
@ MukeshSaiKumar Du hattest Recht mit dem Rootkit. Ich habe eine Antwort hinzugefügt.
Jo Kin

Antworten:

4

Ich spannte mich an lsund bekam mehr Informationen zum Graben (gestrippte unwichtige Systemaufrufe):

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

Hmm, wir sehen, dass syscall getdentskorrekt funktioniert und alle 3 Einträge ('.', '..' und '_--- *') zurückgegeben hat, aber lsnur '.' Geschrieben hat . und '..'. Dies bedeutet, dass wir ein Problem mit dem Wrapper haben, um getdentsden Coreutils verwendet wird. Und Coreutils verwenden readdirGlibc Wrapper für getdents. Auch zu beweisen , dass es keine Probleme mit getdentsi wenig prog aus Beispiel Abschnitt getdents' getestet Mann - Seite. Dieser Prog zeigte alle Dateien.

Vielleicht haben wir gerade einen Fehler im Glibc gefunden? Also habe ich das glibc-Paket auf die letzte Version in meiner Distribution aktualisiert, aber kein gutes Ergebnis erzielt. Außerdem habe ich in Bugzilla keine entsprechenden Informationen gefunden.

Gehen wir also tiefer:

# 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

Warte was? libncom.so.4.0.1? Keine libc? Ja, wir sehen nur eine böswillige gemeinsam genutzte Bibliothek mit libc-Funktionen zum Ausblenden böswilliger Aktivitäten:

# 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

Entfernen von Rootkit-Dateien, Überprüfen aller rpm -VaPaketdateien ( in meinem Fall), Autostart-Skripte, Preload / Prelink-Konfigurationen, Systemdateien ( find /+ rpm -qfin meinem Fall), Ändern betroffener Kennwörter, Suchen und Beenden von Rootkit-Prozessen:

# for i in /proc/[1-9]*; do name=$(</proc/${i##*/}/comm); ps -p ${i##*/} > /dev/null || echo $name; done
_-minerd

Am Ende vollständige Systemaktualisierung, Neustart und Problem behoben. Grund für das erfolgreiche Hacken: ipmi-Schnittstelle mit sehr alter Firmware, die plötzlich über das öffentliche Netzwerk verfügbar war.

Jo Kin
quelle
Wow, Sie waren nett genug, um hier eine vollständige Offenlegung und Diagnose zu geben! +1 :)
Mukesh Sai Kumar
nur neugierig, ist "minerd" in 'ps' oder einem anderen Tool aufgetaucht? und wie hast du es zu ipmi gebracht?
Rajaganesh87
@ rajaganesh87 _-minerd-Prozess war für libproc-basierte Utils (ps, top usw.) unsichtbar, aber über procfs sichtbar (deshalb habe ich for-loop mit / proc / [1-9] * und ps -pfür jede pid verwendet zur Erkennung unsichtbarer Prozesse). Hacker haben böswilliges libproc-3.2.8.so kompiliert und in / lib / dir gefunden (libproc-3.2.8.so der Distribution befand sich in / lib64, aber / lib dir in dieser Distribution hat mehr Priorität, wenn gemeinsam genutzte Bibliotheken geladen werden). Mit gehacktem ipmi ist es möglich, den Server neu zu starten. Neustart -> grub -> init = / bin / bash -> Backdoor erstellen -> Neustart des normalen Systems erneut -> Backdoor für böswillige Aktivitäten verwenden.
Jo Kin
1

Innerhalb können debugfsSie die Datei löschen. Sie brauchen nicht einmal den Dateinamen (was relevant sein kann, wenn es Probleme mit Sonderzeichen gibt, wie Francois P in den Kommentaren vermutet hat):

kill_file <26808797>
Hauke ​​Laging
quelle
1
Ist es sicher auf montierten fs zu tun? In der Laborumgebung (frische ext4 auf Schleifengerät) nach kill_file für normale Datei und Erstellen einer neuen Datei bekam ich: touch: cannot touch '/test/3': Input/output errorundEXT4-fs error (device loop2): __ext4_new_inode:1111: comm touch: failed to insert inode 13: doubly allocated?
Jo Kin
Das gleiche Ergebnis mit rmvia debugfs auf gemounteten fs. Es ist also unsicher.
Jo Kin
@JoKin Ich bin kein Dateisystem-Experte und kann Ihnen daher nicht sagen, ob es einen Weg gibt, es wirklich sicher zu machen. Ich denke, es ist ziemlich sicher, solange der Seiten-Cache nicht den betroffenen Bereich enthält. Ich habe vergessen, wie das geht, aber IIRC kann man irgendwie den ganzen Seiten-Cache wegwerfen.
Hauke ​​Laging
@JoKin Weil du gefragt hast "ohne Abhängen und vollständige Überprüfung von fs", habe ich angenommen, dass umountalleine (ohne fsck) für dich OK wäre.
Hauke ​​Laging