Ich möchte einen Zuordner erstellen, der Speicher mit den folgenden Attributen zur Verfügung stellt:
Die Idee ist, dass dies vertrauliche Informationen (wie Lizenzinformationen) enthält, auf die der Benutzer keinen Zugriff haben sollte. Ich habe die üblichen Recherchen online durchgeführt und ein paar andere Leute dazu befragt, aber ich kann keinen guten Startpunkt für dieses Problem finden.
Aktualisierungen
Josh erwähnt, dass VirtualAlloc
verwendet wird, um den Schutz für den Speicherplatz festzulegen . Ich habe einen benutzerdefinierten Zuordner erstellt (siehe unten). Ich habe festgestellt, dass die Funktion VirtualLock
die Speichermenge begrenzt, die ich zuweisen kann. Dies scheint jedoch von Entwurf zu sein. Da ich es für kleine Objekte verwende, ist das kein Problem.
und wird verwendet
%Vor%Ted Percival erwähnt mlock, aber ich habe noch keine Implementierung davon .
Ich fand Practical Cryptography von Neil Furguson und Bruce Schneier auch sehr hilfreich.
Sie können nicht wirklich vor dem Speicherzugriff schützen. Sie können das Paging wahrscheinlich verhindern, wenn Sie als Administrator oder als System arbeiten, aber Sie können nicht verhindern, dass der Administrator oder das System Ihren Speicher liest. Selbst wenn Sie andere Prozesse irgendwie daran hindern könnten, Ihren Speicher zu lesen (was Sie nicht können), könnte ein anderer Prozess tatsächlich einen neuen Thread in Ihren Prozess einfügen und den Speicher auf diese Weise lesen.
Auch wenn Sie Ihren Prozess irgendwie vollständig sperren und sicherstellen könnten, dass das Betriebssystem niemals anderen Personen den Zugriff auf Ihren Prozess ermöglicht, haben Sie immer noch keinen vollständigen Schutz. Das gesamte Betriebssystem könnte auf einer virtuellen Maschine ausgeführt werden, die jederzeit angehalten und überprüft werden kann.
Sie können Speicherinhalte nicht vom Eigentümer des Systems schützen. Hollywood und die Musikindustrie haben seit Jahren dafür gesorgt. Wenn es möglich wäre, würden sie es schon tun.
Wenn Sie für Windows entwickeln, gibt es Möglichkeiten, den Zugriff auf den Arbeitsspeicher zu beschränken, aber das vollständige Blockieren anderer ist nicht möglich. Wenn Sie hoffen, ein geheimes Geheimnis zu bewahren, lesen Sie Secure Code schreiben - die dieses Problem einigermaßen anspricht, aber beachten Sie, dass Sie nicht wissen können, ob Ihr Code auf einem echten Computer oder einer virtuellen Maschine ausgeführt wird. Es gibt eine Menge Win32-API-Kram, der sich mit solchen Dingen beschäftigt, einschließlich der sicheren Aufbewahrung von Geheimnissen - das Buch spricht darüber. Sie können sich die Microsoft CyproAPI Details anzeigen lassen. Die OS-Designer erkennen genau dieses Problem und die Notwendigkeit, den Klartext sicher zu halten (lesen Sie erneut Sicherer Code schreiben ).
Die Win32-API-Funktion VirtualAlloc
ist der Speicher auf Betriebssystemebene Zuweiser. Damit können Sie den Zugriffsschutz einstellen. Sie können den Zugriff auf PAGE_GUARD
oder PAGE_NOACCESS
ändern und den Zugriff auf etwas freundlicheres ändern, während Ihr Programm liest und danach zurücksetzt, aber das ist nur ein schneller Höcker, wenn jemand wirklich versucht, Ihr Geheimnis zu sehen .
Zusammenfassend können Sie sich die Crypto-APIs auf Ihrer Plattform ansehen, die das Problem besser angehen als etwas, das Sie selbst hacken.
Nehmen wir das Stück für Stück:
Ich möchte einen Allokator erstellen, der bietet Speicher mit folgenden Attribute:
Das ist fair genug.
%Vor%
Das wird schwer werden. Soweit mir bekannt ist, können Sie Virtual Paging nicht so deaktivieren, wie es vom Betriebssystem gehandhabt wird. Wenn es einen Weg gibt, dann wirst du in den Tiefen des OS speln.
%Vor%
Sie können es über PGP ausführen und es verschlüsselt im Speicher speichern und es bei Bedarf entschlüsseln. Massive Leistung getroffen.
Die Idee ist, dass dies enthalten wird sensible Informationen (wie Lizenz Informationen), die sein sollten für den Benutzer nicht zugänglich. Ich habe es getan die übliche Recherche online und fragte a wenige andere Leute darüber, aber ich Ich kann keinen guten Platz finden Problem.
Halten Sie alle vertraulichen Informationen vom Gerät fern. Ernst. Speichern Sie keine vertraulichen Informationen im Speicher. Schreiben Sie eine benutzerdefinierte Löschroutine, die automatisch alle Daten aus den von Ihnen ausgeführten Zuordnungen löscht. Niemals den allgemeinen Zugang zu einer Maschine mit empfindlichem Material erlauben. Wenn Sie den Datenbankzugriff ausführen, stellen Sie sicher, dass der gesamte Zugriff vor dem Brennen bereinigt wurde. Nur Personen mit bestimmten Anmeldedaten dürfen zugreifen. Kein allgemeiner Gruppenzugriff.
Nebenbei bemerkt, welche anderen Methoden sind dort auf den Speicher eines zugreifen Prozess anders als das Anfügen eines Debugger?
Einen Speicherauszug machen.
Auf Unix-Systemen können Sie mlock (2) verwenden, um Speicherseiten im RAM zu sperren und so zu verhindern, dass sie ausgelagert werden .
mlock () und mlockall () sperren jeweils einen Teil oder alle Anrufe den virtuellen Adressraum des Prozesses in den RAM-Speicher und verhindert, dass der Speicher in den Swap-Bereich ausgelagert werden.
Es gibt eine Grenze dafür, wie viel Speicher jeder Prozess sperren kann, er kann mit ulimit -l
angezeigt werden und wird in Kilobyte gemessen. Auf meinem System beträgt das Standardlimit 32 kB pro Prozess.
Installieren Sie Libsodium, verwenden Sie Zuweisungsmechanismen durch # include <sodium.h>
Langsamer als malloc () und Freunde benötigen sie 3 oder 4 zusätzliche Seiten virtuellen Speichers.
%Vor% Weisen Sie Speicher zu, um vertrauliche Daten mit sodium_malloc()
und sodium_allocarray()
zu speichern. Sie müssen zuerst sodium_init()
aufrufen, bevor Sie diese Heap-Wächter verwenden.
Die sodium_allocarray()
-Funktion gibt einen Zeiger zurück, von dem jeweils auf Zählobjekte zugegriffen werden kann, die die Größe von Bytes des Speichers haben. Es bietet dieselben Garantien wie sodium_malloc()
, schützt aber auch vor arithmetischen Überläufen, wenn count * size
SIZE_MAX
überschreitet.
Diese Funktionen fügen Schutzseiten um die geschützten Daten hinzu, um sie in einem Heartbleed-ähnlichen Szenario weniger zugänglich zu machen.
Darüber hinaus kann der Schutz für Speicherbereiche, die auf diese Weise zugeordnet sind, mit den sperrenden Speicheroperationen geändert werden: sodium_mprotect_noaccess()
, sodium_mprotect_readonly()
und sodium_mprotect_readwrite()
.
Nach sodium_malloc
können Sie sodium_free()
zum Entsperren und Freigeben von Speicher verwenden. An diesem Punkt in Ihrer Implementierung sollten Sie den Speicher nach der Verwendung auf Null setzen.
Nach der Verwendung sollten sensible Daten überschrieben werden, aber memset () und handgeschriebener Code können automatisch durch einen optimierenden Compiler oder den Linker entfernt werden.
Die Funktion sodium_memzero () versucht, len Bytes beginnend mit pnt effektiv zu zerlegen, selbst wenn Optimierungen auf den Code angewendet werden.
Die Funktion sodium_mlock()
sperrt mindestens len Bytes des Speichers ab addr. Auf diese Weise können Sie verhindern, dass vertrauliche Daten auf die Festplatte ausgelagert werden.
Die Funktion sodium_mprotect_noaccess () macht eine Region unzugänglich, die mithilfe von sodium_malloc () oder sodium_allocarray () zugewiesen wurde. Es kann nicht gelesen oder geschrieben werden, aber die Daten bleiben erhalten. Diese Funktion kann verwendet werden, um vertrauliche Daten unzugänglich zu machen, außer wenn sie tatsächlich für eine bestimmte Operation benötigt werden.
%Vor%Die Funktion sodium_mprotect_readonly () markiert eine Region, die mit natrium_malloc () oder natrium_allocarray () als schreibgeschützt zugewiesen wurde. Wenn Sie versuchen, die Daten zu ändern, wird der Prozess beendet.
%Vor% Die Funktion sodium_mprotect_readwrite()
markiert eine Region, die mit sodium_malloc()
oder sodium_allocarray()
als lesbar und schreibbar zugewiesen wurde, nachdem sie mit sodium_mprotect_readonly()
oder sodium_mprotect_noaccess()
geschützt wurde.
Was Sie fordern, wird auf Betriebssystemebene behandelt. Sobald die Daten in Ihrem Programm sind, wird es wahrscheinlich ausgelagert.
Für den Zugriff auf den Speicher kann eine motivierte Person einen Hardware-Debugger anhängen.
@graham
Sie können es über PGP ausführen und es verschlüsselt im Speicher speichern und es bei Bedarf entschlüsseln. Massive Leistung getroffen.
Dann müssten Sie den Schlüssel im Speicher halten. Das würde es etwas schwieriger machen, aber definitiv nicht unmöglich. Jeder, der motiviert ist, wird es schaffen, die Daten aus dem Speicher zu holen.
Am besten ist es, etwas Ähnliches wie die SecureString-Klasse von .NET zu implementieren und darauf zu achten, dass alle Klartextkopien Ihrer Daten sofort gelöscht werden (vergessen Sie nicht, das Programm zu bereinigen, auch wenn Ausnahmen ausgelöst werden). Eine gute Möglichkeit, dies mit std :: string zu tun, ist die Verwendung eines benutzerdefinierten Zuordners .
Wenn Sie unter Windows CryptProtectMemory (oder RtlEncryptMemory für ältere Systeme) verwenden, wird das Verschlüsselungskennwort in nicht umlagerbarem (Kernel?) Speicher gespeichert. In meinen Tests sind diese Funktionen ziemlich verdammt schnell, insb. unter Berücksichtigung des Schutzes, den sie Ihnen geben.
Auf anderen Systemen verwende ich gerne Blowfish, da es eine gute Mischung aus Geschwindigkeit und Stärke ist. In letzterem Fall müssen Sie beim Programmstart nach dem Zufallsprinzip Ihr eigenes Passwort (16+ Byte Entropie für Blowfish) generieren. Leider gibt es nicht viel, was Sie tun können, um dieses Passwort ohne Betriebssystemunterstützung zu schützen, obwohl Sie allgemeine Verschleierungstechniken verwenden könnten, um einen hartcodierten Salt-Wert in Ihre ausführbare Datei einzubetten, den Sie mit dem Passwort kombinieren können (jedes bisschen hilft).
Insgesamt ist diese Strategie nur ein Teil eines breiter angelegten Defense-in-Depth-Ansatzes. Denken Sie auch daran, dass einfache Fehler wie Pufferüberläufe und das Bereinigen von Programmeingaben bei weitem die häufigsten Angriffsvektoren bleiben.
Sie können den Speicherinhalt nicht vom Eigentümer des Systems schützen. Hollywood und die Musikindustrie haben seit Jahren dafür gesorgt. Wenn es möglich wäre, würden sie es schon tun.
Haben Sie sich Vista angesehen (und darüber) Geschützte Prozesse (direkt .doc herunterladen ). Ich glaube, dass der Schutz durch den Betriebssystem-Schutz der Unterhaltungsindustrie zu Gute kommt.
@Derek: Oh, aber mit Trusted Computing können Sie Memory Curtaining verwenden! : -P & lt; / devils-advocate & gt;
@roo
Ich habe wirklich gehofft, dass das möglich ist und ich es noch nicht gefunden habe. Ihr Beispiel hat mir gerade klar gemacht, dass wir genau das versuchen - nur Zugriff auf Dateien im Kontext unseres Programms erlauben und so die IP erhalten.
Ich glaube, ich muss akzeptieren, dass es keine wirklich sichere Möglichkeit gibt, Dateien von jemandem auf einem anderen Computer zu speichern, besonders wenn der Besitzer zu einem bestimmten Zeitpunkt Zugriff auf diese Datei hat.
Das ist definitiv das Problem. Sie können etwas sicher speichern, solange Sie niemals Zugriff gewähren, aber sobald Sie Zugriff gewähren, ist Ihre Kontrolle weg. Sie können es ein bisschen schwieriger machen, aber das ist alles.
@ Chris
Oh, aber mit Trusted Computing können Sie Memory Curtaining verwenden! :-P
Aber dann muss man tatsächlich bereit sein, für einen Computer zu bezahlen, den jemand anders besitzt. : p
@Derek Park
Er sagte nur härter, nicht unmöglich. PGP würde es schwieriger machen, nicht unmöglich.
Tags und Links memory c++ security ram-scraping