我知道有很多关于这个主题的(好的)教程,但是在阅读它们之后,我真的无法理解他们的想法(例如:Smashing The Stack For Fun And Profit):
问题是我们不知道我们试图利用的代码(以及它后面的字符串)将被放置在程序的内存空间中的哪个位置。一种解决方法是使用 JMP 和 CALL 指令。JMP 和 CALL 指令可以使用 IP 相对寻址,这意味着我们可以跳转到当前 IP 的偏移量,而无需知道我们想要跳转到的内存中的确切地址。如果我们在“/bin/sh”字符串之前放置一条 CALL 指令,并在其上放置一条 JMP 指令,则在执行 CALL 时,字符串地址将作为返回地址被压入堆栈。我们所需要做的就是将返回地址复制到寄存器中。CALL 指令可以简单地调用我们上面代码的开头。
鉴于以下“crackme”(此示例用作演示,您可以跳过它并阅读下面的问题):
#include <stdio.h>
#include <string.h>
void funktion(char *args) {
char buffer[250];
strcpy(buff, args);
}
int main(int argc, char *argv[]) {
if (argc > 1)
funktion(argv[1]);
else
printf("Kein Argument!\n");
return 0;
}
目标:我想在该进程中执行一个非常基本的 shellcode。
漏洞:经典的潜在堆栈缓冲区溢出,由于strcpy(...).
需要的信息:
(gdb) info frame 0
Stack frame at 0xffffd300:
eip = 0x8048449 in funktion (stack_bof2.c:7); saved eip = 0x8048474
called by frame at 0xffffd330
source language c.
Arglist at 0xffffd2f8, args: args=0xffffd575 "A"
Locals at 0xffffd2f8, Previous frame's sp is 0xffffd300
Saved registers:
ebp at 0xffffd2f8, eip at 0xffffd2fc
(gdb) print/x &buffer
$1 = 0xffffd1f6
- 将
buffer在开始0xffffd1f6。 - 的
RE打开I指令Pointer(RIP)位于0xffffd2fc。 RIP从 的buffer第一个元素的偏移量为262 bytes。
方法论:
- 在
RIP已被覆盖与buffer第一个元素的地址0xffffd1f6。 - 所述的shellcode必须被放置在
buffer位置,并且不应当超过的长度261 bytes,因为从262th byte上,所述RIP被覆盖。
问题:我不知道为什么所有消息来源都说我们不知道我们试图利用代码的程序内存空间的哪个位置。我的意思是,我知道。很明显buffer,shellcode 被放置在 , 中。所以RIP必须指向它。不JMP,CALL和相对寻址...
Downloadlink的的的crackme。