Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Allgemeines (OffTopic) » Exploit mit printf&Co

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
10.09.2004, 15:51 Uhr
mike
Pinguinhüpfer
(Operator)


Hi!
Man hört des Öfteren, dass man mit printf & Co Exploits erzwingen kann. Wie ist das gemeint? Kann mir evntl. wer ein Beispiel zeigen?

Danke im Voraus,
mfg
--
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
10.09.2004, 16:20 Uhr
0xdeadbeef
Gott
(Operator)


scanf ist anfällig für Buffer overflows in der Art:

C++:
buf[10];
scanf("%s, buf"); /* <-- buffer overflow, wenn jemand hier mehr als 9 Zeichen eingibt */


Das widerum kann u.U. dazu führen, dass andere Variablen auf dem Stack mit irgendwelchem Kram überschrieben werden, und das kann alle möglichen Effekte haben. Bei mir zum Beispiel:

sh:

$ cat t.c
#include <stdio.h>

int main() {
  char buf2[100],
    buf[5],
    *p = buf,
    *q = buf2;

  scanf("%s", p);
  puts(buf2);

  return 0;
}
$ echo abcdefghijklmnopqrstuvwxyz | ./a.out
qrstuvwxyz


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 10.09.2004 um 16:20 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
10.09.2004, 16:26 Uhr
virtual
Sexiest Bit alive
(Operator)


Ein knkretes Beispiel kann ich Dir nicht geben, lediglich einen Eindruck. Zu diesem Zweck mal folgendes Progrämmchen:

C++:
#include <stdio.h>

void test() {
    char a[4] = { 0, 0, 0, 0 };
    char b[4] = { 0, 0, 0, 0 };
    char c[4] = { 0, 0, 0, 0 };
    int i;

    memcpy(b, "hello", 5); // Denk dir hier ein printf

    printf("a (%p):", a);
    for(i=0; i<4; ++i) printf("%d ", a[i]);
    puts("");
    printf("b (%p):", b);
    for(i=0; i<4; ++i) printf("%d ", b[i]);
    puts("");
    printf("c (%p):", c);
    for(i=0; i<4; ++i) printf("%d ", c[i]);
    puts("");
}

int main()
{
    test();
}


Zum Ablauf: test enthält drei 4 byte große Arrays, welche Anfangs alle auf 0 gesetzt werden. Dann gibt es eine memcpy Anweisung, die in den Speicher von b schreibt, leider aber auch ein wenig darüber. Das könnte auch ein printf, oder ein gets gewesen sein, also eben irgendwas, was den Speicher von b verändern wird.

Das Programm ist noch recht sicher, aber wenn Du es laufen läßt, solltest Du sehen, daß eben auch das letzte Byte von a in Mitleidenschaft gezogen wurde, weil man über die Puffergrenzen geschrieben hat. Bishier ist das so harmlos wie jede Art von Pufferüberlauf: es führt zum Absturz oder eben nicht (in diesem Fall nicht, weil ich es so wollte).

Was die Ausgabe aber auch zeigt ist, daß a eine größere Speicheradresse als b hat. Das ist von ziemlicher bedeutung, weil bei den meisten Archtikturen von großen nach kleinen Speicheraddressen wächst. Dh wenn Du in einer Funktion bist und der Stackframe bei X beginnt, dann wird dieser der nächste Stackframe auf einer kleineren Speicheraddresse abgelegt.
So ein Stackframe enthät in der Regel auch sowas wie eine Rücksprungadresse, Sicherungskopien wichtiger Register usw. Rücksprungaddressen dienen dazu, daß sich der Computer merken kann, wo es weiter geht, wenn die Funktion verlassen wird.

Wenn ich nun im obigen Beispiel also eine gewisse anzahl von Bytes reinschreibe, habe ich ganz gute karten:
1. Jede lokale Variable zu verändern, die Stack eine höhere Addresse hat, daß der eigentliche Zielbuffer
2. Die sicherungkopien einiger wichtiger Register
3. Die Rücksprungadresse.

Da es den I/O Routinen ziemlich egal ist, was man so eingibt, kann man natürlich nun auf die Idee kommen, nicht nur druckbare Zeicheneinzugeben, sondern eben auch Bytefolgen, die eben irgendwie Sinn machen, aber letztlich mit dazu führen können, daß man og angesprochenen Dinge so überschreibt, daß das Programm nicht abstürzt, wohl aber etwas anderes tut, als man eigentlich wollte:

Ich mache sowas nicht, von daher kann ich Dir auch nicht sagen, in wie weit es Tools gibt, die diese Sache stark vereinfachen, aber ich denke, daß das Prinzip schon so ist.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
10.09.2004, 16:44 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


Ich hab darüber auch mal was gelesen das dann nämlich wie virtual bereits sagte nicht irgendwas in den Speichergeschrieben wird, sondern gaaaaaaaaaaaanz viel NOPs. Diese sagen dem Funktionspointer vom BS das er nichts machen soll und er geht eine Stelle weiter. Irgendwann hinter den NOPs wird dann der eigentliche auszuführende Code in Maschinensprache angehangen.

Wenn also der Funktionspointer irgendwann auf eine Stelle trifft die von NOPs überschrieben wurde wandert er so lange weiter bis er an den Code trifft und führt diesen aus (und das sogar mit den Rechten die das Programm hatte das eigentlich eine andere Funktion an der Stelle ausführen wollte die von NOPs überschrieben war).

Das Ganze ist natürlich sehr vereinfacht ausgedrückt und ich weis auch gar nicht mehr ob der Zeiger den ich meine überhaupt Funktionszeiger heißt,aber das Prinzip sollte klar werden
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
10.09.2004, 18:17 Uhr
~mike
Gast


Hi!
Danke für Eure Antworten und Samples!!
@virtual: Finde ich interessant. a braucht 4 bytes und b schießt weit drüber hinaus, so dass c erst einige bytes später anfängt. Dann schreibt b aber wieder in den Bereich von a Schön kompliziert. Werd ich mal genauer unter die Lupe nehmen

Dake euch,
mfg
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
10.09.2004, 19:42 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


@mike
nein a,b und c liegen einfach hintereinander im speicher auf den stack weil sie auch in der reihenfolge definiert wurde, wurden sie auch in der reihenfolge auf dem stack abgelgt...
da er a über schreibt und nicht c weisst und in welche richtung des speichers er schreibt also von "unten nach oben" ...

mal dir den speicher einfach mal auf nem blatt papier auf dann peilst du das auch sofort...
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
10.09.2004, 21:38 Uhr
lookIN



falls es jemanden interessiert: hier
gibt es ein sehr interessantes Buch zu dem Thema. Beschäftigt sich hauptsächlich mit buffer-overflows und format-strings(so nennt sich das).
Das Buch beschäftigt sich hauptsächlich mit Linux.
Ich habs daheim stehen, noch nicht ganz durch, aber ich finde es sehr gut.

Zu dem ganzen. Bevor ich das Buch hatte hab ich gedacht, dass es doch hoffentlich wenigstens ein bisschen schwerer ist eine schwachstelle in einem Programm auszunutzen, aber es sind meistens wirklich einfach nur ein drei Zeilen Code und ein bisschen Disassembler bzw. Decompiler(manchmal ein bisschen besser lesbar, auch wenns so was ja eigentlich nicht gibt) und schon hat man's.
Gruß
--
--
lookIN
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
19.09.2004, 15:43 Uhr
~mike
Gast


Hi!
Ist man eigentlich mit

C++:
#include <stdio.h>

int
main(void)
{
  char puff[10];
  scanf("%20s",puff);
  printf("\n%s",puff);
}


sicher unterwegs?

Hab noch was kewles gefunden
www.cs.ucsb.edu/~jzhou/security/overflow.html

thx&mfg
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
19.09.2004, 15:50 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


Nein es wird trotzdem die gesamte Eingabe gespeichert.

Du könntest es aber so machen:

C++:
#include <stdio.h>

int main(void)
{
  char puff[10];
  scanf("%9c",puff);
  puff[9]=0;
  printf("\n%s",puff);
  return 0;
}


oder direkt fgets nehmen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
19.09.2004, 18:57 Uhr
~mike
Gast


Hmm. Man oh man. Also ich glaube das C ist nix für mich

Thx für sample. Werd mir noch mal alles anschaun

mfg
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ Allgemeines (OffTopic) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: