Sicherheit von C/C++



  • 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.



  • Bashar schrieb:

    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.

    Hast du ein Beispiel für eine derart dumme VM, der man explizit sagt, ein Objekt zu vernichten und es trotzdem zulässt, darauf zuzugreifen. Es würde eine Laufzeitexception fliegen, genau das gleiche, wenn man auf null eine Methode aufruft.
    Und was hat das ganze mit Typsicherheit zu tun?
    😕



  • tfa schrieb:

    Bashar schrieb:

    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.

    Hast du ein Beispiel für eine derart dumme VM, der man explizit sagt, ein Objekt zu vernichten und es trotzdem zulässt, darauf zuzugreifen. Es würde eine Laufzeitexception fliegen, genau das gleiche, wenn man auf null eine Methode aufruft.

    Es nicht garantiert, dass an der Stelle, an die o zeigt, kein Objekt liegt. Wenn das so wäre, könnte man sich ja die Speicherfreigabe auch sparen. Es wird natürlich irgendwann dort wieder ein Objekt liegen! Und wenn das von einem Typ ist, der zu SomeObject kompatibel ist, merkt die VM das auch nicht.
    BTW, hast du ein Beispiel für eine VM ohne GC? 😉

    Und was hat das ganze mit Typsicherheit zu tun?

    Das ist der letzte Satz von oben. Typsicherheit heißt, dass es nicht möglich ist, ein Objekt eines Typs als Objekt eines anderen (inkompatiblen) Typs zu benutzen. Es wäre sonst ja auch denkbar, dass an der Stelle o ein Objekt des Typs Hund liegt, und o.machwas() dessen beißen()-Methode aufruft.



  • Bashar schrieb:

    Und was hat das ganze mit Typsicherheit zu tun?

    Das ist der letzte Satz von oben. Typsicherheit heißt, dass es nicht möglich ist, ein Objekt eines Typs als Objekt eines anderen (inkompatiblen) Typs zu benutzen. Es wäre sonst ja auch denkbar, dass an der Stelle o ein Objekt des Typs Hund liegt, und o.machwas() dessen beißen()-Methode aufruft.

    Und das sowas nicht passieren kann, kann die VM durchaus sicherstellen. Schließlich verwaltet sie die Objekte.

    BTW, hast du ein Beispiel für eine VM ohne GC? 😉

    Guter Punkt. Offensichtlich streiten wir uns über vollkommen blödsinnige Fragen.



  • tfa schrieb:

    Bashar schrieb:

    Und was hat das ganze mit Typsicherheit zu tun?

    Das ist der letzte Satz von oben. Typsicherheit heißt, dass es nicht möglich ist, ein Objekt eines Typs als Objekt eines anderen (inkompatiblen) Typs zu benutzen. Es wäre sonst ja auch denkbar, dass an der Stelle o ein Objekt des Typs Hund liegt, und o.machwas() dessen beißen()-Methode aufruft.

    Und das sowas nicht passieren kann, kann die VM durchaus sicherstellen. Schließlich verwaltet sie die Objekte.

    Und was wenn das Objekt an der Stelle zufällig von einem passenden Typ ist?



  • /deleted



  • Bashar schrieb:

    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*

    Natuerlich ist Zeigerarithmetik keine Speicherverwaltung, aber wenn du Zeigerarithmetik verwendest, dann umgehst du die Speicherverwaltung des GC. Also in C++ zumindest. Weil durch die Zeigerarithmetik greifst du direkt auf Speicherbereiche zu, die normalerweise von dem GC verwaltet werden. (natuerlich koennte man eine VM/GC bauen, die auch Zeigerarithmetik ueberprueft).

    Bashar schrieb:

    DEvent schrieb:

    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.

    Das ist aber sehr weit hergeholt. Gibt es dazu Beispiele? Also nicht die DOS-Atacke, sondern das andere.



  • DEvent schrieb:

    Meinst du eigentlich sowas:
    [...]

    Nein.

    Oder meinst du:

    SomeObject o = new SomeObject();
    o.machwas();
    delete o; // o ist jetzt freigegeben
    // ... mehr Code
    o.machwas()
    

    Dann gibt es eine NullPointerException (oder was aehnliches), und das Programm stuertzt ab oder die Exception wird gefangen.

    Eine NullPointerException gibt es, wenn o = null, was hier nicht der Fall ist. Eine andere Exception gibt es möglicherweise, wenn o auf irgendwas zeigt, was nicht mit SomeObject kompatibel ist.
    Das war jetzt die dritte Erklärung, ich hoffe es reicht langsam.



  • @Bashar sorry habe dich nicht ganz verstanden.



  • Bashar schrieb:

    Und was wenn das Objekt an der Stelle zufällig von einem passenden Typ ist?

    Dann wird dieses Objekt genommen. Jedenfalls wäre man eine solche Sprache ziemlich kaputt -- schlimmer als C++.


Anmelden zum Antworten