$ k=v p &
[1] 3028
Gibt es eine Möglichkeit p
, den Inhalt von zu ändern, /proc/3028/environ
um nicht zu erwähnen, k=v
während p
noch läuft?
linux
security
process
linux-kernel
environment-variables
Cetin Sert
quelle
quelle
Antworten:
Unter Linux können Sie den Wert der Umgebungszeichenfolgen auf dem Stapel überschreiben.
Sie können den Eintrag also ausblenden, indem Sie ihn mit Nullen oder etwas anderem überschreiben:
Rennen wie:
das
k=v
wurde überschrieben mit\0\0\0
.Beachten Sie, dass
setenv("k", "", 1)
das Überschreiben des Werts nicht funktioniert. In diesem Fall wird eine neue"k="
Zeichenfolge zugewiesen.Wenn Sie die
k
Umgebungsvariable nicht anderweitig mitsetenv()
/ geändert habenputenv()
, sollten Sie auch in der Lage sein, die Adresse derk=v
Zeichenfolge auf dem Stapel (also einer von ihnen) abzurufen:Beachten Sie jedoch, dass nur einer der
k=v
in der Umgebung empfangenen Einträge entfernt wird . Normalerweise gibt es nur einen, aber nichts hindert jemanden daran, beidek=v1
undk=v2
(oderk=v
zweimal) die an übergebene env-Liste zu übergebenexecve()
. Dies war in der Vergangenheit die Ursache für Sicherheitslücken wie CVE-2016-2381 . Es könnte tatsächlichbash
vor dem Shellshock passieren , wenn sowohl eine Variable als auch eine Funktion mit demselben Namen exportiert werden.In jedem Fall wird es immer ein kleines Fenster geben, in dem die Zeichenfolge env var noch nicht überschrieben wurde. Daher möchten Sie möglicherweise einen anderen Weg finden, um die geheimen Informationen an den Befehl zu übergeben (z. B. eine Pipe), wenn Sie sie über verfügbar machen
/proc/pid/environ
ist ein Anliegen.Beachten Sie auch , dass im Gegensatz zu
/proc/pid/cmdline
,/proc/pid/environment
durch Prozesse mit demselben euid oder root nur zugänglich ist (oder root nur , wenn die euid und ruid des Prozesses nicht das Gleiche sind wie es scheint).Sie können diesen Wert vor ihnen verbergen
/proc/pid/environ
, aber sie können möglicherweise weiterhin jede andere Kopie der Zeichenfolge im Speicher abrufen, indem Sie beispielsweise einen Debugger an sie anhängen.Unter https://www.kernel.org/doc/Documentation/security/Yama.txt finden Sie Möglichkeiten, um zu verhindern, dass zumindest Nicht-Root-Benutzer dies tun.
quelle
Seit 2010 war es nicht erforderlich, die Zeichenfolgen über (nicht wirklich auf ) dem Stack des Hauptthreads unter Linux zu überschreiben .
Beide
/proc/self/cmdline
und können/proc/self/environ
vom Prozess selbst zur Laufzeit geändert werden, indem dieprctl()
Funktion mitPR_SET_MM_ARG_START
+PR_SET_MM_ARG_END
bzw.PR_SET_MM_ENV_START
+ aufgerufen wirdPR_SET_MM_ENV_END
. Diese setzen die Speicherzeiger direkt in den Anwendungsspeicherbereich des Prozesses, der vom Kernel für jeden Prozess gehalten wird und zum Abrufen des Inhalts von/proc/${PID}/cmdline
und/proc/${PID}/environ
und damit der vom Befehl gemeldeten Befehlszeile und Umgebung verwendet wirdps
.Man muss also einfach ein neues Argument oder eine neue Umgebungszeichenfolge erstellen (kein Vektor, beachten Sie - der Speicher, auf den verwiesen wird, muss die tatsächlichen Zeichenfolgendaten sein, verkettet und
␀
begrenzt) und dem Kernel mitteilen, wo er sich befindet.Dies ist in der Linux-Handbuchseite für die
prctl(2)
Funktion sowie auf derenviron(7)
Handbuchseite dokumentiert. Was nicht dokumentiert ist, ist, dass der Kernel jeden Versuch ablehnt, die Startadresse über der Endadresse oder die Endadresse unter der Startadresse festzulegen. oder um eine der Adressen auf Null (zurück) zu setzen. Dies ist auch nicht der ursprüngliche Mechanismus, den Bryan Donlan 2009 vorgeschlagen hatte und der es ermöglichte, Start und Ende in einer einzigen Operation atomar festzulegen. Darüber hinaus bietet der Kernel keine Möglichkeit , die aktuellen Werte dieser Zeiger abzurufen.Dies macht es schwierig, die Umgebung und die Befehlszeilenbereiche mit zu ändern
prctl()
. Dieprctl()
Funktion muss bis zu vier Mal aufgerufen werden, da die ersten Versuche dazu führen können, dass der Startzeiger höher als der Endzeiger gesetzt wird, je nachdem, wo sich die alten und neuen Daten im Speicher befinden. Man muss es noch vier Mal aufrufen, wenn man sicherstellen will, dass andere Prozesse im System nicht die Möglichkeit haben, einen beliebigen Bereich des Speicherplatzes des Prozesses in der Zeit des neuen Starts / Endes zu untersuchen wurde gesetzt, aber das neue Ende / Start wurde nicht gesetzt.Ein einziger Aufruf eines atomaren Systems, der den gesamten Bereich auf einmal festlegt, wäre für Anwendungsprogramme weitaus einfacher zu verwenden gewesen.
Eine weitere Falten ist , dass, ohne wirklich guten Grund (die Kontrollen im Kernel gegeben, die Überschreibbarkeit der ursprünglichen Datenbereiche sowieso , und die Tatsache , dass die Mittel nicht privilegierte Operationen auf einem der BSDs), auf Linux erfordert diese Super - User Privilegien.
Ich habe ziemlich einfach
setprocargv()
undsetprocenvv()
Funktionen für meine Toolsets geschrieben, die dies verwenden. Kettenladeprogramme aus den eingebauten Toolsets wiesetenv
undforeground
spiegeln somit die verketteten Befehlsargumente und die Umgebung wider, sofern Linux dies zulässt.Beachten Sie, dass dies nicht gegen Dinge spricht, die den Prozess verfolgen und auf andere Weise direkt auf seinen Speicher zugreifen (anstatt über diese beiden Pseudodateien), und natürlich ein Fenster verlässt, bevor die Zeichenfolgen geändert werden, in dem diese Informationen nur angezeigt werden wie das Überschreiben der Daten über dem Stapel des Hauptthreads. Und genau wie beim Überschreiben der Daten werden hier keine Sprachlaufzeitbibliotheken berücksichtigt, die unter verschiedenen Umständen Kopien der Umgebung (auf dem Heap) erstellen. Betrachten Sie dies im Allgemeinen nicht als einen so guten Mechanismus zum Übergeben von "Geheimnissen" an ein Programm, wie wenn Sie beispielsweise einen offenen Dateideskriptor an das Leseende einer unbenannten Pipe erben, der vollständig unter Ihrer Kontrolle in einen Eingabepuffer eingelesen wird dass du dann abwischst.
Weiterführende Literatur
quelle
/proc/$pid/stat
(neben anderen Werten, die Sie möglicherweise benötigenstruct prctl_mm_map
). Siehe auch mein Beispiel filter_env.c für eine kleine Demo. JdeBP, können Sie Links zu Ihrensetprocargv()
/setprocenvv()
Funktionen hinzufügen ?