Sicherheit OpenBSD > FreeBSD ?

»Unsere Anstrengungen liegen vor allem in der [...] vorausschauenden Sicherheit [...].«

Für alle, die mit dem von double-p geposteten Vortrag »Exploit Mitigation Techniques« nichts anfangen oder dieser ihnen zu theoretisch ist, einfach mal ein paar Beispielcodes.

Erstmal zu meinem System:
Code:
$ uname -msr
OpenBSD 3.9 i386

Guardpages

Code:
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(void)
{
        char *pointer;

        if ((pointer = malloc(10)) == NULL)
                err(1, NULL);

        memset(pointer, 0, 65536);

        exit(0);
}

Eine Guardpage wird am Ende einer Page angelegt. Damit ich auch wirklich am Ende meiner zugewiesenen Page ankomme, schreibe ich 64 KBit Nullen:

Code:
$ gcc -o guard guard.c
$ ./guard
Segmentation fault (core dumped)

randomisiertes malloc()

Code:
#include <err.h>
#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
        int i;
        char *pointer[20];

        for (i = 0; i < 20; i++) {
                if ((pointer[i] = malloc(500)) == NULL)
                        err(1, NULL);
                printf("%2d. Pointer zeigt auf %x\n", i + 1, pointer[i]);
        }

        for (i = 0; i < 20; i++) {
                free(pointer[i]);
        }

        exit(0);
}

Ich reserviere einfach 20 Charpointer mit 500 Zeichen ... vollkommen beliebig:

Code:
$ gcc -o malloc malloc.c
$ ./malloc
 1. Pointer zeigt auf 8a1d9000
 2. Pointer zeigt auf 8a1d9200
 3. Pointer zeigt auf 8a1d9400
 4. Pointer zeigt auf 8a1d9600
 5. Pointer zeigt auf 8a1d9800
 6. Pointer zeigt auf 8a1d9a00
 7. Pointer zeigt auf 8a1d9c00
 8. Pointer zeigt auf 8a1d9e00
 9. Pointer zeigt auf 84fb5000
10. Pointer zeigt auf 84fb5200
11. Pointer zeigt auf 84fb5400
12. Pointer zeigt auf 84fb5600
13. Pointer zeigt auf 84fb5800
14. Pointer zeigt auf 84fb5a00
15. Pointer zeigt auf 84fb5c00
16. Pointer zeigt auf 84fb5e00
17. Pointer zeigt auf 87876000
18. Pointer zeigt auf 87876200
19. Pointer zeigt auf 87876400
20. Pointer zeigt auf 87876600
$ ./malloc
 1. Pointer zeigt auf 7f714000
 2. Pointer zeigt auf 7f714200
 3. Pointer zeigt auf 7f714400
 4. Pointer zeigt auf 7f714600
 5. Pointer zeigt auf 7f714800
 6. Pointer zeigt auf 7f714a00
 7. Pointer zeigt auf 7f714c00
 8. Pointer zeigt auf 7f714e00
 9. Pointer zeigt auf 851c0000
10. Pointer zeigt auf 851c0200
11. Pointer zeigt auf 851c0400
12. Pointer zeigt auf 851c0600
13. Pointer zeigt auf 851c0800
14. Pointer zeigt auf 851c0a00
15. Pointer zeigt auf 851c0c00
16. Pointer zeigt auf 851c0e00
17. Pointer zeigt auf 7c716000
18. Pointer zeigt auf 7c716200
19. Pointer zeigt auf 7c716400
20. Pointer zeigt auf 7c716600

Wie man sieht kann man nichts darüber aussagen, wo die Daten landen bzw. in welcher Reihenfolge dies geschieht (mal vor dem vorherigen Speicherplatz, dann wieder dahinter, etc.)

ProPolice

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void
input(void)
{
        char eingabe[10];
        memset(eingabe, 0, 20);
        return;
}

int
main(void)
{
        input();
        exit(0);
}

Ganz klar wird mir in meiner Funktion input der Stack überschrieben. Propolice wird das merken, da am Ende des Stacks Zufallswerte stehen, die am Ende der Funktion auf ihre Richtigkeit hin überprüft werden:

Code:
$ gcc -o stack stack.c
$ ./stack
Abort trap (core dumped)

Und jetzt nochmal ohne Propolice:

Code:
$ gcc -fno-stack-protector -o stack stack.c
$ ./stack
$ _

systrace

(Seltsam, dass das noch gar nicht genannt wurde ...)

Code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void
evil(void)
{
        char *nargv[2];
        nargv[0] = "/bin/sh";
        nargv[1] = NULL;
        execvp("/bin/sh", nargv);
}

void
good(void)
{
        char *nargv[2];
        nargv[0] = "/bin/ls";
        nargv[1] = NULL;
        execvp("/bin/ls", nargv);
}

int
main(int argc, char **argv)
{
        if (argc == 1)
                good();
        else
                evil();
        exit(1);
}

Jaaa, einfach mal Kreativität freien Lauf lassen und vorstellen, dass evil() irgendein Bytecode ist, den man mit einer vorherigen Schwachstelle (über Kommandozeile ;) eingeschleust hat - oder was auch immer).

Mit systrace -A lege ich erstmal eine Policy an, so, wie das Programm laufen soll:

Code:
$ gcc -o trace trace.c
$ systrace -A ./trace
guard      guard.core malloc.c   stack.c    trace
guard.c    malloc     stack      stack.core trace.c

Ich geh hier jetzt nicht auf die Konfiguration von systrace ein, dafür gibt es Manualseiten. Es sei aber soviel gesagt, dass für trace nur noch das erlaubt ist, was bisher ausgeführt wurde. Mal sehen, was passiert, wenn ich jetzt die Shell über evil() starten will (mit -a erzwinge ich die neu erstellte Richtlinie):

Code:
$ systrace -a ./trace bytecode
Segmentation fault (core dumped)



Wenn ich Mist geschrieben habe oder es Verbesserungsvorschläge gibt, nur her damit! Schließlich will ich auch was dazulernen. :belehren:
 
[ot]boah, solche Beitraege wuerde ich gerne oefter sehen. der war richtig interessant.
Danke, paldium[/ot]
 
Hi Paldium, Forum,
zum langen Texte lesen fehlt mir in der Nacht der Nerv *g* Und hab mich mit dieser Materie nicht wirklich gross beschäftig bisher (auch weil ich nicht wirklich in C programmiere...). Aber vorhandene kurze Codeschnipsel zu testen reizt natürlich immer ;-)

Paldium schrieb:
Also bei diesem Quellcode erhalte ich bei FreeBSD das selbe Ergebnis:
Code:
$ uname -msr
FreeBSD 5.4-SECURITY i386
$ ./guard
Speicherschutzverletzung (core dumped)
Aber vielleicht liegt das "zufällig" selbe Ergebnis jetzt auch am Quellcode. Was hätte den ohne diese "Guardpages" passieren sollen, oder gibts das auch bei FreeBSD?

Paldium schrieb:
randomisiertes malloc()
Hier bekommt man bei FreeBSD tatsächlich immer die selbe Reihenfolge.

Paldium schrieb:
Das liegt ja in erster Linie IMHO am gepatchten GCC von OpenBSD? Da SSP ja im GCC4.1 offiziell mit drin ist, denk ich mal es kommt auch für FreBSD. Wer es jetzt schon haben will, kann mal hier lesen:
http://www.trl.ibm.com/projects/security/ssp/buildfreebsd.html

Paldium schrieb:
Mangels Systraceunterstützung in meinem FreeBSD kann ich da jetzt nichts dazu sagen. Und die Ports geht wohl auch nicht richtig voran?
http://techie.devnull.cz/systrace/
http://www.citi.umich.edu/u/provos/systrace/freebsd.html
 
double-p schrieb:
Das ganze blabla ueber "nur so gut wie der Admin"-Sicherheit halte ich in so einer
Diskussion fuer nichtig - es geht da schonmal um system-inherente Schwaechen
oder Staerken, die nichtmal "administriert" werden muessen. Schliesslich geht's
ja nicht um Admin1 ist "sicherer" als Admin2.

Das halte ich nicht für nichtig.
Fakt ist, das OpenBSD Features besitzt, die die Ausnutzung von Schwächen erschweren, und in einigen Fällen auch unmöglich machen. Aber wenn man die Entwicklung von OpenBSD betrachtet, so sind die Features nach und nach entstanden. Und da kommt schon der Admin ins Spiel, der muss nämlich am Ball bleiben, auch (!) bei OpenBSD. Sonst kannst du dir dein ach so sicheres OpenBSD sonst wo hinstecken, um es mal so drastisch zu formulieren. ;)

Gruß c.
 
Guten Morgen Forum,

ein hoch interesanter Thread, möchte mich jetzt nicht posistionieren für irgendein Os sonder möchte darauf verweisen das Sicherheit einfach Os übergreifend und sehr vielschichtig ist, zBsp WLan-Hardware-Systemspezifisch etc....

Eine sehr gute Seite/Archiv über Sicherheit und auch Os spezifische Sicherheitsaspekte findet Ihr hier:

http://84.113.211.190/codejungle/

auch Verweisse zu aktuellen Techniken bezüglich BSD - Linux etc....

http://newsvac.newsforge.com/newsvac/06/08/08/1923227.shtml

Anmerkung und Ergänzung:

Codejungle ist ein Archiv in dem aktuelle Nachrichten gespeichert werden.
Das müssen aber nicht nur zwangsläufig Nachrichten aus der EDV sein, trotzdem hoch interesant und viel Spass beim Stöbern und Lernen.

gruss Rudolf
 
Wiedmann schrieb:
Was hätte den ohne diese "Guardpages" passieren sollen, oder gibts das auch bei FreeBSD?

Hm, ich schätze den Sinn der Guardpages hab ich doch nicht richtig verstanden. Streich sowohl den Code (die Pagesize ist übringes 4 KB und nicht 64 KB wie angegeben) als auch das Argument ... erstmal. ;)

Auch wenn es gerade völlig offtopic ist, weil ich jetzt GNU/Linux mit OpenBSD vergleiche: unter Linux lief das Programm normal durch - ohne Fehler.

Wiedmann schrieb:
Das liegt ja in erster Linie IMHO am gepatchten GCC von OpenBSD?

Ja, der Effekt tritt wegen dem SSP auf. Ich hoffe auch, dass FreeBSD bald standardmäßig mit SSP ausgerüstet ist. Weiß da jemand was drüber?

Aber nichtsdestrotz, SSP ist zu diesem Zeitpunkt eine Stärke von OpenBSD gegenüber FreeBSD. Man will ja mal kleinlich sein.

Noch ein schönes Beispiel für die Wirksamkeit von SSP (habs gestern nicht mehr mit angegeben, weil mir meine Antwort eh schon recht lang vorkam):

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(void)
{
        char *pointer, array[10];

        if ((pointer = malloc(100)) == NULL)
                err(1, NULL);

        memset(array, 0, 40);

        printf("pointer: %x\n", pointer);
        return 0;
}

Code:
$ gcc -o stack2 stack2.c
$ ./stack2
pointer: 7d393000
Abort trap (core dumped)

gegenüber

Code:
$ gcc -fno-stack-protector -o stack2 stack2.c
$ ./stack2
pointer: 0

Der Grund hierfür ist, dass SSP die Variablen im Stack umsortiert, damit ein Überlauf des Arrays nicht den Pointer erreichen kann. Ist auch ganz nett. :)

Wiedmann schrieb:
Mangels Systraceunterstützung in meinem FreeBSD kann ich da jetzt nichts dazu sagen. Und die Ports geht wohl auch nicht richtig voran?

Da hoffe ich auch drauf, dass FreeBSD das übernimmt. Systrace ist unglaublich nützlich und einfach zu konfigurieren, wenn man keine Scheu vor regulären Ausdrücken hat.
 
KEIN system ist sicher.
ob es nun tausend loecher hat oder eines ist am ende voellig irrelevant, wenn erstmal die platte geputzt wurde.

ich persoenlich habe mich fuer openbsd aufgrund der farbe der kernelmeldungen entschieden. die starke betonung auf sicherheit und kryptographie hatte mich dann allerdings doch ein wenig mitgerissen und mich bei meiner arbeit inspiriert.
 
hab die programme mal unter linux getestet

leider läuft das erste nicht, aber das liegt nicht an deinem code


wenn ich das letzte beispiel ganz normal compile
Code:
$ gcc -o stack2 stack2.c
$ ./stack2
pointer: 0
benutz ich aber aber mein kleines compile script mit den einstellungen aus meiner make.conf von gentoo
Code:
$ mycompile stack2.c 
C File
gcc -O3 -march=pentium3 -pipe -fomit-frame-pointer -fforce-addr -falign-functions=4 -fprefetch-loop-arrays -o stack2 stack2.c
$ ./stack2
pointer: 804a050
Speicherzugriffsfehler


so was ich noch sagen kann warum openbsd "sicherer" ist, ist das es in 10 jahren nur 2 kritische sicherheitsfehler hatte, weiss jetzt nicht wie es bei bei freebsd aussieht aber vermute mal das es mehr waren.

Quelle ist leider unbekannt

so und noch was
Durch "Secure by Default" und CodeAudits setzt OpenBSD auf eine sichere Grundlage. In der Standard-Installation sind alle unwichtigen Dienste deaktiviert

Quelle: http://www.operating-system.org/betriebssystem/_german/bs-openbsd.htm
 
Immerhin hast Du von Veresterung schon mal gehört!

@*Sheep:
Allerdings wird dieses Thema bis zum Hauptschulabschluss behandelt.

Die Konsistenz Deiner Aussagen ist lächerlich. Zuerst schreibst Du:

Wenn Du die Schlagworte wie tib sie genannt hatte:
* authentification/authorization
* integrity
* confidentiality
* availibility
Und auf einmal wird daraus

Du schreibst über Sicherheit in der Informationstechnik, wie ich über Veresterung.
Was denn nun?

mein Engagement für das Forum hier überdenken.
Wir werden alle Deine essentiellen Threads wie "Völler geht" und "Danke Anke" in diesem BSD-Forum vermissen!
 
tib schrieb:
Wir werden alle Deine essentiellen Threads wie "Völler geht" und "Danke Anke" in diesem BSD-Forum vermissen!
Du sagst "wir", also lieber tib ich wuerde dich gerne auf diesen Beitrag hinweisen und fuer die Zukunft einen Rat geben, bitte sprich nur von dir und gib deine eigene Meinung nicht fuer die Meinung anderer aus.
 
Dr. tib: keines Wegs inkonsistent.
Ich könnte auch ein paar Schlagworte über Veresterung auflisten. Und wie Du bereits bemerkt hast, Hauptschulniveau. Das Du ein paar Schlagworte gelistet hast, macht Dich nicht zu einem Sicherheitsguru in der Informationstechnik. Da diese korrekt sind, kann ich trotzdem darauf verweisen.
Ich beziehe mich auf Dinge von Dir wie:
Dr. tib schrieb:
wer von den Forenteilnehmern, die mit IT hauptberuflich Geld verdienen, verwendet denn überhaupt noch Apache 1.3?

Das zeigt mir sehr deutlich, daß Du KEINE Ahnung hast! Schuster bleib bei Deinen Leisten!

Wenn Du als Akademiker andere Akademiker als:
Dr. tib schrieb:
NUR Hilfswissenschaftler!
bezeichnest, kommt man zwangsläufig auch als Mittelschüler ins Grübeln...

Ich entschuldige mich, daß meine Antworten nicht Deinem überragenden Intellekt entsprechen.
 
*Sheep schrieb:
Sicherheitsguru in der Informationstechnik.
Woher leitest Du Deine Expertise ab?
Aus dem Kopieren von Informationen von der OpenBSD-Page?
Ein Blick über Deine bisherigen Threads und Beiträge
hinterlassen nicht den Eindruck das Du eine besondere Affinität zu der Thematik besitzt!

Zum Thema Apache 1.3.
Die Kunden für die ich arbeite verwenden alle Apache 2.0.x.
Diesen Fakt wirst Du nicht wegdiskutieren können!
Falls Du eine Referenzliste haben möchtest dann schick doch eine PN.
 
Wenn ich Deine insbesondere letzten Beiträge lese, bin ich mir nicht sicher, ob ich erst an Pinky oder Brain denken muß...
Beziehe Dich auf das was ich schreibe und interpretiere doch nicht was ich nicht schreibe.
Dr. tib schrieb:
tib (Chemielaborant und Dr. rer. nat.)
Welchen Grund sollte ich haben, auf Deine Kundenliste gespannt zu sein? Erst recht welche Bewegründe diese Deiner Kunden haben, den zweier Zweig des Apachen zu benutzen -- Sicherheitsgründe jedenfalls nicht. .oO(Wofür braucht man eingentlich zum Laborputzen einen Webserver?)
 
Huch lars, du hast vollkommen Recht ich habe mich gehen lassen. Ich entschuldige mich für mein "Off-topic"-Gesülze.
 
Bitte beruhigt euch bitte wieder!
Wenn ihr unbedingt streiten wollt, dann macht das. Aber bitte nicht hier!

Danke, Athaba
 
:-)

Der Thread könnte sein Post 43 zu sein!

Wo hängt es denn?

PS: Über wen oder was sollte ich mich eigentlich aufregen, :-)
 
*Sheep schrieb:
Wenn ich Deine insbesondere letzten Beiträge lese, bin ich mir nicht sicher, ob ich erst an Pinky oder Brain denken muß...
Beziehe Dich auf das was ich schreibe und interpretiere doch nicht was ich nicht schreibe.

Meinst Du etwa mich ????
 
Paldium schrieb:
Hm, ich schätze den Sinn der Guardpages hab ich doch nicht richtig verstanden.
Sodele, an einem grauen Samstag kann man sich ja mal etwas Theorie antun ;-)

Bei der Gelegenheit kann man dann gleich nochmal dein malloc() Beispiel ansprechen. Das malloc() keine fortlaufenden Blöcke liefert, liegt daran, dass malloc() hier kein brk() mehr benutzt, sondern mmap().

mmap() wurde geändert, damit es zufällige Speicheradressen zurückliefert.

Und im Kernel wird jetzt überwacht, dass zwischen zwei von Objekten benutzen Seicherseiten eben eine Speicherseite leer bleibt: die Guard Page.
 
Alles klar, jetzt hab auch ich es verstanden. :)

Die Guardpages sind also einfach nur nicht allokierte Speicherstellen, denen man einen Namen gegeben hat. Pages liegen nie direkt hintereinander, so dass ein Zugriff über die Page (oder vor die Page) einen Segmentationfault zur Folge hat.

Damit müsste also dieses Programm hier unter FreeBSD (ohne malloc-Patch, der hier gepostet wurde) funktionieren, wenn die Pagesize dort auch 4 KB beträgt:

Code:
#include <err.h>
#include <stdio.h>
#include <stdlib.h>

int
main(void)
{
        int i;
        char *pointer[2];

        for (i = 0; i < 2; i++) {
                if ((pointer[i] = malloc(4096)) == NULL)
                        err(1, NULL);
                strncpy(pointer[i], "Ein Beispieltext", 4096);
                printf("Pointer (%x) mit Wert: %s\n", pointer[i], pointer[i]);
        }

        memset(pointer[0], 0, 2 * 4096);

        for (i = 0; i < 2; i++) {
                printf("Pointer (%x) mit Wert: %s\n", pointer[i], pointer[i]);
                free(pointer[i]);
                pointer[i] = NULL;
        }

        exit(0);
}

Code:
$ gcc -o guard guard.c
$ ./guard
Pointer (81980000) mit Wert: Ein Beispieltext
Pointer (7eb28000) mit Wert: Ein Beispieltext
Segmentation fault (core dumped)

Andererseits frage ich mich jetzt, wenn ich mir die Manualseite für malloc.conf durchlese, ob in OpenBSD Guardpages wirklich standardmäßig aktiviert sind.

G ``Guard''. Enable guard pages and chunk randomization. Each
page size or larger allocation is followed by a guard page that
will cause a segmentation fault upon any access. Smaller than
page size chunks are returned in a random order.

Diese Chunk Randomization ist beispielsweise nicht aktiv, denn das malloc-Programm hätte mit Chuck Randomization so aussehen müssen:

Code:
$ gcc -static -o malloc malloc.c
$ env MALLOC_OPTIONS=G ./malloc
 1. Pointer zeigt auf 7c520e00
 2. Pointer zeigt auf 7c520400
 3. Pointer zeigt auf 7c520800
 4. Pointer zeigt auf 7c520600
 5. Pointer zeigt auf 7c520c00
 6. Pointer zeigt auf 7c520a00
 7. Pointer zeigt auf 7c520200
 8. Pointer zeigt auf 7c520000
 9. Pointer zeigt auf 820bf200
10. Pointer zeigt auf 820bf800
11. Pointer zeigt auf 820bf400
12. Pointer zeigt auf 820bfc00
13. Pointer zeigt auf 820bfa00
14. Pointer zeigt auf 820bfe00
15. Pointer zeigt auf 820bf600
16. Pointer zeigt auf 820bf000
17. Pointer zeigt auf 7d397e00
18. Pointer zeigt auf 7d397400
19. Pointer zeigt auf 7d397a00
20. Pointer zeigt auf 7d397000

Wie man sieht sind jetzt auch innerhalb der Page die Werte durcheinandergewürfelt - vorher nicht. Im Übrigen musste ich das Programm statisch kompilieren, da es sonst nicht einmal die MALLOC_OPTIONS-Variable akzeptiert.

(nach unzähligen EDITs): Ich sehe gerade, dass Guardpages nicht standardmäßig aktiv sind.
 
Zuletzt bearbeitet:
Zurück
Oben