Herkunft von nicht initialisiertem Speicher?



  • Bashar schrieb:

    SeppJ schrieb:

    Jedes gaengige Betriebssystem nullt den Speicher, auf den dein Programm zugreifen kann, vor Benutzung.

    Hast du dafür eine Quelle? Das hör ich zum ersten Mal.

    Wäre das Gegenteil nicht eine riesige Sicherheitslücke?



  • Tim06TR unlogged schrieb:

    Bashar schrieb:

    SeppJ schrieb:

    Jedes gaengige Betriebssystem nullt den Speicher, auf den dein Programm zugreifen kann, vor Benutzung.

    Hast du dafür eine Quelle? Das hör ich zum ersten Mal.

    Wäre das Gegenteil nicht eine riesige Sicherheitslücke?

    Ja.
    Unter Win kann man eine Datei anlegen oder eine eigene Datei öffnen und sie dann mit SetFileLength() oder so vergrößern und der Spreicher auf der Platte wird nicht gelöscht, sondern man kann halt lesen, was zufällig da auf den Sektoren steht. Man bekommt alte Dateifragmente von beliebigen Benutzern, mitunter auch Auslagerungsdatei. Böses Loch eigentlich, aber viel zu umständlich, was zu schreiben, was das in Massen ausnutzt.



  • Tim06TR unlogged schrieb:

    Wäre das Gegenteil nicht eine riesige Sicherheitslücke?

    Ja, deshalb ist es auch üblich, Puffer die zum Einlesen von Passwörtern verwendet wurden danach zu überschreiben. Da gabs mal ziemlichen Knatsch, weil der gcc das plötzlich wegoptimiert hat.

    Siehe z.B. hier: https://www.securecoding.cert.org/confluence/display/cplusplus/MSC06-CPP.+Be+aware+of+compiler+optimization+when+dealing+with+sensitive+data



  • Bashar schrieb:

    SeppJ schrieb:

    Jedes gaengige Betriebssystem nullt den Speicher, auf den dein Programm zugreifen kann, vor Benutzung.

    Hast du dafür eine Quelle? Das hör ich zum ersten Mal.

    Soweit ich mich erinnere, kann der DMA-Controller auch Speicher nullen/kopieren (man kann ja eine Speicherseite mit 0 vorhalten). Damit kostet es *keine* Prozessorzeit, Speicher vor der nächsten Verwendung zu nullen, es geht mit niedriger Priorität stillschweigend nebenher. Außer man saugt soo viel Speicher, was der I7 kann, daß das RAM nicht nachkommt. Dann wäre das "sichere" BS lahmer. Aber ich denke, daß normalerweise das "sichere" BS auch schlau sein könnte und eben jenem Prozess, der gerade RAM saugt, ihm unbereinigtes RAM geben könnte, was von ihm selber kommt. Und damit in der Praxis oder in Toms-Hardware-Tests nicht langsamer sein.



  • OK, das scheint wohl tatsächlich so gängig zu sein. Ich hab zwar immer noch keine Quelle, aber auf Stackoverflow sagen das alle, dann wird es wohl stimmen 😕


  • Mod

    Bashar schrieb:

    OK, das scheint wohl tatsächlich so gängig zu sein. Ich hab zwar immer noch keine Quelle, aber auf Stackoverflow sagen das alle, dann wird es wohl stimmen 😕

    Ich muss gerade sagen, dass ich auch ziemlich entsetzt bin, keine klare Quelle dazu zu finden. Ich habe das immer als Allgemeinwissen (zumindest fuer Programmierer) angesehen, ohne selber genau zu wissen, woher ich das ueberhaupt weiss. Und da ich gerade selber keine harten Quellen dafuer finde, befuerchte ich beinahe schon, dass dieses allgemeine Wissen eventuell falsch sein koennte. 😮
    Dass das alle auf Stackoverflow so sagen, bestaetigt nur, dass es allgemeines Wissen ist, aber die Quellenlage ist dann doch sehr duenn und haelt kritischer Betrachtung (bis jetzt) nicht stand. Laut Wikipedia steht das zumindest in der Single UNIX Specification so spezifiziert (fuer sbrk, welches letztendlich die Quelle fuer saemtlichen Speicher eines UNIX-Prozesses ist), aber da das ein viele tausend Seiten langes Dokument ist, mag ich da drin nicht suchen. Fuer Windows finde ich keine entsprechende Dokumentation, aber ich kenne mich mit Windows auch nicht aus, was da ueberhaupt der low-leveligste Systemcall ist, um vom Kernel Speicher zu erhalten.



  • SeppJ schrieb:

    aber ich kenne mich mit Windows auch nicht aus, was da ueberhaupt der low-leveligste Systemcall ist, um vom Kernel Speicher zu erhalten.

    Win hat einige!

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa365541(v=vs.85).aspx wurde im Text entschärft. Früher stand explizit drin, daß man unbereinigte Daten von der Platte lesen kann.

    Die Syscalls von Windows sind "geheim". Wenn man die Syscall kennt, kann man als Admin rohen Speicher lesen, wie unter Linux, aber das kann fast keiner. Man lädt eine System.DLL/so, die die Syscalls für einen macht und noch erheblich mehr, erheblich mehr, viele Prüfungen um Userspace, gerne auch mit switch/case auf mehrere syscalls mapt und auch gerne umgekehrt. Kompatibel bis runter nach Win3.1, das ist ja auch praktisch.

    Und undokumentiert wenn es politisch passt. Doku zu SetFilePointer() wurde ausgetauscht, fertig. Basta.



  • Bashar schrieb:

    https://www.securecoding.cert.org/confluence/display/cplusplus/MSC06-CPP.+Be+aware+of+compiler+optimization+when+dealing+with+sensitive+data

    However, it should be noted that both calling functions and accessing volatile qualified objects can still be optimized out (while maintaining strict conformance to the standard), so the above may still not work.

    Uhm... okay? Kann mir das jemand erklären?



  • Die gängigsten Speicherverwaltungsfunktionen unter Windows sind die Funktionen HeapAlloc , GlobalAlloc und LocalAlloc . Keine dieser Funktionen nullt den Speicher automatisch, aber das lässt sich über ein Flag im Aufruf steuern. Allein die Tatsache, dass eine dieser Funktionen ungenullten Speicher anfordern kann bedeutet, dass zumindest Windows bei der Speicherallokation den Speicher nicht automatisch nullt.
    Die Runtime des Visual Studio füllt den Speicher im Debug Modus aber automatisch mit "0xCD", aber ist kein Verhalten von Windows.

    Edit:
    Das gilt jetzt natürlich nur für korrekt angeforderten Speicher. Da das Nullen optional ist gehe ich davon aus, dass in nicht-initialisiertem Speicher zufällige Daten stehen.



  • SeppJ schrieb:

    Bashar schrieb:

    OK, das scheint wohl tatsächlich so gängig zu sein. Ich hab zwar immer noch keine Quelle, aber auf Stackoverflow sagen das alle, dann wird es wohl stimmen 😕

    Ich muss gerade sagen, dass ich auch ziemlich entsetzt bin, keine klare Quelle dazu zu finden. Ich habe das immer als Allgemeinwissen (zumindest fuer Programmierer) angesehen, ohne selber genau zu wissen, woher ich das ueberhaupt weiss. Und da ich gerade selber keine harten Quellen dafuer finde, befuerchte ich beinahe schon, dass dieses allgemeine Wissen eventuell falsch sein koennte. 😮

    Meiner Meinung nach ist es auch falsch.

    Denn warum sonst gibt es gibt es in Betriebssystemen spezielle Funktionen zum reservieren von Speicher für Passwörter?

    Wenn das OS alles Nullen würde, dann würde man solche Funktionen gar nicht benötigen, sie wären schlichtweg überflüssig.

    Ich bin daher der Meinung, dass der Speicher nicht genullt wird und man daher tatsächlich alte Daten von vorherigen Prozessen bekommt.



  • volkard schrieb:

    Unter Win kann man eine Datei anlegen oder eine eigene Datei öffnen und sie dann mit SetFileLength() oder so vergrößern und der Spreicher auf der Platte wird nicht gelöscht, sondern man kann halt lesen, was zufällig da auf den Sektoren steht.

    Das ist so nicht ganz richtig.
    Wenn du ein File einfach nur mit SetEndOfFile() vergrösserst, dann nullt Windows dir die Sektoren -- zumindest mit NTFS. Dazu wird zu jedem File eine "valid data length" mitgeführt. Wenn dahinter gelesen wird, bekommst du einfach Nullen zurück. Und wenn dahinter geschrieben wird, dann nullt Windows erstmal sämtliche Sektoren bis zu dem der geschrieben werden soll.
    Also neues File aufmachen, File-Länge mit SetEndOfFile() auf z.B. 10 GB stellen und dann auch nur einen Sektor dort schreiben = sehr lange warten.

    Wenn du das von dir beschriebene Verhalten willst, dann musst du noch zusätzlich SetFileValidData() aufrufen.
    Um SetFileValidData() aufzurufen brauchst du SE_MANAGE_VOLUME_NAME . Und das hast du als normaler User unter Windows per Default nicht.
    Und da man als Admin aber sowieso "raw reads" machen kann, ist das auch kein Sicherheitsproblem. Zumindest kein zusätzliches/neues.



  • Auskenner schrieb:

    Ich bin daher der Meinung, dass der Speicher nicht genullt wird und man daher tatsächlich alte Daten von vorherigen Prozessen bekommt.

    Prozesse bekommen grundsätzlich nur virtuellen Speicher, drin stehen kann aber nur was in physikalischem Speicher.
    Man muss also nur gucken wo/wie das Mapping zwischen virtuellen Adressen und physikalischem Speicher gemacht wird, und was da zu dem Thema steht.
    Und gemacht wird es mit VirtualAlloc , und da steht:

    Reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero, unless MEM_RESET is specified.

    MEM_RESET ist nur für Speicher verwendbar der vorher bereits committed war, d.h. in unserem Fall irrelevant.

    Mir wäre auch kein anderer Weg bekannt mit dem man Speicher in einen Prozess mappen kann, der diesen nicht mit Null initialisiert.

    Spezielle Funktionen für Passwörter etc. machen trotzdem Sinn:

    1. Es kann angreifer im selben Prozess geben, bzw. welche die über Admin Rechte aus nem anderen Prozess den Speicher lesen. Wenn nun etwas, was man dekodieren und dann ganz kurz prüfen musste, für ewig irgendwo im Speicher des Prozesses rumgammelt, dann wäre das schlecht.
    2. Es gibt Treiber, und da die in Ring 0 laufen, können die so-ziemlich-alles.
    3. Es gibt Dinge wie das Pagefile, und da sollten diese Daten auch nicht unbedingt drinnen landen.

    Windows hat übrigens sogar einen speziellen Systemprozess, der nur dafür zuständig ist Speicher, der gerade für nix gebraucht wird, mit Nullen vollzuschreiben. Wobei das auch durchaus für andere Dinge gut ist. z.B. dafür dass nicht unnötig Speicher auf dem Host belegt wird, wenn Windows in einer VM läuft.



  • DocShoe schrieb:

    Die gängigsten Speicherverwaltungsfunktionen unter Windows sind die Funktionen HeapAlloc , GlobalAlloc und LocalAlloc . Keine dieser Funktionen nullt den Speicher automatisch, aber das lässt sich über ein Flag im Aufruf steuern. Allein die Tatsache, dass eine dieser Funktionen ungenullten Speicher anfordern kann bedeutet, dass zumindest Windows bei der Speicherallokation den Speicher nicht automatisch nullt.

    Klar. Du kannst aber nie Speicher bekommen wo "Müll" aus einem anderen Prozess drinnen steht. Wichtiger Unterschied.

    Bevor der Heap Speicher "austeilen" kann, muss er nämlich erstmal einen Bereich virtueller Adressen für den Prozess mittels VirtualAlloc & co mit Speicher "hinterlegen". Und dabei wird genullt.


  • Mod

    Ok, dann haben wir jetzt eine harte Quelle fuer Linux und fuer Windows (ich setze einfach mal voraus, dass hustbaer sich besser auskennt, als Auskenner). Das beruhigt.



  • hustbaer schrieb:

    Auskenner schrieb:

    Ich bin daher der Meinung, dass der Speicher nicht genullt wird und man daher tatsächlich alte Daten von vorherigen Prozessen bekommt.

    Prozesse bekommen grundsätzlich nur virtuellen Speicher, drin stehen kann aber nur was in physikalischem Speicher.
    Man muss also nur gucken wo/wie das Mapping zwischen virtuellen Adressen und physikalischem Speicher gemacht wird, und was da zu dem Thema steht.
    Und gemacht wird es mit VirtualAlloc , und da steht:

    Reserves or commits a region of pages in the virtual address space of the calling process. Memory allocated by this function is automatically initialized to zero, unless MEM_RESET is specified.

    MEM_RESET ist nur für Speicher verwendbar der vorher bereits committed war, d.h. in unserem Fall irrelevant.

    Mir wäre auch kein anderer Weg bekannt mit dem man Speicher in einen Prozess mappen kann, der diesen nicht mit Null initialisiert.

    Spezielle Funktionen für Passwörter etc. machen trotzdem Sinn:

    1. Es kann angreifer im selben Prozess geben, bzw. welche die über Admin Rechte aus nem anderen Prozess den Speicher lesen. Wenn nun etwas, was man dekodieren und dann ganz kurz prüfen musste, für ewig irgendwo im Speicher des Prozesses rumgammelt, dann wäre das schlecht.
    2. Es gibt Treiber, und da die in Ring 0 laufen, können die so-ziemlich-alles.
    3. Es gibt Dinge wie das Pagefile, und da sollten diese Daten auch nicht unbedingt drinnen landen.

    Windows hat übrigens sogar einen speziellen Systemprozess, der nur dafür zuständig ist Speicher, der gerade für nix gebraucht wird, mit Nullen vollzuschreiben. Wobei das auch durchaus für andere Dinge gut ist. z.B. dafür dass nicht unnötig Speicher auf dem Host belegt wird, wenn Windows in einer VM läuft.

    Danke für die Erläuterung.



  • SeppJ schrieb:

    Ok, dann haben wir jetzt eine harte Quelle fuer Linux und fuer Windows (ich setze einfach mal voraus, dass hustbaer sich besser auskennt, als Auskenner). Das beruhigt.

    Ich kenne mich vermutlich diesbezüglich besser aus als Auskenner.
    Das heisst aber nicht, dass es nicht doch noch andere Wege geben könnte wie man Speicher in einen Prozess mappen kann. Ich hab ja nur geschrieben Mir wäre auch kein anderer Weg bekannt -- heisst ja nicht dass es dann keinen geben kann.



  • hustbaer schrieb:

    SeppJ schrieb:

    Ok, dann haben wir jetzt eine harte Quelle fuer Linux und fuer Windows (ich setze einfach mal voraus, dass hustbaer sich besser auskennt, als Auskenner). Das beruhigt.

    Ich kenne mich vermutlich diesbezüglich besser aus als Auskenner.
    Das heisst aber nicht, dass es nicht doch noch andere Wege geben könnte wie man Speicher in einen Prozess mappen kann. Ich hab ja nur geschrieben Mir wäre auch kein anderer Weg bekannt -- heisst ja nicht dass es dann keinen geben kann.

    Mega interessnat sowas. Wo zur Hölle hast du sowas gelernt?
    Ich will sowas auch lernen ^^





  • Und wie kommt man dazu sowas zu suchen? Ich meine sitzt ihr daheim, habt nichts zu tun und denkt: "Och das Buch hab ich schon 5 mal gelesen, ich geh mal aug msdn.com und lese ein wenig?"

    Man muss also nur gucken wo/wie das Mapping zwischen virtuellen Adressen und physikalischem Speicher gemacht wird, und was da zu dem Thema steht.
    Und gemacht wird es mit VirtualAlloc,

    Steht sowas in msdn?


  • Mod

    Sqw4n schrieb:

    Man muss also nur gucken wo/wie das Mapping zwischen virtuellen Adressen und physikalischem Speicher gemacht wird, und was da zu dem Thema steht.
    Und gemacht wird es mit VirtualAlloc,

    Steht sowas in msdn?

    Ja. Das habe ich gestern (nach Bashars Frage nach Quellen) selber recht schnell bei Google gefunden. Suchbegriffe dafuer duerften so etwas wie "Windows memory page allocate" oder vergleichbares gewesen sein. Auf diese Begriffe kommt man natuerlich nur, wenn man grob weiss, was virtual memory ist und dass moderne OS das benutzen, aber das sollte bei der Fragestellung hier im Thread wohl vorausgesetzt sein. Wenn man sich damit nicht auskennt, dann muss man natuerlich erst einmal Wikipedia oder aehnliches studieren, wie Speicherverwaltung ueberhaupt grob funktioniert.

    Ich war mir eben bloss nicht sicher, ob das wirklich die einzige low-level Methode der Windowsspeicherverwaltung ist. Natuerlich ist hustbaers Aussage (wie er schon selber schreibt), dass er keine andere kennt, keine absolute Versicherung. Aber hustbaer kennt sich ziemlich gut mit der Materie aus. Wenn er sagt, dass er keine andere Methode kennt, dann gibt es sehr wahrscheinlich keine anderen Methoden. Bloss irgendwelche undokumentierten NSA-Hintertueren.


Anmelden zum Antworten