[原理分析]Linux下的栈溢出案例分析-GDB调试操练[4]
来源:互联网 发布:linux系统安装软件 编辑:程序博客网 时间:2024/05/23 20:45
摘要:
本系列的3介绍了现有的linux系统对栈的保护,在那种栈保护措施下,要修改SIP(saved instruction pointer)不可能;但是栈保护对象有限,对程序中的数据不一定都能保护到。本文就是探讨程序中有内存操作漏洞时,如何利用漏洞改写数据,达到控制的目的。
测试平台:
1. ubuntu 9, gcc4.4.1, gdb 7.0
2. ubuntu系统安装在virtualBox 3.2.8系统上;
正文:
首先看个如下的示例代码:
#include<stdio.h>#include<stdlib.h>int main(){printf("hello world\n");sleep(1000);return 0;}该代码中主要是调用了两个标准库函数,下面是其反汇编代码:
如果仔细看的话,我们发现对于puts以及sleep的调用不是转入函数的入口,而是在call指令处通过一个额外的jmp来实现跳转,比如call 0x8048320处的指令时jmp *0x804a004,最后跳转处的地址存放在0x804a004中。我们可以认为一个程序中的用到库函数接口会对应一相应的表格,表格中存放着对应的库跳转地址,如下的表结构:
0x8048a004: 库接口1的跳转地址;
0x8048a000: 库接口2的跳转地址;
0x8048fffb: 库接口3的跳转地址;
理解上述原理后,如果能修改上述库跳转表格中的地址,那么我们就能控制程序的跳转。仔细看下面的代码:
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#define SIZE 12#define MAX 20typedef struct node{char buf[SIZE];void* next;}node;void hax(){execl("/bin/echo", "echo", "hello", NULL);}void readFile(char* file, char* buf){FILE *fd = fopen(file, "r");if(fd == NULL){printf("open error\n");exit(-1);}fread(buf, 1, MAX, fd);printf("read data2 %s\n", buf);fclose(fd);}int main(){char buf1[MAX+1];buf1[MAX] = '\0';readFile("data1.dat", buf1);char buf2[MAX+1];buf2[MAX] = '\0';readFile("data2.dat", buf2);node data1, data2;data1.next = &data2;data2.next = &data1;memcpy(&data1, buf1, MAX);//MAX or SIZE, I think it should be SIZE;memcpy(data1.next, buf2, SIZE);exit(-1);return 0;}上述代码中主要是两个数据节点,采用循环链表的方式链接在一起。上述代码中,主要的漏洞在于main函数中的第一个memcpy操作,其中的赋值超过buf的SIZE。利用这个漏洞,如果我们在data1.dat的输入文件中,将data1.dat中的next值替换为exit()函数对应的库跳转表地址值0x0804a024。然后,再将hax()(我们要替换exit的函数)的地址写在data2.dat文件中,该地址会通过第二个memcpy操作替换掉0x0804a024处原来的值,然后程序运行到exit后,就会执行我们的hax函数。下面是hax的地址:
下面是两个输入文件data1.dat和data2.dat中的数据:
data1
data2
data1中的主要设置是前面的12个字节存放'A'数据,最后跟上exit的表地址;而data2的前四个字节是hax()函数的入口地址,后面的四个字节只是保存了下exit的表地址中存储的原值。设定完这些文件后,运行程序,可以看到我们的设定的确发生作用,hax被调用了:
结束语:
本文展现如何对数据进行修改从而达到控制程序执行流程的案例。该案例主要基于内存漏洞,造成漏洞的主要原因在于内存拷贝时的越界。
参考文献:
《现代Linux系统中的栈溢出攻击》
- [原理分析]Linux下的栈溢出案例分析-GDB调试操练[4]
- [原理分析]Linux下的栈溢出案例分析-GDB调试操练[1]
- [原理分析]Linux下的栈溢出案例分析-GDB调试操练[2]
- [原理分析]Linux下的栈溢出案例分析-GDB调试操练[3]
- linux调试工具gdb的演示分析
- linux调试工具gdb的演示分析
- X86_64架构下的LINUX缓冲区溢出栈分析
- 通过gdb调试分析Linux内核的启动过程
- linux下的gdb调试
- Linux下的GDB调试
- linux下的GDB调试
- linux下的GDB调试
- linux下的gdb调试
- Linux下的gdb调试
- gdb调试实例分析
- 缓冲区溢出原理分析
- 【堆调试工具】pageheap的使用和原理分析&Linux下相似的功能实现
- 缓冲区溢出分析第02课:缓冲区溢出的原理
- mysql存储过程创建
- Eclipse 代码评测与优化系列二——PMD的安装配置与使用
- 汇编语言中常用进制数据输出的程序实现
- 路径问题大盘点
- IOS连线问题
- [原理分析]Linux下的栈溢出案例分析-GDB调试操练[4]
- spark 1.1.0 /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.9' not found
- 5.4.3.2 F# 中的类型推断
- 排序和顺序统计量与堆排序
- 无聊写排序之 ---- 希尔排序(ShellSort)
- 配置redhat yum源
- maven3常用命令
- SSO服务在云端为身份认证保驾护航
- 将QT程序设为ARM板开机自行启动的方法