2

I'm looking at the following code and am trying to figure out how this bug would be helpful for something like launching a shell.

int func(int i, double *data1, double data2) 
{

double  *p = data1;       
double  *vec[10];

if ((i<0) || (i>10)) return;   

vec[i] = data1; 
*p = data2;     

}

There is an answer on the linked pdf below (Send i = 10 and data1 = RetAddr) but I'm looking for a more elaborate explanation.

The question comes from Dan Boneh's CS 155 class and is #3 here:

1 Answer 1

2

The short answer is that index 10 is beyond the bounds of array vec and writing an 8-byte double to vec[10] could overwrite the previous function's base pointer and the function return address - depending on how the compiler allocates memory on the stack for local variables.

Here is a diagram of the runtime stack when func has been called (x86 architecture is assumed):

 <------------ 4 bytes ----------->
                 .
                 .
                 .
 +---------------------------------+
 |             data2               |
 +---------------------------------+  arg 3 (8 bytes)
 |             data2               |
 +---------------------------------+  
 |             data1               |
 +---------------------------------+  arg 2 (8 bytes)
 |             data1               |
 +---------------------------------+
 |               i                 |  arg 1 
 +---------------------------------+
 |         return address          |                 < 8 bytes to      <--\
 +---------------------------------+                 < be overwritten      |
 | previous ebp (old base pointer) |  <-- "vec[10]"  < by data1            |
 +---------------------------------+                                       |  stack
 |             vec[9]              |                                       |  frame
 +---------------------------------+                                       |  for
 |             vec[8]              |                                       |  "func"
 +---------------------------------+                                       |
                 .                                                         |
                 .                                                         |
                 .                                                         |
 +---------------------------------+                                       |
 |             vec[1]              |                                       |
 +---------------------------------+                                       |
 |             vec[0]              |                                   <--/
 +---------------------------------+

Note that the arrangement of memory allocated for local variables in a stack frame is determined by the compiler. This means that stack alignment can result in "slack space" that throws off buffer offset calculation, for example. In addition, if the compiler allocates memory for variable p between saved ebp and memory allocated for the array vec, p will be overwritten rather than old ebp and the return address of func.

For more info on stack frame layout see:

5
  • Thanks! But then why would a canary not solve this problem...|| vec[9] | canary | ebp | return address ||. The answers suggests that stackShield would help (I agree), but why not stackGuard? Wouldn't | vec[10]] | replace the canary? Dec 9, 2017 at 18:38
  • @NathanReitinger stack protection was not mentioned in your post so I did not take it into consideration. Would you like an explanation of parts b, c and d as well?
    – julian
    Dec 9, 2017 at 18:42
  • this was a follow-up question---I get part (a) now thanks to the great answer :) so i moved on to parts (b)-(d). I understand both (c) and (d), but I'm wondering why a canary would not help. Dec 9, 2017 at 19:10
  • @NathanReitinger I think this paper should cover everything: Four different tricks to bypass StackShield and StackGuard protection. The short answer is that StackGuard places the canary between the saved base pointer and the return address, which means that the saved base pointer can be overwritten. There is a diagram of a StackGuard-protected stack frame shown in section 2 of the original paper
    – julian
    Dec 9, 2017 at 21:30
  • oops i mean section 3, figure 2
    – julian
    Dec 9, 2017 at 22:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .