-2

I have a piece of code which contains an obvious buffer overflow at strcpy(buf, x) since it doesn't check if buf is large enough to fit the string x. I'm wondering how to actually exploit this bug.

void fun(char *x) {
    char buf[10];
    strcpy(buf, x);
    printf("You gave me this: %s", buf);
    exit(0);
}

And here's how the function is called from main:

fun(argv[1]);

The classical technique for exploiting a buffer overflow on the stack is overwriting the return address with a pointer to the shell code. This will execute the shell code once ret pops modified return address from the stack and jumps to it. But this technique won't work here because the function fun is not returning. Instead, exit(0) is executed.

Also, I can't do a format string attack because printf is being used safely (I think). At first, I thought that this cannot be exploited. Then I did some research and found out about code caving. But the problem is that code caving requires modification of the binary.

So, my question is can the buffer overflow in the above code be exploited? If not, what other techniques can be used given that there is no other vulnerable code in main()?

PS: Linux, 32-bit, Intel. Assume that no safeguards like ASLR etc are active.

PS: Exploit should result in me getting a root shell.

  • No. No other vulnerable code. I don't see any string format bug. – David Mealy Mar 5 '14 at 12:12
  • @DavidMealy I modified your question to be a bit clearer. If you don't like my edit, feel free to roll it back. – CodesInChaos Mar 5 '14 at 13:54
  • main has another flaw: It assumes there there is at least one command line argument. If there isn't, evaluating argv[1] is undefined behavior. But I don't see a way to exploit this. – CodesInChaos Mar 5 '14 at 13:57
2

I originally thought the code was vulnerable however after reading @CodesInChaos comment I decided to look into it more. This code is NOT vulnerable.It is possible to EIP however this is meaningless this would not change the flow of execution. If this code did not contain exit(0); Then it would be possible to exploit. Here is an explanation. The code supply I could not work with so I modified it.

-#/home/tim/scripts/fun "`perl -e 'print "a"x22 . "\x21\x43\x65\x87";'`"

Breakpoint 1, main (argc=2, x=0xbffff184) at mod2.c:6  
6   strcpy(buffer, x[1]);  
(gdb) info frame  
Stack level 0, frame at 0xbffff0f0:  
 eip = 0x8048486 in main (mod2.c:6); saved eip 0xb7e29905  
 source language c.  
 Arglist at 0xbffff0e8, args: argc=2, x=0xbffff184  
 Locals at 0xbffff0e8, Previous frame's sp is 0xbffff0f0  
 Saved registers:  
  ebp at 0xbffff0e8, eip at 0xbffff0ec  
(gdb) disas main  
Dump of assembler code for function main:  
   0x0804847d <+0>: push   %ebp  
   0x0804847e <+1>: mov    %esp,%ebp  
   0x08048480 <+3>: and    $0xfffffff0,%esp  
   0x08048483 <+6>: sub    $0x20,%esp  
=> 0x08048486 <+9>: mov    0xc(%ebp),%eax   
   0x08048489 <+12>:    add    $0x4,%eax  
   0x0804848c <+15>:    mov    (%eax),%eax  
   0x0804848e <+17>:    mov    %eax,0x4(%esp)  
   0x08048492 <+21>:    lea    0x16(%esp),%eax <-This is where EIP is overwritten   
   0x08048496 <+25>:    mov    %eax,(%esp)  
   0x08048499 <+28>:    call   0x8048340 <strcpy@plt>  
   0x0804849e <+33>:    lea    0x16(%esp),%eax  
   0x080484a2 <+37>:    mov    %eax,0x4(%esp)  
   0x080484a6 <+41>:    movl   $0x8048550,(%esp)  
   0x080484ad <+48>:    call   0x8048330 <printf@plt>  
   0x080484b2 <+53>:    movl   $0x0,(%esp)  
   0x080484b9 <+60>:    call   0x8048360 <exit@plt>  
End of assembler dump.  
(gdb) list  
1   #include <string.h>  
2   #include <stdlib.h>  
3   #include <stdio.h>  
4   void main(int argc, char *x[]) {  
5   char buffer[10];  
6   strcpy(buffer, x[1]);  
7   printf("You gave me this: %s\n", buffer);  
8   exit(0);  
9   }  
(gdb) break 7  
Breakpoint 2 at 0x804849e: file mod2.c, line 7.  
(gdb) cont  
Continuing.  

Breakpoint 2, main (argc=0, x=0xbffff184) at mod2.c:7  
7   printf("You gave me this: %s\n", buffer);  
(gdb) info frame  
Stack level 0, frame at 0xbffff0f0:  
 eip = 0x804849e in main (mod2.c:7); saved eip 0x87654321 <-EIP is overwritten   
 source language c.  
 Arglist at 0xbffff0e8, args: argc=0, x=0xbffff184  
 Locals at 0xbffff0e8, Previous frame's sp is 0xbffff0f0  
 Saved registers:  
  ebp at 0xbffff0e8, eip at 0xbffff0ec  
(gdb) cont  
Continuing.  
You gave me this: aaaaaaaaaaaaaaaaaaaaaa!Ce�  
[Inferior 1 (process 30432) exited normally] <-Program exists without a problem  
(gdb)  
  • please explain the vulnerability. – David Mealy Mar 5 '14 at 13:15
  • I have explained the vulnerability above. @DavidMealy – Tim Jonas Mar 5 '14 at 13:28
  • I don't think it would overwrite the EIP because exit() will terminate the program before the return address is popped. – David Mealy Mar 5 '14 at 13:37
  • 1
    @executifs There is no format string error there. printf("The right way to print user-controlled input:\n"); printf("%s", text); and printf("\nThe wrong way to print user-controlled input:\n"); printf(text); – Tim Jonas Mar 5 '14 at 13:37
  • 1
    It still gets overwritten with exit(0); See above @DavidMealy – Tim Jonas Mar 5 '14 at 14:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.