1
votes

Trying a buffer overflow to overwrite return address on stack for the following program. I want to call accept on both case of strcmp()

void accept()
{ 
  printf ("\nAccess Granted!\n");
  return;
}    
void deny()
{
  printf ("\nAccess Denied!\n");
  return;
}
int main()
{
  char pwd[16]={0};
  printf ("Enter Password: ");
  gets (pwd);
  if(strcmp(pwd, "pwd1"))
    deny ();
  else
    accept ();
return 0;
}

While disassembling the main, it's understood 20 bytes are allocated for variables as in 0x080484fb <+14>: sub $0x14,%esp Dump of assembler code for function main:

   0x080484ed <+0>:     lea    0x4(%esp),%ecx
   0x080484f1 <+4>:     and    $0xfffffff0,%esp
   0x080484f4 <+7>:     pushl  -0x4(%ecx)
   0x080484f7 <+10>:    push   %ebp
   0x080484f8 <+11>:    mov    %esp,%ebp
   0x080484fa <+13>:    push   %ecx
   0x080484fb <+14>:    sub    $0x14,%esp
   0x080484fe <+17>:    movl   $0x0,-0x18(%ebp)
   0x08048505 <+24>:    movl   $0x0,-0x14(%ebp)
   0x0804850c <+31>:    movl   $0x0,-0x10(%ebp)
   0x08048513 <+38>:    movl   $0x0,-0xc(%ebp)
   0x0804851a <+45>:    sub    $0xc,%esp
   0x0804851d <+48>:    push   $0x8048611
   0x08048522 <+53>:    call   0x8048370 <printf@plt>
   0x08048527 <+58>:    add    $0x10,%esp
   0x0804852a <+61>:    sub    $0xc,%esp
   0x0804852d <+64>:    lea    -0x18(%ebp),%eax
   0x08048530 <+67>:    push   %eax
   0x08048531 <+68>:    call   0x8048380 <gets@plt>
   0x08048536 <+73>:    add    $0x10,%esp
   0x08048539 <+76>:    sub    $0x8,%esp
   0x0804853c <+79>:    push   $0x8048622
   0x08048541 <+84>:    lea    -0x18(%ebp),%eax
   0x08048544 <+87>:    push   %eax
   0x08048545 <+88>:    call   0x8048360 <strcmp@plt>
   0x0804854a <+93>:    add    $0x10,%esp
   0x0804854d <+96>:    test   %eax,%eax
   0x0804854f <+98>:    je     0x8048558 <main+107>
   0x08048551 <+100>:   call   0x80484d4 <deny>
   0x08048556 <+105>:   jmp    0x804855d <main+112>
   0x08048558 <+107>:   call   0x80484bb <accept>
   0x0804855d <+112>:   mov    $0x0,%eax
   0x08048562 <+117>:   mov    -0x4(%ebp),%ecx
   0x08048565 <+120>:   leave  
   0x08048566 <+121>:   lea    -0x4(%ecx),%esp
   0x08048569 <+124>:   ret

When I try to fuzz with input string AAAAA... I found the overwrite on buffer is partial

Backtrace stopped: Cannot access memory at address 0x41413d
(gdb) R
The program being debugged has been started already.
Start it from the beginning? (y or n) Y
Starting program: BufferOverflow.x 
\Enter Password: AAAAAAAAAAAAAAAAAAAAAAAA

Access Denied!

Program received signal SIGSEGV, Segmentation fault.
0x08048569 in main ()
(gdb) BT
#0  0x08048569 in main ()
Backtrace stopped: Cannot access memory at address 0x4141413d
(gdb) R
The program being debugged has been started already.
Start it from the beginning? (y or n) Y
Starting program: BufferOverflow.x 
Enter Password: AAAAAAAAAAAAAAAAAAAAAAAAA

Access Denied!

Program received signal SIGSEGV, Segmentation fault.
0x08048569 in main ()
(gdb) BT
#0  0x08048569 in main ()
Backtrace stopped: Cannot access memory at address 0x4141413d
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: BufferOverflow.x 
Enter Password: AAAAAAAAAAAAAAAAAAAAAAAAAA

Access Denied!

Program received signal SIGSEGV, Segmentation fault.
0x08048569 in main ()
(gdb) bt
#0  0x08048569 in main ()
Backtrace stopped: Cannot access memory at address 0x4141413d

If you observe closely, the return address is not overflowed completely, but partially as 0x4141413d, if note the address ends with 3d always, even for 100 As - the return address same 0x4141413d

I disabled before starting

cat  /proc/sys/kernel/randomize_va_space
0

And compiled as:

gcc BufferOverflow.c -o BufferOverflow.x -m32 -fno-stack-protector

Am using gcc

gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

Any help in identifying why the buffer is not overflown properly would be appreciated.

Thanks

2

2 Answers

0
votes

Because a buffer overflow causes undefined behavior, it's hard to say what is causing this without looking through the internals of the gets() function. It's quite possible that some pointer inside gets() is being manipulated and causing this corruption.

Note also that "?" is commonly used to represent unprintable characters in ASCII. This could be related to the behavior you're seeing, though I couldn't find any documentation describing such behavior with gets()

0
votes

Just had the same question, and eventually found the answer here. In short, you need to wrap the vulnerable calls in another function, and call that function in main().