返回libc-问题
我在返回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,
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