Root-Privilegien können in Python auch nach Setzen von seteuid nicht fallen gelassen werden. Ein Bug?
BEARBEITEN Zusammenfassung: Ich habe vergessen, die gid abzulegen. Die akzeptierte Antwort könnte Ihnen dennoch helfen.
Hallo. Ich kann in Python 3.2 auf meinem Linux die Root-Berechtigung nicht ablegen. Tatsächlich kann es selbst nach seteuid(1000) root-eigene Dateien mit 400-Berechtigungen lesen. Die euid ist definitiv auf 1000 gesetzt!
Ich habe herausgefunden, dass der privilegierte Zugriff nach einem leeren os.fork() -Aufruf korrekt verweigert wird. (Aber das passiert nur im Elternprozess. Das Kind kann immer noch ungerechtmäßig lesen.) Ist das ein Bug in Python oder liegt es an Linux?
Probieren Sie den untenstehenden Code aus. Kommentieren Sie eine der drei Zeilen am Ende aus und führen Sie ihn als Root aus.
Vorab vielen Dank.
#!/usr/bin/python3
# Beispiel für ein Problem mit Python seteuid.
# Führen Sie dies als den Root aus.
# Hier wird versucht, auf root-eigene Dateien /etc/sudoers und /etc/group zuzugreifen.
# Einfacher Zugriff auf sie *gelingt* auch nach seteuid(1000), was fehlschlagen sollte.
# Drei Funktionen, stillRoot(), forkCase() und workAround(), sind definiert.
# Die ersten beiden scheinen falsch zu sein. In der letzten funktioniert der Zugriff wie gewünscht.
# ***Kommentieren Sie*** eine der drei Zeilen am Ende aus, bevor Sie es ausführen.
# Wenn Ihr Python < 3.2 ist, kommentieren Sie die gesamte Definition von forkCase() aus.
import os
def stillRoot():
"""Das Öffnen gelingt, obwohl es fehlschlagen sollte."""
os.seteuid(1000)
open('/etc/sudoers').close()
def forkCase():
"""Das Kind kann es immer noch öffnen. Wow."""
# setresuid benötigt Python 3.2
os.setresuid(1000, 1000, 0)
pid = os.fork()
if pid == 0:
# Sie sind sicherlich 1000, nicht 0!
print('UID: ', os.getuid(), 'EUID: ', os.geteuid())
open('/etc/sudoers').close()
print('Öffnen im Kind erfolgreich.')
exit()
else:
print('Kind-PID: ', pid)
open('/etc/group').close()
print('Elternprozess konnte öffnen.')
def workAround():
"""Also, ist ein Dummy-Fork nach seteuid notwendig?"""
os.seteuid(1000)
pid = os.fork()
if pid == 0:
exit(0)
else:
os.wait()
open('/etc/group').close()
## Führen Sie eine von ihnen aus.
# stillRoot()
# forkCase()
# workAround()