Die Open-Source-Betriebssystemdistribution OpenBSD ist unter Systemadministratoren bekannt, insbesondere unter denen, die Server verwalten, für ihren Fokus auf Sicherheit über Geschwindigkeit, Funktionen und ausgefallene Frontends.
Passenderweise ist sein Logo vielleicht ein Kugelfisch – aufgeblasen, mit seinen Stacheln, die bereit sind, jeden gerissenen Hacker abzuwehren, der vorbeikommen könnte.
Aber das OpenBSD-Team ist wahrscheinlich am besten nicht für seine gesamte Distribution bekannt, sondern für das Fernzugriffs-Toolkit OpenSSH das Ende der 1990er Jahre für die Aufnahme in das Betriebssystem selbst geschrieben wurde.
SSH, kurz für sichere Hülle, wurde ursprünglich von einem finnischen Informatiker entwickelt Tatu Ylönen Mitte der 1990er Jahre in der Hoffnung, Systemadministratoren von der riskanten Angewohnheit abzubringen, das Telnet-Protokoll zu verwenden.
Das Problem mit Telnet
Telnet war bemerkenswert einfach und effektiv: Anstatt physische Kabel anzuschließen (oder ein Modem über eine Telefonleitung zu verwenden), um eine Teletype-Verbindung zu entfernten Servern herzustellen, verwendeten Sie stattdessen eine TELetype NETwork-Verbindung.
Grundsätzlich wurden die Daten, die normalerweise über eine dedizierte serielle Verbindung oder eine DFÜ-Telefonleitung hin und her fließen würden, über das Internet gesendet und empfangen, wobei eine paketvermittelte TCP-Netzwerkverbindung anstelle einer leitungsvermittelten Punkt-zu-Punkt-Verbindung verwendet wurde .
Gleiches vertrautes Anmeldesystem, günstigere Verbindungen, keine Notwendigkeit für dedizierte Datenleitungen!
Der große Fehler in Telnet war natürlich das völlige Fehlen von Verschlüsselung, so dass das Ausspähen Ihrer genauen Terminalsitzung trivial war und es Crackern ermöglichte, jeden von Ihnen eingegebenen Befehl zu sehen (sogar die Fehler, die Sie gemacht haben, und alle Male, die Sie getroffen haben). [Backspace]
), und jedes Byte der erzeugten Ausgabe …
…und natürlich Ihren Benutzernamen und Ihr Passwort zu Beginn der Sitzung.
Jeder in Ihrem Netzwerkpfad könnte Ihre Sysadmin-Sitzungen nicht nur problemlos in Echtzeit auf seinem eigenen Bildschirm rekonstruieren, sondern wahrscheinlich auch Ihre Sitzung manipulieren, indem er die Befehle ändert, die Sie an den Remote-Server gesendet haben, und die zurückkommenden Antworten vortäuscht, damit Sie es nicht bemerken die Ausflucht.
Sie könnten sogar einen Betrüger-Server einrichten, Sie dorthin locken und es Ihnen überraschend schwer machen, die Täuschung zu erkennen.
Starke Verschlüsselung FTW
Ylönens SSH zielte darauf ab, jedem Ende einer Telnet-ähnlichen Sitzung eine Schicht starker Verschlüsselung und Authentifizierung hinzuzufügen, wodurch eine sichere Hülle (dafür steht der Name, falls Sie sich jemals gefragt haben, obwohl fast jeder ihn einfach so nennt ess-ess-aitch heutzutage).
Es war ein sofortiger Hit, und das Protokoll wurde schnell von Systemadministratoren überall übernommen.
OpenSSH folgte bald, wie oben erwähnt, und erschien erstmals Ende 1999 als Teil des OpenBSD2.6 freizugeben.
Das OpenBSD-Team wollte eine freie, zuverlässige Open-Source-Implementierung des Protokolls schaffen, das sie und jeder andere könnte verwenden, ohne die lizenzrechtlichen oder kommerziellen Komplikationen, die Ylönens ursprüngliche Implementierung in den Jahren unmittelbar nach ihrer Veröffentlichung belastet hatten.
Wenn Sie den Windows-SSH-Server ausführen und sich jetzt von einem Linux-Computer aus mit ihm verbinden, verlassen Sie sich mit ziemlicher Sicherheit auf die OpenSSH-Implementierung an beiden Enden.
Das SSH-Protokoll wird auch in anderen beliebten Client-Server-Diensten verwendet, darunter SCP und SFTP, kurz für sichere Kopie und sicheres FTP bzw. SSH bedeutet frei übersetzt „sicher verbinden und am anderen Ende eine Befehls-Shell ausführen“, typischerweise für interaktive Anmeldungen, da das Unix-Programm normalerweise für eine Befehls-Shell steht /bin/sh
. SCP ist ähnlich, aber zum Kopieren von Dateien, da allgemein der Unix-Befehl file-copy aufgerufen wird /bin/cp
, und SFTP wird ähnlich benannt.
OpenSSH ist nicht das einzige SSH-Toolkit in der Stadt.
Andere bekannte Implementierungen sind: libssh2, für Entwickler, die SSH-Unterstützung direkt in ihre eigenen Anwendungen einbauen möchten; Fallbär, ein abgespeckter SSH-Server des australischen Programmierers matt johnston das ist weit verbreitet auf sogenannten IoT-Geräten (Internet of Things) wie Heimroutern und Druckern; und PuTTY, eine beliebte, kostenlose Sammlung von SSH-bezogenen Tools für Windows von unabhängigen Open-Source-Entwicklern Simon Tatham in England.
Aber wenn Sie ein normaler SSH-Benutzer sind, haben Sie sich heute mit ziemlicher Sicherheit mit mindestens einem OpenSSH-Server verbunden, nicht zuletzt, weil die meisten modernen Linux-Distributionen ihn als Standard-Fernzugriffstool enthalten und Microsoft sowohl einen OpenSSH-Client als auch ein OpenSSH anbietet Server als offizielle Windows-Komponenten in diesen Tagen.
Double-Free-Fehlerbehebung
OpenSSH-Version 9.2 kam gerade heraus, und die Versionshinweise wie folgt melden:
Diese Version enthält Korrekturen für […] ein Speichersicherheitsproblem. [Dieser Fehler] wird nicht als ausnutzbar angesehen, aber wir melden die meisten über das Netzwerk erreichbaren Speicherfehler als Sicherheitsfehler.
Der Fehler betrifft sshd
, der OpenSSH-Server (die -d
Suffix steht für Daemon, der Unix-Name für die Art von Hintergrundprozess, den Windows a nennt ):
sshd(8): Behebung eines doppelt freien Speicherfehlers bei der Vorauthentifizierung, der in OpenSSH 9.1 eingeführt wurde. Es wird nicht angenommen, dass dies ausnutzbar ist, und es tritt im unprivilegierten Pre-Auth-Prozess auf, der chroot(2) unterliegt und auf den meisten großen Plattformen weiter in einer Sandbox ausgeführt wird.
Ein Double-Free-Bug bedeutet, dass ein Speicherblock, den Sie bereits an das Betriebssystem zurückgegeben haben, um in anderen Teilen Ihres Programms wiederverwendet zu werden …
…wird später wieder von einem Teil des Programms zurückgegeben, der diesen Speicher eigentlich nicht mehr „besitzt“, aber nicht weiß, dass er es nicht hat.
(Oder absichtlich auf Aufforderung von Code zurückgegeben, der versucht, den Fehler absichtlich zu provozieren, um a Verwundbarkeit In ein ausbeuten.)
Dies kann zu subtilen und schwer zu entwirrenden Fehlern führen, insbesondere wenn das System den freigegebenen Block beim ersten Mal als verfügbar markiert free()
passiert, weist es später einem anderen Teil Ihres Codes zu, wenn es nach Speicher via fragt malloc(
) und markiert dann beim überflüssigen Aufruf den Block wieder frei free()
erscheint.
Das bringt Sie in die Situation, die Sie erleben, wenn Sie in ein Hotel einchecken, das sagt: „Oh, gute Neuigkeiten! Wir dachten, wir wären voll, aber ein anderer Gast hat sich entschieden, früher auszuchecken, damit Sie sein Zimmer haben können.“
Auch wenn das Zimmer beim Eintreten sauber geputzt und für neue Bewohner hergerichtet ist und somit so aussieht, als wäre es ordnungsgemäß für Ihre exklusive Nutzung reserviert worden, müssen Sie dennoch darauf vertrauen, dass die Keycard des vorherigen Gastes tatsächlich korrekt entwertet wurde und dass „ früher Check-out“ war kein listiger Trick, um später am selben Tag zurückzuschleichen und Ihren Laptop zu stehlen.
Bugfix für Bugfix
Wenn Sie sich die aktuelle OpenSSH-Codehistorie ansehen, werden Sie ironischerweise feststellen, dass OpenSSH einen geringfügigen Fehler in einer aufgerufenen Funktion hatte compat_kex_proposal()
, wird verwendet, um zu prüfen, welche Art von Schlüsselaustauschalgorithmus beim Aufbau einer Verbindung verwendet werden soll.
Aber die Behebung dieses bescheidenen Fehlers führte stattdessen zu einer schwerwiegenderen Schwachstelle.
Übrigens, das Vorhandensein des Fehlers in einem Teil der Software, der während des Verbindungsaufbaus verwendet wird, macht dies zu einem sogenannten Netzwerk-erreichbare Vorauthentifizierung Schwachstelle (bzw Fehler vor der Authentifizierung kurz).
Der Double-Free-Fehler tritt in Code auf, der ausgeführt werden muss nachdem ein Client hat eine Remote-Sitzung initiiert, aber Bevor Es hat keine Schlüsselvereinbarung oder Authentifizierung stattgefunden, sodass die Schwachstelle theoretisch ausgelöst werden kann, bevor Passwörter oder kryptografische Schlüssel zur Validierung vorgelegt wurden.
In OpenSSH 9.0, compat_kex_proposal
sah in etwa so aus (hier stark vereinfacht):
char* compat_kex_proposal(char* suggestion) { if (condition1) { return suggestion; } if (condition2) { suggestion = allocatenewstring1(); } if (condition3) { suggestion = allocatenewstring2(); } if (isblank(suggestion)) { error(); } return suggestion; }
Die Idee ist, dass der Anrufer seinen eigenen Speicherblock mit einer Textzeichenfolge übergibt, die eine Schlüsselaustauscheinstellung vorschlägt, und entweder eine Genehmigung zur Verwendung des von ihm gesendeten Vorschlags oder eine neu zugewiesene Textzeichenfolge mit einem aktualisierten Vorschlag zurückerhält .
Der Fehler ist, dass, wenn Bedingung 1 falsch ist, aber Bedingungen 2 und 3 beide wahr sind, der Code zuweist XNUMX neue Textzeichenfolgen, sondern gibt nur zurück dank One.
Der von zugeordnete Speicherblock allocatenewstring1()
wird nie freigegeben, und wenn die Funktion zurückkehrt, ist ihre Speicheradresse für immer verloren, also gibt es für keinen Code eine Möglichkeit free()
es in Zukunft.
Dieser Block wird im Wesentlichen aufgegeben, was zu dem führt, was als a bekannt ist Speicherleck.
Im Laufe der Zeit kann dies zu Problemen führen und möglicherweise sogar dazu führen, dass der Server heruntergefahren wird, um sich von einer Speicherüberlastung zu erholen.
In OpenSSH 9.1 wurde der Code aktualisiert, um zu vermeiden, dass zwei Zeichenfolgen zugewiesen, aber eine davon aufgegeben wird:
/* Always returns pointer to allocated memory, caller must free. */ char* compat_kex_proposal(char* suggestion){ char* previousone = NULL; if (condition1) { return newcopyof(suggestion); } if (condition2) { suggestion = allocatenewstring1(); } if (condition3) { previousone = suggestion; suggestion = allocatenewstring2(); } free(previousone); } if (isblank(suggestion()) { error(); } return suggestion; }
Dies hat den Double-Free-Bug, denn wenn Bedingung 1 und Bedingung 2 beide falsch sind, aber Bedingung 3 wahr ist, weist der Code eine neue Zeichenfolge zu, die als Antwort zurückgesendet wird …
… gibt aber fälschlicherweise die Zeichenfolge frei, die der Aufrufer ursprünglich übergeben hat, weil die Funktion allocatenewstring1()
wird nie aufgerufen, um die Variable zu aktualisieren suggestion
.
Die übergebene Vorschlagszeichenfolge ist Speicher, der dem Anrufer gehört, und dass der Anrufer sich daher später selbst freigibt, was zur Double-Free-Gefahr führt.
In OpenSSH 9.2 ist der Code vorsichtiger geworden und verfolgt alle drei möglichen Speicherblöcke, die verwendet werden: das Original suggestion
(Speicher, der jemand anderem gehört) und zwei mögliche neue Zeichenfolgen, die unterwegs zugewiesen werden könnten:
/* Always returns pointer to allocated memory, caller must free. */ char* compat_kex_proposal(char* suggestion) { char* newone = NULL; char* newtwo = NULL; if (condition1) { return newcopyof(suggestion); } if (condition2) { newone = allocatenewstring1(); } if (condition3) { newtwo = allocatenewstring2(); } free(newone); newone = newtwo; } if (isblank(newone)) { error(); } return newone; }
Wenn Bedingung 1 wahr ist, wird eine neue Kopie der übergebenen Zeichenfolge verwendet, damit der Aufrufer dies später tun kann free()
die Erinnerung ihrer übergebenen Zeichenfolge, wann immer sie möchten.
Wenn wir an Bedingung 1 vorbeikommen und Bedingung 2 wahr ist, aber Bedingung 3 falsch ist, dann wird der alternative Vorschlag erstellt von allocatenewstring1()
zurückgegeben wird, und das übergeben-in suggestion
Saite bleibt allein.
Wenn Bedingung 2 falsch und Bedingung 3 wahr ist, wird eine neue Zeichenfolge generiert und zurückgegeben und übergeben suggestion
Saite bleibt allein.
Wenn sowohl Bedingung 2 als auch Bedingung 3 wahr sind, werden unterwegs zwei neue Zeichenfolgen zugewiesen; der erste wird freigegeben, weil er nicht benötigt wird; der zweite wird zurückgegeben; und die Passierten suggestion
Saite bleibt allein.
Du kannst dich RTxM um das zu bestätigen, wenn Sie anrufen free(newone)
wann newone
is NULL
, dann wird „keine Operation durchgeführt“, da dies immer sicher ist free(NULL)
. Trotzdem schützen sich viele Programmierer mit Code wie z if (ptr != NULL) { free(ptr); }
.
Was ist zu tun?
Wie das OpenSSH-Team andeutet, wird es schwierig sein, diesen Fehler auszunutzen, nicht zuletzt wegen der eingeschränkten Privilegien, die der sshd
Programm während des Verbindungsaufbaus zur Nutzung hat.
Trotzdem haben sie es als Sicherheitslücke gemeldet, weil es das ist, also stellen Sie sicher, dass Sie darauf aktualisiert haben OpenSSH 9.2.
Und wenn Sie Code in C schreiben, denken Sie daran, dass Sie bei der Speicherverwaltung leicht Fehler machen können, egal wie erfahren Sie sind …
…also pass auf da draußen auf.
(Ja, Rust und seine modernen Freunde werden es tun helfen Ihnen, den richtigen Code zu schreiben, aber manchmal müssen Sie immer noch C verwenden, und selbst Rust kann dies nicht garantieren hindern Sie daran, falschen Code zu schreiben wenn Sie unüberlegt programmieren!)
- SEO-gestützte Content- und PR-Distribution. Holen Sie sich noch heute Verstärkung.
- Platoblockkette. Web3-Metaverse-Intelligenz. Wissen verstärkt. Hier zugreifen.
- Quelle: https://nakedsecurity.sophos.com/2023/02/03/openssh-fixes-double-free-memory-bug-thats-pokable-over-the-network/