Sicherheit von C/C++
-
Tim schrieb:
Bashar schrieb:
@hustbaer: Was hat denn ein GC mit Sicherheit zu tun?
Er kann bei Sicherheitsrelevanten Systemen verhindern, dass die Software aufgrund einen Speicherlecks den Dienst verweigert.
Kann er leider nicht, da man auch mit GC wunderbare Leaks zaubern kann (ich sag' nur statische Maps/Listen, "unbeabsichtigte" GC-Roots etc.)
Mit "Hacker"-Sicherheit hat das aber auch nichts zu tun.
Doch, ein wenig.
Wenn man von rein Funktionalen Sprachen mal absieht, ist ein GC die einzige Möglichkeit (*), garantieren zu können, dass ein Objekt, auf welches man zugreift, auch den Typ hat, den man erwartet.
Das klingt jetzt komisch, aber wenn man genauer drüber nachdenkt, wird vielleicht klar wieso.
Wenn ein nicht-GC Programm sagt "das brauch ich jetzt nimmer" (delete p;), dann wird der Speicher als frei markiert. Ganz egal, ob man noch woanders Zeiger/Referenzen auf diesen Speicher hat.
Das System wird den Speicher also alsbald wieder hergeben, und das Programm wird munter andere Dinge damit anstellen. Wenn nun die "alten" Zeiger auf diesen Speicherbereich wieder verwendet werden, passieren Dinge, von denen man vermutlich nicht möchte, dass sie passieren.
Gezielt ausnutzen lassen sich solche Bugs wohl schwer, aber ein System zumindest dazu zu bringen gröber Mist zu bauen, könnte durchaus manchmal drinnen sein, wenn man mal so einen Bug gefunden hat.Für die "Sicherheit" im Sinn von "Robustheit" hat ein GC dadurch allerdings einen dramatischen Einfluss.
----
So, nun zum *: natürlich braucht man keinen GC in dem Sinn, aber man braucht ein System, welches sämtliche Referenzen "trackt", und verhindert, dass Speicher "mehrfach verwendet" wird. Wenn man sowas allerdings schonmal hat, ist der Schritt, einen GC draus zu basteln, nichtmehr weit.
-
~fricky schrieb:
hustbaer schrieb:
Was Hack-Sicherheit angeht: in C und C++ kann man sehr leicht Programme schreiben die Sicherheitslöcher haben, z.B. "unchecked buffer".
ja, aber es gibt noch viele andere fallstricke, wie z.b. integer-überläufe und dadurch ungewollte vorzeichenwechsel, usw. usw. die einem programm seltsame angewohnheiten entlocken können.
Jo, klar gibt's noch haufenweise andere Dinge die man falsch machen/ausnutzen kann. Da steht ja auch "z.B."
-
DEvent schrieb:
Tim schrieb:
Bashar schrieb:
@hustbaer: Was hat denn ein GC mit Sicherheit zu tun?
Er kann bei Sicherheitsrelevanten Systemen verhindern, dass die Software aufgrund einen Speicherlecks den Dienst verweigert. Allerdings fragt sich wer auf solchen Systemen überhaupt dynamische Speicherverwaltung will. Mit "Hacker"-Sicherheit hat das aber auch nichts zu tun.
Ein GC (also im Grunde eine automatische, bzw. eine ueberwachte Speicherverwaltung) schliest schonmal den Hack-Angriff eines Buffer-Overflows aus. Bei einem Buffer-Overflow wird ja die Schwachstelle genutzt um Code einzuschleusen, der dann von der CPU ausgefuehrt wird. Wenn die Speicherverwaltung aber ueberwacht wird (wie es bei einem GC der Fall ist), dann kann man in einen Speicherbereich keinen Code injezieren.
Nope, stimmt so nicht. Es gibt auch Systeme wo man einen GC hat, aber trotzdem Zeigerarithmetik. z.B. sämtliche Systeme die auf C oder C++ einen GC draufsetzen. Die meisten Sprachen mit GC kennen allerdings keine Zeigerarithmetik, und verwenden "bounds-checking" bei Array-Zugriffen. Solche Systeme verhindern dann den klassischen "unchecked stack based buffer" Exploit.
Was immer noch nicht verhindert wird sind allerdings Fehler, wo man das System zwar nicht dazu bringt beliebigen Code auszuführen, aber immerhin dazu bringt irgendwas gröber falsch zu machen. Man kann ja z.B. auch innerhalb eines Puffers irgendwelche Grenzen haben, und vergessen, diese zu checken.
-
hustbaer schrieb:
Tim schrieb:
Bashar schrieb:
@hustbaer: Was hat denn ein GC mit Sicherheit zu tun?
Er kann bei Sicherheitsrelevanten Systemen verhindern, dass die Software aufgrund einen Speicherlecks den Dienst verweigert.
Kann er leider nicht, da man auch mit GC wunderbare Leaks zaubern kann (ich sag' nur statische Maps/Listen, "unbeabsichtigte" GC-Roots etc.)
Kann ich mir ehrlich gesagt gerade nichts drunter vorstellen. Magst mal ein konkretes Beispiel geben?
-
Bashar schrieb:
~fricky schrieb:
ja, aber es gibt noch viele andere fallstricke, wie z.b. integer-überläufe und dadurch ungewollte vorzeichenwechsel, usw. usw. die einem programm seltsame angewohnheiten entlocken können.
Aber auch in Java und .NET.
das schon, aber da sind sie weitaus ungefährlicher. ein übergelaufener int als array-index oder pointer offset ergibt ein prima sicherheitsloch. ausserdem nehmen c++ progger auch gern mal 'int' obwohl sie eigentlich 'int32_t' meinen.
-
hustbaer schrieb:
Doch, ein wenig.
Wenn man von rein Funktionalen Sprachen mal absieht, ist ein GC die einzige Möglichkeit (*), garantieren zu können, dass ein Objekt, auf welches man zugreift, auch den Typ hat, den man erwartet.Das reicht nicht aus, man muss auch wildes Casten a la C verhindern können. Aber du scheinst insofern recht zu haben, als dass ein GC eine notwendige Voraussetzung für (Typ-)Sicherheit darstellt.
-
Bashar schrieb:
hustbaer schrieb:
Doch, ein wenig.
Wenn man von rein Funktionalen Sprachen mal absieht, ist ein GC die einzige Möglichkeit (*), garantieren zu können, dass ein Objekt, auf welches man zugreift, auch den Typ hat, den man erwartet.Das reicht nicht aus, man muss auch wildes Casten a la C verhindern können. Aber du scheinst insofern recht zu haben, als dass ein GC eine notwendige Voraussetzung für (Typ-)Sicherheit darstellt.
Das denke ich nicht. Der springende Punkt ist nicht der GC sondern eine Laufzeitumgebung bzw. virtuelle Maschine.
-
buzz_lightzyear schrieb:
Hallo,
ich habe bis mittwoch einen Text über die Sicherheit von der Programmiersprache C/C++ zu schreiben. Mit Sicherheit ist denk ich mal "Hack-Sicherheit" gemeint.
Leider habe ich keinen Plan was ich darüber schreiben soll. Hat irgendjemand einen Link zu besonderer Literatur was dieses Thema betrifft? die Uni-Bibliothek hilft hier auch nicht wirklich. Was würdet ihr über dieses thema schreiben? Bin für jeden Anhaltspunkt dankbar
Lg
bES GIBT KEINE PROGRAMMIERSPRACHE MIT DEM NAMEN C/C++. ES GIBT EINE PROGRAMMIERSPRACHE MIT DEM NAMEN "C" UND EINE ANDERE MIT DEM NAMEN "C++".
Und nun zum Thema: Keine der beiden Sprachen sind unsicher. Es sind höchstens die Programme, die ich mit der Sprache schreibe unsicher. Dann sind es aber Programmierfehler in dem Programm, aber nicht in der Sprache. Und Programmierfehler, die Sicherheitslücken verursachen sind in jeder Sprache möglich.
Die Sprache C ist recht rudimentär und ist dadurch recht aufwändig, sichere Programme zu schreiben. Oft ist man beispielsweise bestrebt, feste Puffergrössen zu verwenden, die unter Umständen zu Pufferüberläufen führen. Eine solche Sicherheitslücke entsteht aber durch Bequemlichkeit und nicht durch die Sprache C.
In anderen höheren Sprachen, wie beispielsweise C++ ist es einfacher, beispielsweise std::string oder std::vector zu nutzen. Sicher sind auch hier Pufferüberläufe und andere Programmierfehler möglich, aber einfacher zu verhindern.
-
tntnet schrieb:
In anderen höheren Sprachen, wie beispielsweise C++ ist es einfacher, beispielsweise std::string oder std::vector zu nutzen.
dumm ist nur, dass du in c++ auch alle fehler machen kannst, die in C möglich sind. was das angeht, kann der OP beide ruhig in einen topf werfen.
-
hustbaer schrieb:
Nope, stimmt so nicht. Es gibt auch Systeme wo man einen GC hat, aber trotzdem Zeigerarithmetik. z.B. sämtliche Systeme die auf C oder C++ einen GC draufsetzen. Die meisten Sprachen mit GC kennen allerdings keine Zeigerarithmetik, und verwenden "bounds-checking" bei Array-Zugriffen. Solche Systeme verhindern dann den klassischen "unchecked stack based buffer" Exploit.
Du willst zum einen die Sicherheit einer Speicherverwaltung (GC), aber dann umgehst du diese mit Zeigerarithmetik? Natuerklich darfst du keine eigene Speicherverwaltung neben dem GC haben.
hustbaer schrieb:
Was immer noch nicht verhindert wird sind allerdings Fehler, wo man das System zwar nicht dazu bringt beliebigen Code auszuführen, aber immerhin dazu bringt irgendwas gröber falsch zu machen. Man kann ja z.B. auch innerhalb eines Puffers irgendwelche Grenzen haben, und vergessen, diese zu checken.
Im schlimmsten Fall stuertzt also das Programm ab. Das ist um Dimensionen weniger Schaden als was mit injeziertem Code machen kann. Das Ziel eines Hackers ist es nicht deine Programme zum Absturz zu bringen, sondern die Kontrolle ueber deinen Computer zu erlangen.
-
tfa schrieb:
Bashar schrieb:
ein GC eine notwendige Voraussetzung für (Typ-)Sicherheit darstellt.
Das denke ich nicht. Der springende Punkt ist nicht der GC sondern eine Laufzeitumgebung bzw. virtuelle Maschine.
Angenommen, wir hätten eine VM ohne GC, und folgenden Code:
SomeObject o = new SomeObject(); o.machwas(); delete o; // ... mehr Code o.machwas()
Woher weiß die VM ohne GC, dass o nicht mehr auf dasselbe Objekt wie am Anfang verweist? Es könnte sein, dass das neue Objekt an der Stelle, auf die o verweist, vom Typ SomeObject ist, dann erkennt man das auch nicht durch Laufzeit-Typprüfung.
-
DEvent schrieb:
Du willst zum einen die Sicherheit einer Speicherverwaltung (GC), aber dann umgehst du diese mit Zeigerarithmetik? Natuerklich darfst du keine eigene Speicherverwaltung neben dem GC haben.
Zeigerarithmetik != Speicherverwaltung *gebetsmühle*
Im schlimmsten Fall stuertzt also das Programm ab. Das ist um Dimensionen weniger Schaden als was mit injeziertem Code machen kann. Das Ziel eines Hackers ist es nicht deine Programme zum Absturz zu bringen, sondern die Kontrolle ueber deinen Computer zu erlangen.
man DOS-Attacke
Angriff etwa nach dem Schema: Ein für die Sicherheit einer Website notwendiges System wird zum Absturz gebracht. Anstatt dann aber das ganze Angebot einzustellen, wird (aufgrund Manager-Entscheidung) das System mit verringerter Sicherheit weitergefahren, bis die IT-ler das wieder zum Laufen gebracht haben.
-
~fricky schrieb:
dumm ist nur, dass du in c++ auch alle fehler machen kannst, die in C möglich sind. was das angeht, kann der OP beide ruhig in einen topf werfen.
Können ja, aber ich würde dennoch C und C++ nicht auf eine Stufe setzen (und auch als Sprache trennen). Wenn man C++ im Sinne der C++ Standardbibliothek etc. verwendet, kann man einige Fallstricke von C umgehen. Das man die gleichen Fehler machen kann, gerade wenn man meint C++ wie C zu programmieren, steht aber außer Frage...
-
Bashar schrieb:
Angenommen, wir hätten eine VM ohne GC, und folgenden Code:
SomeObject o = new SomeObject(); o.machwas(); delete o; // ... mehr Code o.machwas()
Woher weiß die VM ohne GC, dass o nicht mehr auf dasselbe Objekt wie am Anfang verweist? Es könnte sein, dass das neue Objekt an der Stelle, auf die o verweist, vom Typ SomeObject ist, dann erkennt man das auch nicht durch Laufzeit-Typprüfung.
Da steht "delete o;" Ob das o jetzt explizit durch dich oder einen GC (da stünde da z.B. o=null;) gelöscht wird, ist doch egal.
-
asc schrieb:
~fricky schrieb:
dumm ist nur, dass du in c++ auch alle fehler machen kannst, die in C möglich sind. was das angeht, kann der OP beide ruhig in einen topf werfen.
Können ja, aber ich würde dennoch C und C++ nicht auf eine Stufe setzen (und auch als Sprache trennen). Wenn man C++ im Sinne der C++ Standardbibliothek etc. verwendet, kann man einige Fallstricke von C umgehen. Das man die gleichen Fehler machen kann, gerade wenn man meint C++ wie C zu programmieren, steht aber außer Frage...
klar, beide sprachen haben gute und schlechte seiten, wobei allerdings C++ fast alles gute und schlechte von C geerbt hat. angenommen, ich wollte ein software bauen, die möglichst stabil und immun gegen hackerangriffe sein soll und angenommen, ich könnte mich nur zwischen C und C++ entscheiden. weiterhin angenommen, ein haufen mittelmäsiger anwendungsentwickler soll mit der aufgabe betraut werden. wahrscheinlich würde ich mich für C entscheiden. gründe: für C gibt es fiese coding-richtlinien, wie misra, etc. mit denen man die leute ärgern kann, die aber trotz allem die qualität hoch halten. ausserdem haben es statische code-analysetools einfacher, in C-code fehler zu finden, als in C++ code.
-
~fricky schrieb:
asc schrieb:
~fricky schrieb:
dumm ist nur, dass du in c++ auch alle fehler machen kannst, die in C möglich sind. was das angeht, kann der OP beide ruhig in einen topf werfen.
Können ja, aber ich würde dennoch C und C++ nicht auf eine Stufe setzen (und auch als Sprache trennen). Wenn man C++ im Sinne der C++ Standardbibliothek etc. verwendet, kann man einige Fallstricke von C umgehen. Das man die gleichen Fehler machen kann, gerade wenn man meint C++ wie C zu programmieren, steht aber außer Frage...
gründe: für C gibt es fiese coding-richtlinien, wie misra, etc. mit denen man die leute ärgern kann, die aber trotz allem die qualität hoch halten.
MISRA gibt es auch für C++. Aber ich glaube nicht, dass das für unsere x86-only-Kandidaten hier überhaupt eine Relevanz hat
-
tntnet schrieb:
ES GIBT KEINE PROGRAMMIERSPRACHE MIT DEM NAMEN C/C++. ES GIBT EINE PROGRAMMIERSPRACHE MIT DEM NAMEN "C" UND EINE ANDERE MIT DEM NAMEN "C++".
Und nun zum Thema: Keine der beiden Sprachen sind unsicher. Es sind höchstens die Programme, die ich mit der Sprache schreibe unsicher. Dann sind es aber Programmierfehler in dem Programm, aber nicht in der Sprache. Und Programmierfehler, die Sicherheitslücken verursachen sind in jeder Sprache möglich.
Die Sprache C ist recht rudimentär und ist dadurch recht aufwändig, sichere Programme zu schreiben. Oft ist man beispielsweise bestrebt, feste Puffergrössen zu verwenden, die unter Umständen zu Pufferüberläufen führen. Eine solche Sicherheitslücke entsteht aber durch Bequemlichkeit und nicht durch die Sprache C.
In anderen höheren Sprachen, wie beispielsweise C++ ist es einfacher, beispielsweise std::string oder std::vector zu nutzen. Sicher sind auch hier Pufferüberläufe und andere Programmierfehler möglich, aber einfacher zu verhindern.
das ist klar. paßt aber nicht zum thema.
thema ist "die Sicherheit von der Programmiersprache C/C++".
a) der lehrer hat das thema vorgegeben. dann hat er keine ahnung und ein schüler, der schreibt, wie es richtig ist, hat verkackt.
b) der schüler hat sich das thema ausgesucht, dann wüßte er bereits die einfachsten grundlagen, das scheint nicht der fall.
c) ein troll.
ich halte a) für am wahrscheinlichsten."C/C++" liest man eigentlich nur noch in java-höhlen, wo jemand wiedermal schreibt, c++ sei total schlecht, weil man in c vor 20 jahren als anfänger oft probleme mit zeigern hatte, gehen wir also davon aus, daß der lehrer einen verriß wünscht. tun wir ihm doch den gefallen.
-
volkard schrieb:
...c++ sei total schlecht, weil man in c vor 20 jahren als anfänger oft probleme mit zeigern hatte...
das konnte stroustrup vor 30 jahren ja noch nicht wissen.
-
tfa schrieb:
Bashar schrieb:
Angenommen, wir hätten eine VM ohne GC, und folgenden Code:
SomeObject o = new SomeObject(); o.machwas(); delete o; // ... mehr Code o.machwas()
Da steht "delete o;" Ob das o jetzt explizit durch dich oder einen GC (da stünde da z.B. o=null;) gelöscht wird, ist doch egal.
Nein, das ist nicht egal. In dem einen Fall habe ich noch eine Referenz (nämlich mindestens o) auf das nicht mehr vorhandene Objekt, dann kann ich also o.machwas() auf einem falschen Objekt ausführen, im anderen Fall nicht.
-
volkard schrieb:
tntnet schrieb:
ES GIBT KEINE PROGRAMMIERSPRACHE MIT DEM NAMEN C/C++. ES GIBT EINE PROGRAMMIERSPRACHE MIT DEM NAMEN "C" UND EINE ANDERE MIT DEM NAMEN "C++".
Und nun zum Thema: Keine der beiden Sprachen sind unsicher. Es sind höchstens die Programme, die ich mit der Sprache schreibe unsicher. Dann sind es aber Programmierfehler in dem Programm, aber nicht in der Sprache. Und Programmierfehler, die Sicherheitslücken verursachen sind in jeder Sprache möglich.
Die Sprache C ist recht rudimentär und ist dadurch recht aufwändig, sichere Programme zu schreiben. Oft ist man beispielsweise bestrebt, feste Puffergrössen zu verwenden, die unter Umständen zu Pufferüberläufen führen. Eine solche Sicherheitslücke entsteht aber durch Bequemlichkeit und nicht durch die Sprache C.
In anderen höheren Sprachen, wie beispielsweise C++ ist es einfacher, beispielsweise std::string oder std::vector zu nutzen. Sicher sind auch hier Pufferüberläufe und andere Programmierfehler möglich, aber einfacher zu verhindern.
das ist klar. paßt aber nicht zum thema.
thema ist "die Sicherheit von der Programmiersprache C/C++".
a) der lehrer hat das thema vorgegeben. dann hat er keine ahnung und ein schüler, der schreibt, wie es richtig ist, hat verkackt.
b) der schüler hat sich das thema ausgesucht, dann wüßte er bereits die einfachsten grundlagen, das scheint nicht der fall.
c) ein troll.Bekäme ich eine solche Aufgabenstellung vom Lehrer, unterschiede ich dennoch C und C++. Meiner Ansicht nach (die ich bei einem solchen Referat auch verträte), macht C++ genau das aus, daß ich einfacher sicheren Code schreiben kann. Und genau das ist doch das Thema.