Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
返回libc-问题_C_Linux_Stack Overflow_Buffer Overflow_Exploit - Fatal编程技术网

返回libc-问题

返回libc-问题,c,linux,stack-overflow,buffer-overflow,exploit,C,Linux,Stack Overflow,Buffer Overflow,Exploit,我在返回libc时遇到问题。问题是什么都没有发生,但没有分段错误(是的,我实际上溢出了堆栈) 这是我的节目: int main(int argc, char **argv) { char array[512]; gets(array); } 我使用gets而不是strcopy,因为我的地址以0x00开头,strcpy认为它是字符串的结尾,所以我不能使用它 以下是我需要的地址: $ gdb main core (gdb) p system $1 = {<text variable,

我在返回libc时遇到问题。问题是什么都没有发生,但没有分段错误(是的,我实际上溢出了堆栈)

这是我的节目:

int main(int argc, char **argv) {
  char array[512];
  gets(array);
}
我使用gets而不是strcopy,因为我的地址以0x00开头,strcpy认为它是字符串的结尾,所以我不能使用它

以下是我需要的地址:

$ 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"
没什么

但如果我输入520'A(0x41),则EIP将溢出'A'。如果有516“A”,则不会发生任何事情,但EIP包含系统地址,在退出地址之后,在/bin/sh指针之后


为什么什么都没发生?

让我们先做一些asm:

代码

Asm

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

我建议您使用以下源代码进行破解:

$ cat getss.c
f()
{
  char array[512];
  gets(array);
}
int main(int argc, char **argv) {
    f();
}
因为f在堆栈重新对齐方面没有问题

.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()
的堆栈布局:

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


您是否在使用ASLR的环境中运行此程序?不,/proc/sys/kernel/randomize\u va_空间为0(因此它被禁用)。在这个问题中,还有一些其他东西需要尝试:我禁用了所有这些保护机制,我还使用正确的标志编译了-fno stack protector。。。所以没有保护,我可以毫无问题地溢出我的EIP(我用“A”溢出进行了测试,结果正常)。问题是上面的漏洞不起作用,我不知道为什么。如有任何提示,将不胜感激。我是否做错了什么,是否必须将系统地址放入EIP-4中?gets()也适用于字符串。它将在0x00处停止,就像strcpy一样,将fread()用于binary data.Hi。我知道堆栈是如何工作的,我知道堆栈对齐,这不是问题所在,因为我也计算了所有这些。问题是我无法将\x00保存在堆栈上,因为它是'\0'字符。@user620429,我认为,您错了,并且允许在字符串中保存一个
\0
字符。('d已检查glibc源)。@user620429,显示
读取的字节数为零
$ 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
(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
$ cat getss.c
f()
{
  char array[512];
  gets(array);
}
int main(int argc, char **argv) {
    f();
}
.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
(char)  array[0]
...
(char)  array[511]
(32bit) old ebp
(32bit) return address
(gdb) x/w $sp
0xXXXXXa3c:     0x41414141