Tracing ohne Leserechte ausführbar

17

Ich habe unter Ubuntu 14.04 straceein überraschendes Verhalten bei der Verwendung einer ausführbaren Datei festgestellt , für die ich keine Leseberechtigung habe. Ich frage mich, ob dies ein Fehler ist oder ob ein Standard dieses undurchsichtige Verhalten vorschreibt.

Lassen Sie uns zuerst sehen, was passiert, wenn ich eine gewöhnliche ausführbare Datei im Hintergrund starte und an sie anhänge. Wie erwartet funktioniert dies:

$ /bin/sleep 100 &
[2] 8078
$ strace -p 8078
Process 8078 attached
restart_syscall(<... resuming interrupted call ...>

Als nächstes versuche ich es mit einer ausführbaren Datei, für die ich keine Leseberechtigung habe:

---x--x--x 1 root root 26280 Sep  3 09:37 sleep*

Das Anhängen an diesen laufenden Prozess ist nicht zulässig:

$ ./sleep 100 &
[1] 8089
$ strace -p 8089
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted

Das würde ich auch erwarten. Das Gewähren von Ausführungsberechtigungen ohne Leseberechtigung würde nicht viel nützen, wenn ich einfach einen Debugger an den Prozess anhängen und auf diese Weise effektiv Leseberechtigungen für die ausführbare Datei haben könnte.

Wenn ich die ausführbare Datei jedoch unter einem bereits verfolgten Prozess starte, darf ich dies tun:

$ strace ./sleep 100
execve("./sleep", ["./sleep", "100"], [/* 69 vars */]) = 0
brk(0)                                  = 0x9b7a000

Das ist für mich unerwartet. Handelt es sich um eine Sicherheitslücke, oder handelt es sich um eine von einem Standard vorgeschriebene Funktion?

Kasperd
quelle
3
@ StéphaneChazelas: Der Punkt ist, dass er es verfolgen kann, indem er es einfach als Argument benutzt, um es zu verfolgen. Die Hauptursache scheint zu sein, dass bei execveAufrufen die Leseberechtigungen der ausgeführten Datei nicht erneut überprüft werden, wenn der Prozess bereits verfolgt wird. Seine Frage ist , ob das ist ein Sicherheitsfehler oder eine ermächtigte Funktion (wenn dieser, würde ich es immer noch ein Sicherheitsproblem betrachten, nur eine Sicherheitslücke der Spezifikation).
Celtschk
@celtschk, sorry, ich habe die Frage zu schnell gelesen.
Stéphane Chazelas
1
Das EPERMscheint von get_dumpable()(wird auch verwendet, um zu prüfen, ob Core-Dumping erlaubt ist, also "dumpable") aufgerufen von __ptrace_may_access()aufgerufen von ptrace_attach()an kernel/ptrace.c.
Ninjalj
Stehen dem Debugger während der Ausführung eines Programms genügend Informationen zur Verfügung, um eine ausführbare ausführbare Datei mit seinem Code zu generieren, oder verwirft der Programmlader beispielsweise Korrekturen, die erforderlich wären, damit ein Programm tatsächlich funktioniert?
Supercat
@supercat Soweit ich weiß, hat der Debugger Zugriff auf den gesamten Benutzermoduscode, der ausgeführt wird, einschließlich des Verschiebungscodes. Mit dieser Zugriffsebene sollte es nicht allzu schwierig sein, eine funktionierende ausführbare Datei zu reproduzieren.
Kasperd

Antworten:

7

Dies ist keine Antwort, sondern eine Sammlung von Links und Gedanken, falls jemand anderes auch lernen möchte. Weil das eine interessante Sache ist.

Verwandte Antworten zu Unix & Linux, die erwähnen, dass es (oder war, kann derzeit nicht mit Vanilla-Kernel getestet werden) möglich ist, schreibgeschützte Binärdateien auf diese Weise zu sichern.

Grsecurity hat versucht, diese Konfigurationsoption und den Patch selbst zu reparieren (obwohl er sich seitdem möglicherweise geändert hat)

Dieses Commit lässt wirklich den Anschein erwecken, dass sich Kernel-Entwickler wirklich nur darum kümmern, suid-Binärdateien abzulegen.

Aber eigentlich würde ich von dieser Zeile aus vermuten, dass der Kernel verhindern möchte, dass unlesbare Binärdateien im Hinblick auf den SUID-Status entleert werden. Und diese Zeile legt nahe, dass Binärdateien, die nicht dumpbar sind, nicht rückverfolgbar sein sollten.

Auf den ersten Blick scheint es, als hätten Sie einen Fehler im Kernel gefunden, der Auswirkungen auf die Sicherheit hat. Aber ich bin kein Kernelentwickler, also kann ich nicht sicher sagen. Ich würde auf LKML fragen.

Edit: eine weitere Entdeckung in Bezug auf den Debugger, die in Kommentaren zum ursprünglichen Beitrag erwähnt wurde - von der schnellen Suche (wieder) scheint mir, dass gdb die nachverfolgten Binärdateien und verwendet /proc/<pid>/mem. Sobald die ausgeführte Binärdatei nicht mehr lesbar ist, wird cat /proc/<pid>/memzurückgegeben EPERM. Wenn die Binärdatei lesbar ist, wird sie zurückgegeben EIO. (Getestet auf Ubuntu 14.10, auf dem mehrere Sicherheitspatches ausgeführt werden. Dies unterscheidet sich möglicherweise vom Vanille-Kernel. Ich habe keinen Vanille-Kernel, der irgendwo zum Laufen kommt :()

Fuchs
quelle