Some files that demonstrate buffer overflow and stack smashing. All these programs were tested on a PC running FreeBSD. You may need to make adjustments to make these work with other CPUs/OSs. execls: just shows how to use the exec() system call (it exec's /bin/ls). ov.c: a function that modifies the return address to point to a string. The string actually holds a small version of execls. Once the subroutine returns, it execs /bin/ls instead. vulnerable.c: a program with an overflowable buffer. This program reads from standard input and then stuffs whatever it got into a string. If we give it the right string (that is too large for the buffer and happens to hold a program and substitute return-address) - we can turn the program into /bin/ls or whatever we want! genpgm.c: a program that prints out a string that happens to be what we need to mess up the vulnerable program (to make it exec /bin/ls). genpgm needs an offset specified as a command line parameter - it adds this offset to the fixed number it assumes is the address of the buffer it is overflowing (used to replace the return address on the stack). Usage: genpgm 16 | ./vulnerable 16 seems to work (right now on BSD machine). The stack pointer seems to move around a little under bsd (it's not always the same value for the same program in the same function), so some playing around may be required. The vulnerable program actually prints out the relevant stackpointer, so it may be necessary to modify genpgm to use this value and recompile. If you change genpgm to output a string that is a program that will exec /bin/sh - you need to keep the pipe to vulnerable open so you can type in commands (so you can interact with the shell). Here is one way: (./genpgm 16; cat) | ./vulnerable So genpgm runs and sends it output to the pipe. Once it is done the cat command takes over, it's output is also sent to the pipe. BSD NOTES: system calls are done differently under BSD and linux. The file myexecls.s is assembly language for exec'ing "/bin/ls" with no absolute address dependencies and no nulls in the opcode. To create a string from myexecls: gcc -c myexecls.s objdump -D -z myexecls.o | ./makestring output from the perl script makestring looks something like this: char str[] = { 0x55, 0x89, 0xe5, 0x31, 0xc9, 0x51, 0xeb, 0x1b, 0x58, 0x88, 0x48, 0x07, 0x89, 0x40, 0x08, 0x89, 0x48, 0x0c, 0x8d, 0x58, 0x08, 0x53, 0x50, 0x31, 0xc0, 0xb0, 0x3b, 0x50, 0xcd, 0x80, 0x83, 0xc4, 0x0c, 0xc9, 0xc3, 0xe8, 0xe0, 0xff, 0xff, 0xff, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x6c, 0x73, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; Usually you need to add a bunch of nops (0x90) at the beginning of the string to make things work (this simply provides for some margin of error when estimating the address of the program once it has overflowed the buffer). 10/17/2003 current working parameters: ./vultest 16 ./genpgm 64 | ./vulnerable (./genpgmsh 64; cat) | ./vulnerable