Archiv der Kategorie: Betriebssysteme

C : List all network devices with their properties / attributes like GUID, adapter name, MAC address, Description

Problem

In some cases mighty libs like NPCap or WinPCap are used to get a list of all network devices with common properties like GUID and so on.

Approach

#pragma comment(lib, "iphlpapi.lib")
This links the IP Helper API library, which provides functions for retrieving network configuration and statistics, such as:

  • Network adapter information
  • IP address tables
  • Routing tables

#pragma comment(lib, "ws2_32.lib")
This links the Winsock 2 library, which is essential for network programming on Windows. It provides:

  • Socket APIs for TCP/UDP communication
  • DNS resolution
  • Network initialization and cleanup functions

Solution

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <iphlpapi.h>
#include <ws2tcpip.h>

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

int main() {
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    IP_ADAPTER_ADDRESSES *pAddresses = NULL;
    IP_ADAPTER_ADDRESSES *pCurrAddresses = NULL;

    ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
    ULONG family = AF_UNSPEC;

    // Erste Abfrage zur Bestimmung der Puffergröße
    dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &dwSize);
    if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
        pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(dwSize);
        if (pAddresses == NULL) {
            printf("Speicher konnte nicht reserviert werden.\n");
            return 1;
        }
    }

    // Zweiter Aufruf mit gültigem Puffer
    dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &dwSize);
    if (dwRetVal == NO_ERROR) {
        pCurrAddresses = pAddresses;
        while (pCurrAddresses) {
            printf("Adapter GUID: %s\n", pCurrAddresses->AdapterName);
            printf("Adaptername: %ws\n", pCurrAddresses->FriendlyName);
            printf("Beschreibung: %ws\n", pCurrAddresses->Description);
            if (pCurrAddresses->PhysicalAddressLength != 0) {
                printf("MAC-Adresse: ");
                for (DWORD i = 0; i < pCurrAddresses->PhysicalAddressLength; i++) {
                    printf("%02X", pCurrAddresses->PhysicalAddress[i]);
                    if (i < pCurrAddresses->PhysicalAddressLength - 1)
                        printf(":");
                }
                printf("\n");
            }
            
            printf("--------------------------------------------------\n");
            pCurrAddresses = pCurrAddresses->Next;
        }       
    } else {
        printf("GetAdaptersAddresses fehlgeschlagen mit Fehler: %lu\n", dwRetVal);
    }

    if (pAddresses) {
        free(pAddresses);
    }

    return 0;
}

Output

PS C:\Betriebssysteme\Übung 6> .\ListNetworkDevices  
Adapter GUID: {E01CE7A3-099B-4184-8C16-1F5054A8317F}
Adaptername: Ethernet
Beschreibung: Intel(R) Ethernet Connection (7) I219-LM
MAC-Adresse: 34:48:ED:61:86:BA
--------------------------------------------------
Adapter GUID: {4012AE18-3341-4541-892C-BC0286FA6504}
Adaptername: Ethernet 2
Beschreibung: Check Point Virtual Network Adapter For Endpoint VPN Client
MAC-Adresse: 54:DF:6F:F5:98:06
--------------------------------------------------
Adapter GUID: {6EFE57EA-027E-45AA-9BFD-8071CE36C5FD}
Adaptername: Ethernet 7
Beschreibung: VirtualBox Host-Only Ethernet Adapter
MAC-Adresse: 0A:00:27:00:00:0F
--------------------------------------------------
Adapter GUID: {1A8FA3D8-A753-4453-8362-78FA3A6B314C}
Adaptername: Local Area Connection* 1
Beschreibung: Microsoft Wi-Fi Direct Virtual Adapter
MAC-Adresse: B8:9A:2A:2F:51:8F
--------------------------------------------------
Adapter GUID: {4BE430BD-CB19-4CBB-BA70-0D4EE0F6AECE}
Adaptername: Local Area Connection* 2
Beschreibung: Microsoft Wi-Fi Direct Virtual Adapter #2
MAC-Adresse: BA:9A:2A:2F:51:8E
--------------------------------------------------
Adapter GUID: {DFDC464C-3487-4D61-B1AE-28733CA18E2E}
Adaptername: Wi-Fi
Beschreibung: Intel(R) Wi-Fi 6 AX200 160MHz
MAC-Adresse: B8:9A:2A:2F:51:8E
--------------------------------------------------
Adapter GUID: {BAA489E2-AF2D-4A75-A99C-2E4C19B04F44}
Adaptername: Bluetooth Network Connection
Beschreibung: Bluetooth Device (Personal Area Network)
MAC-Adresse: B8:9A:2A:2F:51:92
--------------------------------------------------
Adapter GUID: {88CB09EB-7A9D-11EF-986B-806E6F6E6963}
Adaptername: Loopback Pseudo-Interface 1
Beschreibung: Software Loopback Interface 1
--------------------------------------------------
PS C:\Betriebssysteme\Übung 6>

MBR (Master Boot Record) ansehen / anzeigen lassen | View MBR

MBR, Schutz-MBR und GPT

Zum Verständnis ein kurzer Exkurs von 4 Überschriften …

In aktuellen und älteren Betriebssystemen befindet sich in den ersten 512 Byte von Sektor 0 der Master Boot Record. Der MBR endet immer an den letzten 2 Bytes mit 0x55 0xAA.

In modernen Betriebssystemen existiert dieser nur noch, damit ältere Betriebssysteme die Platte als beschriebene Partition erkennen und dann wird dieser als Schutz-MBR bezeichnet.

GPT ist der Nachfolger vom MBR. Alte Betriebssysteme booten über das BIOS den MBR. Moderne Betriebssysteme booten über UEFI den GPT.

UEFI (Unified Extensible Firmware Interface) hat das traditionelle BIOS (Basic Input/Output System) weitgehend ersetzt

Struktur des MBR

  1. Bootloader-Code: Die ersten 446 Bytes enthalten den Bootloader-Code, der für das Starten des Betriebssystems verantwortlich ist.
  2. Partitionstabelle: Die nächsten 64 Bytes enthalten die Partitionstabelle, die Informationen über die Partitionen auf dem Speichermedium enthält.
  3. Signatur: Die letzten 2 Bytes (55 AA) sind die Boot-Signatur, die das Ende des MBR markiert und vom BIOS überprüft wird.

MBR (Master Boot Record)

  • Alter: MBR ist ein älteres Partitionsschema, das erstmals 1983 eingeführt wurde.
  • Größe: Der MBR belegt die ersten 512 Bytes eines Speichermediums.
  • Partitionen: Unterstützt bis zu vier primäre Partitionen oder drei primäre und eine erweiterte Partition.
  • Kapazität: Kann Festplatten bis zu 2 TB verwalten.
  • Boot-Prozess: Enthält den Bootloader-Code, der das Betriebssystem startet.

Schutz-MBR (Protective MBR)

  • Zweck: Wird auf GPT-formatierten Festplatten verwendet, um ältere Systeme daran zu hindern, die Festplatte als unpartitioniert zu erkennen.
  • Inhalt: Enthält eine einzige Partition, die den gesamten Speicherplatz des Mediums abdeckt.
  • Kompatibilität: Hilft bei der Kompatibilität mit älteren BIOS-Systemen.

GPT (GUID Partition Table)

  • Alter: GPT ist ein moderneres Partitionsschema, das mit UEFI eingeführt wurde.
  • Größe: GPT verwendet global eindeutige Bezeichner (GUIDs) für Partitionen.
  • Partitionen: Unterstützt eine nahezu unbegrenzte Anzahl von Partitionen.
  • Kapazität: Kann Festplatten größer als 2 TB verwalten.
  • Sicherheit: Bietet eine höhere Ausfallsicherheit durch redundante Kopien der Partitionstabelle.

Darstellung eines bootfähigen Speichermediums nach Andrew S. Tanenbaum

Linux

Unter Linux ist es mit dem Kommando dd möglich den MBR (Master Boot Record) eines Speichermediums anzeigen zu lassen, wenn man über Administratorrechte / Super-User-Rechte verfügt.

Dafür kann der Befehl genutzt werden:
sudo dd if=/dev/sda bs=512 count=1 | hexdump -C

sudo: Super-Userrechte für den Befehl dd
dd if=/dev/sda: Ausgabe der Datei, die im DEV-Ordner die erste Festplatte darstellt
count=1: Nur einen Input-Block einlesen
| hexdump -C: Ausgabe in Hexadezimal

karpbjde@BBRAUN:/$ sudo dd if=/dev/sda bs=512 count=1 | hexdump -C
00000000  eb 63 90 00 00 00 00 00  00 00 00 00 00 00 00 00  |.c..............|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000050  00 00 00 00 00 00 00 00  00 00 00 80 00 08 00 00  |................|
00000060  00 00 00 00 ff fa 90 90  f6 c2 80 74 05 f6 c2 70  |...........t...p|
00000070  74 02 b2 80 ea 79 7c 00  00 31 c0 8e d8 8e d0 bc  |t....y|..1......|
00000080  00 20 fb a0 64 7c 3c ff  74 02 88 c2 52 bb 17 04  |. ..d|<.t...R...|
00000090  f6 07 03 74 06 be 88 7d  e8 17 01 be 05 7c b4 41  |...t...}.....|.A|
000000a0  bb aa 55 cd 13 5a 52 72  3d 81 fb 55 aa 75 37 83  |..U..ZRr=..U.u7.|
000000b0  e1 01 74 32 31 c0 89 44  04 40 88 44 ff 89 44 02  |..t21..D.@.D..D.|
000000c0  c7 04 10 00 66 8b 1e 5c  7c 66 89 5c 08 66 8b 1e  |....f..\|f.\.f..|
000000d0  60 7c 66 89 5c 0c c7 44  06 00 70 b4 42 cd 13 72  |`|f.\..D..p.B..r|
000000e0  05 bb 00 70 eb 76 b4 08  cd 13 73 0d 5a 84 d2 0f  |...p.v....s.Z...|
000000f0  83 d0 00 be 93 7d e9 82  00 66 0f b6 c6 88 64 ff  |.....}...f....d.|
00000100  40 66 89 44 04 0f b6 d1  c1 e2 02 88 e8 88 f4 40  |@f.D...........@|
00000110  89 44 08 0f b6 c2 c0 e8  02 66 89 04 66 a1 60 7c  |.D.......f..f.`||
00000120  66 09 c0 75 4e 66 a1 5c  7c 66 31 d2 66 f7 34 88  |f..uNf.\|f1.f.4.|
00000130  d1 31 d2 66 f7 74 04 3b  44 08 7d 37 fe c1 88 c5  |.1.f.t.;D.}7....|
00000140  30 c0 c1 e8 02 08 c1 88  d0 5a 88 c6 bb 00 70 8e  |0........Z....p.|
00000150  c3 31 db b8 01 02 cd 13  72 1e 8c c3 60 1e b9 00  |.1......r...`...|
00000160  01 8e db 31 f6 bf 00 80  8e c6 fc f3 a5 1f 61 ff  |...1..........a.|
00000170  26 5a 7c be 8e 7d eb 03  be 9d 7d e8 34 00 be a2  |&Z|..}....}.4...|
00000180  7d e8 2e 00 cd 18 eb fe  47 52 55 42 20 00 47 65  |}.......GRUB .Ge|
00000190  6f 6d 00 48 61 72 64 20  44 69 73 6b 00 52 65 61  |om.Hard Disk.Rea|
000001a0  64 00 20 45 72 72 6f 72  0d 0a 00 bb 01 00 b4 0e  |d. Error........|
000001b0  cd 10 ac 3c 00 75 f4 c3  00 00 00 00 00 00 00 00  |...<.u..........|
000001c0  02 00 ee ff ff ff 01 00  00 00 ff ff 1f 03 00 00  |................|
000001d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|

Windows

Unter Windows kann man den kostenlosen HEX-Editor HxD benutzen um sich den MBR anzeigen zu lassen. Bei folgendem System handelt es sich nur noch um einen Schutz-MBR.

Ein Schutz-MBR (Protective MBR) wird verwendet, um sicherzustellen, dass ältere Programme und Betriebssysteme, die nur das traditionelle MBR-Partitionsschema kennen, ein Speichermedium nicht fälschlicherweise als leer oder uninitialisiert erkennen. Dies ist besonders wichtig bei der Verwendung der GUID-Partitionstabelle (GPT), die bei modernen Systemen und großen Festplatten üblich ist 

Der Schutz-MBR enthält eine einzige Partition, die den gesamten Speicherplatz des Mediums abdeckt und so verhindert, dass ältere Systeme versuchen, das Medium neu zu partitionieren oder zu formatieren.

Nach der Installation von HxD kann man über Extras -> Datenträgerabbild öffnen die ersten 512 Bytes des primären Mediums anzeigen lassen.

Wifi-Passwort von WLAN’s herausfinden, mit denen man bereits verbunden war | Get wifi passwords of wireless networks to which already a wifi connection has been established

Problem

Man hat das Kennwort / Passwort von WLAN’s vergessen und möchte diese auf einem anderen Gerät einrichten.

Ansatz

Verwendung von netsh über die Eingabeaufforderung / CMD / Kommandozeile

Lösung

  • Öffne eine MS-DOS-Eingabeaufforderung / eine Konsole / ein Terminal (z.B. nach cmd suchen)
  • Gebe den folgenden Befehl ein um WLAN’s aufzulisten, mit denen man bereits verbunden war:
C:\Users\karpbjde>netsh wlan show profile

Profile auf Schnittstelle Wi-Fi:

Gruppenrichtlinienprofile (schreibgeschützt)
---------------------------------
BBraun (GPO)

Benutzerprofile
---------------
Profil für alle Benutzer : Karpenstein2
Profil für alle Benutzer : karpenstein
Profil für alle Benutzer : eduroam
  • Um das Wifi-Password für eines der aufgelisteten Profile zu sehen, geben folgendes ein:
C:\Users\karpbjde>netsh wlan show profile "Karpenstein2" key=clear

Das Profil "Karpenstein2" auf Schnittstelle Wi-Fi:
=======================================================================

Angewendet: Profil für alle Benutzer

Profilinformationen
-------------------
Version : 1
Typ : Drahtlos-LAN
Name : Karpenstein2
Steuerungsoptionen :
Verbindungsmodus : Automatisch verbinden
Netzwerkübertragung : Verbinden, nur wenn dieses Netzwerk überträgt
Automatisch wechseln : Nicht zu anderen Netzwerken wechseln.
MAC-Randomisierung : Deaktiviert

Konnektivitätseinstellungen
---------------------
Anzahl von SSIDs : 1
SSID-Name : "Karpenstein2"
Netzwerktyp : Infrastruktur
Funktyp : [ Beliebiger Funktyp ]
Herstellererweiterung : Nicht vorhanden

Sicherheitseinstellungen
------------------------
Authentifizierung : WPA2-Personal
Verschlüsselung : CCMP
Authentifizierung : WPA2-Personal
Verschlüsselung : GCMP
Sicherheitsschlüssel : Vorhanden
Schlüsselinhalt : SAG_ICH_NED

Kosteneinstellungen
-------------------
Kosten : Uneingeschränkt
Überlastet : Nein
Datenlimit bald erreicht: Nein
Über Datenlimit : Nein
Roaming : Nein
Kostenquelle : Standard


C:\Users\karpbjde>
  • Das Kennwort steht unter „Sicherheitseinstellungen -> Sicherheitsschlüssel“ (hier „SAG_ICH_NED“)

Wie funktionieren Buffer Overflows und/oder Heap Overflows?

Intention

Vor einer aktuell kritischen Sicherheitslücke von älteren Microsoft Server Versionen, Windows 11 und Windows 10 wird in einem aktuellen Artikel auf heise.de gewarnt.

Diese offen gelegten Schwachstellen / Sicherheitslücken werden in einer öffentlichen Online-Datenbank aufgelistet:

Konkret handelt es sich dabei um die Ausnutzung von Heap-Overflows für das Einschleusen von Schadcode / schädlichem Code. In diesem Artikel möchte ich darauf eingehen, wie solche Heap-Overflows funktionieren, indem ich die Fragen beantworte, die sich mir vorher gestellt hatten.

Was ist der „Heap“, der überlaufen kann?

Zunächst ist eine Abgrenzung darüber nötig, was ein Heap eigentlich ist. In der Informatik gibt es zwei verschiedene Konzepte, die beide als „Heap“ bezeichnet werden:

  1. Heap im Speicher-Management: Dies bezieht sich auf den Bereich des Speichers, der für dynamische Speicherzuweisungen verwendet wird. Wenn Sie malloc() oder ähnliche Funktionen verwenden, wird der Speicher aus diesem Heap zugewiesen. Ein Heap Overflow tritt auf, wenn mehr Daten in einen Speicherbereich geschrieben werden, als dafür vorgesehen ist, was zu einer Beschädigung des Speichers führen kann.
  2. Heap als Datenstruktur: Wir haben in „Algorithmen und Datenstrukturen“ ebenfalls über Heaps gesprochen. Dies ist eine spezielle Baumstruktur, die bestimmte Eigenschaften erfüllt. Zum Beispiel ist ein Max-Heap ein binärer Baum, bei dem jeder Elternknoten größer oder gleich seinen Kindknoten ist. Diese Art von Heap wird häufig in Algorithmen wie Heapsort oder für Prioritätswarteschlangen verwendet.

Im Nachfolgenden beziehen wir uns auf Definition 1, da der Heap im dynamisch anforderbaren Speicherbereich liegt. Der Prozess kann also von diesem Bereich neuen Speicher für sich anfordern. Der Heap des Prozessspeichers beschränkt sich bei modernen Betriebssystemen auf den ausgeführten Prozess, was bedeutet dass ein Prozess nicht auf den Prozessspeichers eines anderen Prozesses zugreifen kann. Bei früheren Betriebssystemen wie beispielsweise MS DOS war dies noch nicht der Fall, da man hier z.B. direkt in den Bildwiederholspeicher Pixel in einer Farbe durch Speichermanipulation setzen konnte.

Ist die in Definition 1 genannte Beschädigung physisch?

Nein, die Beschädigung bei einem Heap Overflow ist nicht physisch. Sie betrifft den Speicherbereich des Computers und führt zu einer logischen Beschädigung der Daten. Das bedeutet, dass die Daten im Speicher durcheinandergebracht oder überschrieben werden, was zu Programmabstürzen, unerwartetem Verhalten oder Sicherheitslücken führen kann. Physische Hardware wird dabei nicht beschädigt.

Gibt es ein Beispiel, wie ein Heap Overflow zu einer Sicherheitslücke führen kann?

Stellen wir uns vor, ein Programm verwendet die Funktion malloc(), um Speicher für Benutzereingaben zu reservieren, überprüft jedoch nicht, ob die Eingabe die Größe des zugewiesenen Speichers überschreitet. Ein Angreifer könnte dann eine übermäßig große Eingabe senden, die mehr Speicherplatz benötigt, als zugewiesen wurde. Dies führt dazu, dass benachbarte Speicherbereiche überschrieben werden.

Ein konkretes Beispiel ist der Heap Overflow Angriff auf den Microsoft Internet Explorer im Jahr 2014. Angreifer nutzten eine Schwachstelle aus, bei der sie durch gezielte Manipulation des Heaps die Kontrolle über den Programmfluss erlangen konnten. Sie überschrieben kritische Datenstrukturen im Speicher und führten so schädlichen Code aus

Solche Angriffe können schwerwiegende Folgen haben, einschließlich Datenverlust, unbefugtem Zugriff auf Systeme und der Ausführung von Schadsoftware.

Wie liegen diese Kontrollstrukturen im Speicher vor?

Kontrollstrukturen wie Schleifen, Bedingungen und Funktionsaufrufe werden im Speicher durch den Programmcode und die zugehörigen Datenstrukturen repräsentiert. Hier ist eine kurze Übersicht, wie sie im Speicher organisiert sind:

  1. Programmcode: Der eigentliche Code der Kontrollstrukturen wird im Textsegment des Speichers abgelegt. Dies umfasst die Anweisungen, die der Prozessor ausführt.
  2. Stack: Der Stack-Speicher wird verwendet, um lokale Variablen, Funktionsaufrufe und Rücksprungadressen zu speichern. Wenn eine Funktion aufgerufen wird, werden die Parameter und die Rücksprungadresse auf den Stack gelegt. Bei Schleifen und Bedingungen werden die aktuellen Zustände und Variablen ebenfalls auf dem Stack verwaltet.
  3. Heap: Dynamisch zugewiesene Speicherbereiche, die durch Funktionen wie malloc() angefordert werden, befinden sich im Heap. Kontrollstrukturen selbst nutzen den Heap nicht direkt, aber die Daten, die sie verarbeiten, können dort gespeichert sein.

Ein Beispiel für eine Sicherheitslücke durch einen Heap Overflow ist, wenn ein Angreifer den Heap so manipuliert, dass er die Kontrollstrukturen im Speicher überschreibt. Dadurch kann der Angreifer den Programmfluss ändern und schädlichen Code ausführen

Gibt es ein Beispiel, was eine Kontrollstruktur im Heap abspeichern könnte, was dazu führt dass sie manipuliert wird?

Ja, ein Beispiel für eine Kontrollstruktur, die im Heap gespeichert wird und manipuliert werden kann, sind Zeiger auf Funktionszeiger innerhalb von Datenstrukturen. Hier ist ein konkretes Szenario:

Stellen wir uns vor, ein Programm verwendet eine Datenstruktur, die einen Funktionszeiger enthält. Dieser Funktionszeiger zeigt auf eine Routine, die aufgerufen wird, wenn bestimmte Bedingungen erfüllt sind. Wenn ein Heap Overflow auftritt, kann ein Angreifer den Funktionszeiger überschreiben und ihn auf eine schädliche Routine umleiten.

Ein Beispiel für einen solchen Angriff ist der Heap Overflow Angriff auf den iOS-Kernel. In diesem Fall wurde der Heap so manipuliert, dass ein überlaufener Speicherbereich mit einem kritischen Datenobjekt kollidierte. Der Angreifer konnte dadurch den Funktionszeiger innerhalb des Datenobjekts überschreiben und die Kontrolle über den Programmfluss übernehmen.

In dem beschriebenen Szenario hat der Angreifer den Funktionszeiger im Heap-Speicherbereich überschrieben. Der Heap wird für dynamische Speicherzuweisungen verwendet, und in diesem Fall wurde ein Funktionszeiger innerhalb einer Datenstruktur im Heap manipuliert. Durch den Heap Overflow konnte der Angreifer den Funktionszeiger so ändern, dass er auf schädlichen Code zeigt, anstatt auf die ursprünglich vorgesehene Funktion.

Wo lag der schädliche Code, auf den der Funktionszeiger umgeschrieben wurde?

Der schädliche Code, auf den der Funktionszeiger umgeschrieben wurde, kann sich an verschiedenen Stellen im Speicher befinden. Häufig wird er jedoch im Heap oder im Textsegment des Speichers platziert.

Hier sind die beiden häufigsten Szenarien:

  1. Heap: Der Angreifer kann den schädlichen Code direkt im Heap platzieren, indem er eine übermäßige Eingabe sendet, die den Heap überläuft und den Funktionszeiger überschreibt. Der Funktionszeiger wird dann auf den schädlichen Code im Heap umgeleitet.
  2. Textsegment: In einigen Fällen kann der Angreifer den Funktionszeiger so manipulieren, dass er auf bereits vorhandenen schädlichen Code im Textsegment zeigt. Dies kann durch das Einfügen von Shellcode in den Speicher erreicht werden, der dann durch den manipulierten Funktionszeiger ausgeführt wird

Kann man sich auf seinem Rechner den Heap anzeigen lassen?

Es ist möglich, den Heap-Speicherinhalt auf seinem Rechner anzuzeigen, allerdings erfordert dies spezielle Tools und Kenntnisse. Hier sind einige Methoden, wie der Heap-Speicher untersucht werden kann:

  1. Debugger: Mit Debuggern wie GDB (GNU Debugger) oder WinDbg (Windows Debugger) kann man den Speicher eines laufenden Programms untersuchen. Diese Tools ermöglichen es dir, den Heap-Speicher zu durchsuchen und zu analysieren.
  2. Heap-Profiler: Tools wie Valgrind (insbesondere das Modul Massif) oder Visual Studio Profiler können verwendet werden, um den Heap-Speicher zu profilieren und Speicherlecks sowie Speicherüberläufe zu identifizieren.
  3. Speicher-Dump-Analyse: Mit einem Speicher-Dump (Abbild des Speichers) eines laufenden Programms erstellen und diesen mit Tools wie WinDbg oder GDB analysieren. Dies ermöglicht, den Zustand des Heaps zu einem bestimmten Zeitpunkt zu untersuchen.

Hier ist ein einfaches Beispiel, wie man mit GDB den Heap-Speicher eines Programms untersuchen kannst:

gdb ./das_programm
(gdb) run
(gdb) info proc mappings
(gdb) x/20xw 0xheap_start_address

In diesem Beispiel ersetzt man./das_programm durch den Namen des Programms und 0xheap_start_address durch die Startadresse des Heaps, die aus den Speicherzuordnungen kommt.

Wie findet man eine Benutzereingabe, die zu einem Heap Overflow führt?

Das Finden einer Benutzereingabe, die zu einem Heap Overflow führt, ist eine komplexe Aufgabe und erfordert ein tiefes Verständnis des Zielprogramms sowie der Art und Weise, wie es Speicher verwaltet. Hier sind einige Schritte, die oft verwendet werden:

  1. Quellcode-Analyse: Durchsuche den Quellcode des Programms nach Stellen, an denen dynamischer Speicher zugewiesen wird (z.B. durch malloc()calloc()realloc()). Achte besonders auf Funktionen, die Benutzereingaben verarbeiten.
  2. Fuzzing: Verwende Fuzzing-Tools, um das Programm mit zufälligen oder speziell gestalteten Eingaben zu testen. Fuzzing kann helfen, Schwachstellen zu finden, indem es das Programm mit einer Vielzahl von Eingaben bombardiert und nach Abstürzen oder ungewöhnlichem Verhalten sucht. Beispiele für Fuzzing-Tools sind AFL (American Fuzzy Lop) und LibFuzzer.
  3. Manuelle Tests: Erstelle manuell Eingaben, die die Grenzen der Puffer überschreiten könnten. Dies kann durch das Senden von sehr langen Zeichenketten oder durch das Einfügen spezieller Zeichenfolgen geschehen, die das Programm möglicherweise nicht korrekt verarbeitet.
  4. Debugging: Verwende Debugger wie GDB oder WinDbg, um das Programm während der Ausführung zu überwachen. Setze Breakpoints an kritischen Stellen und beobachte, wie das Programm auf verschiedene Eingaben reagiert. Achte auf Speicherüberläufe und überprüfe, ob der Heap beschädigt wird.
  5. Speicheranalyse-Tools: Nutze Tools wie Valgrind oder AddressSanitizer, um Speicherprobleme zu erkennen. Diese Tools können helfen, Speicherlecks, Überläufe und andere Speicherprobleme zu identifizieren.

Hier ist ein einfaches Beispiel für Fuzzing mit AFL:

# Installiere AFL
sudo apt-get install afl

# Instrumentiere das Zielprogramm
afl-gcc -o zielprogramm zielprogramm.c

# Führe AFL aus
afl-fuzz -i input_dir -o output_dir ./zielprogramm

Gibt es ein Beispielcode in C oder C++, wie man einen Heap Overflow verursachen kann?

Dieser Code sollte nur zu Lernzwecken dienen und nicht in einer produktiven Umgebung verwendet werden, da er Sicherheitsrisiken birgt.

Hier ist ein Beispielcode:

#include &lt;stdio.h>
#include &lt;stdlib.h>
#include &lt;string.h>

void vulnerable_function(const char *input) {
    // Allokiere einen Puffer von 10 Bytes auf dem Heap
    char *buffer = (char *)malloc(10 * sizeof(char));
    if (buffer == NULL) {
        fprintf(stderr, "Speicherzuweisung fehlgeschlagen\n");
        exit(1);
    }

    // Kopiere die Eingabe in den Puffer ohne Größenüberprüfung
    strcpy(buffer, input);

    // Ausgabe des Puffers
    printf("Pufferinhalt: %s\n", buffer);

    // Freigabe des Puffers
    free(buffer);
}

int main(int argc, char *argv[]) {
    if (argc &lt; 2) {
        fprintf(stderr, "Verwendung: %s &lt;Eingabe>\n", argv[0]);
        return 1;
    }

    // Aufruf der anfälligen Funktion mit Benutzereingabe
    vulnerable_function(argv[1]);

    return 0;
}

In diesem Beispiel wird ein Puffer von 10 Bytes auf dem Heap allokiert. Die Funktion strcpy kopiert die Benutzereingabe in diesen Puffer, ohne die Größe der Eingabe zu überprüfen. Wenn die Eingabe länger als 10 Bytes ist, wird der Puffer überlaufen, was zu einem Heap Overflow führt.

Mann kann dieses Programm kompilieren und ausführen, um das Verhalten zu beobachten:

gcc -o heap_overflow_example heap_overflow_example.c
./heap_overflow_example "Dies ist eine sehr lange Eingabe, die den Puffer überläuft"

Dies wird zu einem Heap Overflow führen und möglicherweise das Programm zum Absturz bringen oder unerwartetes Verhalten verursachen.

Kann dieses Programm auch Speicherbereiche anderer Programme überschreiben und diese manipulieren?

Nein, dieses Programm kann nicht direkt Speicherbereiche anderer Programme überschreiben und manipulieren. In modernen Betriebssystemen gibt es Schutzmechanismen, die verhindern, dass ein Programm auf den Speicherbereich eines anderen Programms zugreift. Diese Schutzmechanismen umfassen:

  1. Speicherschutz: Betriebssysteme wie Windows, Linux und macOS verwenden Speicherschutzmechanismen, um sicherzustellen, dass jedes Programm nur auf seinen eigenen Speicherbereich zugreifen kann. Versuche, auf den Speicherbereich eines anderen Programms zuzugreifen, führen zu einer Speicherzugriffsverletzung (Segmentation Fault) und dem Absturz des Programms.
  2. Adressraum-Layout-Randomisierung (ASLR): ASLR ist eine Sicherheitsfunktion, die die Speicheradressen von Programmcode, Daten und Bibliotheken zufällig anordnet. Dies erschwert es Angreifern, vorherzusagen, wo sich bestimmte Speicherbereiche befinden, und macht Exploits schwieriger.
  3. Benutzer- und Kernel-Modus: Betriebssysteme trennen den Speicher in Benutzer- und Kernel-Modus. Programme laufen im Benutzermodus und haben keinen direkten Zugriff auf den Kernel-Speicherbereich, was die Sicherheit weiter erhöht.

Ein Heap Overflow innerhalb eines Programms kann jedoch dazu führen, dass das Programm selbst abstürzt oder unerwartetes Verhalten zeigt. In einem Szenario, in dem ein Angreifer den Heap Overflow ausnutzt, könnte der Angreifer schädlichen Code innerhalb des betroffenen Programms ausführen, aber nicht direkt andere Programme beeinflussen.