Frage Wie sollte ich vor harten Linkangriffen schützen?


  • Ich möchte Daten an eine Datei in / tmp anhängen.
  • Wenn die Datei nicht existiert, möchte ich sie erstellen
  • Es ist mir egal, ob jemand anderes die Datei besitzt. Die Daten sind nicht geheim.
  • Ich möchte nicht, dass irgendjemand in der Lage ist, das zu race-konditionieren, um irgendwo anders oder in eine andere Datei zu schreiben.

Was ist der beste Weg, dies zu tun?

Hier ist mein Gedanke:

fd = open("/tmp/some-benchmark-data.txt", O_APPEND | O_CREAT | O_NOFOLLOW | O_WRONLY, 0644);
fstat(fd, &st);
if (st.st_nlink != 1) {
    HARD LINK ATTACK!
}

Problem damit: Jemand kann die Datei mit einer kurzlebigen Datei von mir verknüpfen, so dass /tmp/some-benchmark-data.txt dasselbe ist wie / tmp / tmpfileXXXXXX, das ein anderes Skript von mir verwendet (und ordnungsgemäß geöffnet wurde) O_EXCL und all das). Meine Benchmark-Daten werden dann an diese Datei / tmp / tmpfileXXXXXX angehängt. solange es noch benutzt wird.

Wenn mein anderes Skript seine temp-Datei geöffnet hat, lösche es und verwende es; dann würde der Inhalt dieser Datei durch meine Benchmark-Daten beschädigt werden. Dieses andere Skript müsste dann seine Datei zwischen dem open () und dem fstat () des obigen Codes löschen.

Also mit anderen Worten:

This script          Dr.Evil        My other script or program
                                    open(fn2, O_EXCL | O_CREAT | O_RDWR)
                     link(fn1,fn2)
open(fn1, ...)
                                     unlink(fn2)
fstat(..)=>link is 1
write(...)
close(...)
                                    write(...)
                                    seek(0, ...)
                                    read(...) => (maybe) WRONG DATA!

Und deshalb funktioniert die obige Lösung nicht. Es gibt möglicherweise andere Angriffe.

Was ist der richtige Weg? Außerdem kein weltweit schreibbares Verzeichnis.

Bearbeiten: Um gegen das Ergebnis zu schützen, dass der böswillige Benutzer die Datei mit seinen Eigentumsrechten und Berechtigungen oder nur mit falschen Berechtigungen erstellt (indem er Ihre Datei fest verknüpft und dann das Original entfernt oder eine kurzlebige Datei festlegt), kann ich das tun Überprüfen Sie die Eigentümer- und Berechtigungsbits nach dem nlink-Check.

Es würde kein Sicherheitsproblem geben, aber auch Überraschungen verhindern. Im schlimmsten Fall bekomme ich einige meiner eigenen Daten (aus einer anderen Datei) am Anfang der Datei, die aus einer anderen Datei kopiert wurden.

Bearbeiten 2: Ich denke, es ist fast unmöglich, jemanden davor zu schützen, den Namen mit einer Datei zu verknüpfen, die geöffnet, gelöscht und dann verwendet wird. Beispiele hierfür sind EXE-Packer, die manchmal sogar die gelöschte Datei über / proc / pid / fd-num ausführen. Wenn Sie damit fortfahren, würde die Ausführung des gepackten Programms fehlschlagen. lsof könnte wahrscheinlich herausfinden, ob jemand anders den Inode geöffnet hat, aber es scheint mehr Ärger zu geben, als es wert ist.


7
2018-03-31 06:01


Ursprung


Antworten:


Was auch immer Sie tun, Sie erhalten in der Regel eine Race-Bedingung, bei der ein anderer Benutzer eine Verknüpfung erstellt und diese dann löscht, wenn Ihr fstat () - Systemaufruf ausgeführt wird.

Du hast nicht genau gesagt, was du verhindern willst. Es gibt sicherlich Kernel-Patches, die verhindern, dass (harte oder symbolische) Links zu Dateien, die Sie nicht besitzen, in weltweit schreibbaren Verzeichnissen (oder Sticky-Verzeichnissen) erstellt werden.

Es ist das Richtige, es in ein nicht weltweit schreibbares Verzeichnis zu stellen.

SELinux, das der Standard für erweiterte Sicherheits-Linux zu sein scheint, ist möglicherweise in der Lage, Richtlinien zu konfigurieren, um Benutzern zu verbieten, schlechte Dinge zu tun, die Ihre App beschädigen.

Im Allgemeinen, wenn Sie als root laufen, erstellen Sie keine Dateien in / tmp. Eine andere Möglichkeit besteht darin, setfsuid () zu verwenden, um Ihre Dateisystem-Benutzer-ID auf jemand anderen zu setzen. Wenn die Datei von diesem Benutzer nicht beschreibbar ist, schlägt die Operation einfach fehl.


2
2018-03-31 06:38



Abgesehen von dem, was Sie gerade illustriert haben, war das einzige, was ich probiert habe, fast genauso rassig und teurer, indem Sie inoffizielle Uhren auf / tmp eingerichtet haben vorher zum Erstellen der Datei, die das Abfangen des Ereignisses eines Hardlinks in einigen Fällen ermöglicht.

Allerdings ist es immer noch sehr rassig und ineffizient, da Sie auch eine breite erste Suche nach / tmp durchführen müssen, zumindest bis zu der Ebene, auf der Sie die Datei erstellen möchten.

Es gibt (meines Wissens) keinen "sicheren" Weg, diese Art von Rennen zu vermeiden, außer dass ich keine beschreibbaren Verzeichnisse benutze. Was sind die Konsequenzen, wenn jemand Ihren E / A über eine feste Verbindung abfängt? Würden Sie etwas Nützliches erhalten oder Ihre Anwendung nur undefiniertes Verhalten aufweisen?


1
2018-03-31 10:58