Herkunft von nicht initialisiertem Speicher?



  • 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.



  • Sqw4n schrieb:

    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 ^^

    zieh dir mal Understanding the Linux Kernel rein, dort wird auf die Speicherverwaltung von Linux ziemlich genau eingegangen.
    Und auch wenn Linux und Windows zwei unterschiedliche Betriebssysteme sind, so sind doch viele Grundprinzipien gleich.
    Einen Vorteil hat Linux aber: der Sourcecode ist offen, wenn du wissen willst wie dies und jenes funktioniert schaust du z.B. bei http://lxr.linux.no vorbei und siehst dir die relevante Funktion an.



  • @Sqw4n
    Das sind Sachen die man sich im Laufe der Jahre erfragt/ergoogelt wenn einen das Thema ausreichend interessiert.

    Ich lese aber nicht einfach willkürlich irgendwas in der MSDN - ich such mir die Sachen schon sehr spezifisch aus. Wie Computer und Betriebssysteme so grundsätzlich funktionieren hat mich aber schon immer interessiert. Und dazu gehört auch wie z.B. Prozess-Isolation und virtueller Speicher funktioniert. Oder wo der Speicher "eigentlich herkommt" wenn man malloc bzw. new aufruft. Das sind einfach so grundlegende Dinge. Viele nehmen sowas einfach als gegeben, aber mich interessiert es halt wie das unter der Haube funktioniert.

    Genau so kannst du nen Auto-Freak fragen woher er weiss wie die ganzen Auto-Sachen eigentlich so funktionieren, von denen wir reinen Auto-Verwender auch nur ne sehr nebulöse Vorstellung haben (wenn überhaupt). Das interessiert die halt 😉



  • Ich kann zu ZwAllocateVirtualMemory leider auch keine Info zu dem Thema finden. Bloss nen ReactOS Unit-Test der prüft ob die Seiten die ZwAllocateVirtualMemory zurückgibt zero-filled wurden:

    http://jira.reactos.org/secure/attachment/18911/ZwAllocateVirtualMemory.c

    Was natürlich noch lange nicht heisst dass das auf Windows auch so sein muss. Bei dem Aufwand den MS in den letzten Jahren betrieben hat um die Sicherheit von Windows bzw. Windows-Programmen zu verbessern, würde es mich aber wirklich sehr wundern wenn es nicht so wäre. Also wenn es ein Loch gäbe, über den man an ohne die entsprechenden Berechtigungen an "Speicherüberreste" von anderen Prozessen kommen könnte.



  • hustbaer schrieb:

    Genau so kannst du nen Auto-Freak fragen woher er weiss wie die ganzen Auto-Sachen eigentlich so funktionieren, von denen wir reinen Auto-Verwender auch nur ne sehr nebulöse Vorstellung haben (wenn überhaupt). Das interessiert die halt 😉

    Einspruch, ein Auto aus den 70ern, also noch ohne das viele Elektronikgeraffel ist bestenfalls nur so komplex wie HTML.

    Komplex wird das erst auf Maschinenebene, wenn man sich z:B. fragt, welche Stahlsorte oder Materialen man für den Motorblock verwenden soll, da kann man dann ne Doktorarbeit drüber schreiben, aber so etwas lernt in der Regel kein Hobby Auto-Freak.

    Die ganze IT ist da allein vom Umfang her schon wesentlich komplexer.

    Das ein Ottomotor bei einem 4 Takter in 4 Schritten arbeitet:
    Ansaugen, verdichten & zünden, arbeiten und ausstoßen das weiß ich auch.
    Und bei n>=4 Taktern ist es nur noch eine Überschneidung, aber im wesentlich das gleiche.

    Wie so ein Getriebe funktioniert, das kriege ich auch noch hin. Wer früher als Kind mit Legotechnik gespielt hat, der kann sich das schon so vorstellen.


Anmelden zum Antworten