【0Day】栈溢出漏洞基础——简单输入漏洞 & 修改返回函数
2014-11-29 11:07
323 查看
最近再次利用零零散散的时间,把第二章学完了。 感觉实验成功之后,还是非常开心的!嘿嘿。
书本上的理论可以很快的看完,但是真正实践的时候还是会出现一点问题的。一点点总结将在后面一起分享出来。
自己构造的漏洞代码,如果使用VS编译的话,debug版溢出了会报错,release版它自己把代码优化了,消除了溢出的漏洞。
看来好几年前的技术现在已经被防护的很彻底了呀。 所以说,学技术不能死学,要学习思想。
call中记录的是前栈帧的EBP。 这个时候:
比如这说个函数 int f(int a, int b){ int abc = 5 ; return abc; }
在汇编中,获取函数的局部变量和传入参数,都是利用EBP的相对地址的。
就相当于图中的 param1, 地址为EBP+C
[a] 相当于param2, 地址为EBP+8
调用函数f之后的指令地址为[return addr], 地址为EBP+4
声明的本地变量从EBP开始减,
局部变量[abc]相当于 local pa1,地址为EBP-4,依次类推。
ESP的作用就是堆栈的栈顶指针,一般用于调用函数的时候,压入参数。
此次漏洞构造的目的,就是要利用Function 函数中拷贝函数的溢出特点,把局部变量local pa1,return addr 改变成自己想要的值得目的。
想要挖掘这个代码中的漏洞,就是要看两点。是否有可以溢出的缓冲区?是否有可以向缓冲区填充数据的条件?
本代码中就是 buffer 和strcpy两个函数。我们的目的就是要通过向buffer填充数据,改变相邻变量aut的值为0.为0 表示密码比对成功。
溢出之前的堆栈:
溢出之后的堆栈,aut位被溢出成0了,表示字符串比较成功,为相等:
本例中要求输入的密码小于真正的密码,得到的值为正数1. 反之如果大于真正的密码,将得到负数 -1. 补码为 FFFFFFFF。 普通输入将无法正确的溢出,需借助文件输入。
同样,也应该找到buffer的位置,同时还有返回地址的位置。
首先确定待跳转的地址。这里我们将在函数返回之后直接跳转到提示成功的地方。[b][0x00401467]
接着我们掌握堆栈结构,锁定具体哪一个位置填充我们的地址。
可以发现,每行四个字符,前面6行,24个字符,填充掉,后面四个字符表示返回地址。我们填上自己的地址。
构造的exploit文件时这样:
接着再执行。发现已经替换成我们的地址了。
显示执行成功了!
整理完之后还是感觉很有成就感的。
初步的漏洞理论学习。
下面是利用漏洞注入自己的代码,但是方法不是通用的。跟操作系统版本号,编译器等有关的。
书本上的理论可以很快的看完,但是真正实践的时候还是会出现一点问题的。一点点总结将在后面一起分享出来。
自己构造的漏洞代码,如果使用VS编译的话,debug版溢出了会报错,release版它自己把代码优化了,消除了溢出的漏洞。
看来好几年前的技术现在已经被防护的很彻底了呀。 所以说,学技术不能死学,要学习思想。
0x00 堆栈的基本原理
在调用一个call之后,堆栈的情况是这样的。call中记录的是前栈帧的EBP。 这个时候:
比如这说个函数 int f(int a, int b){ int abc = 5 ; return abc; }
在汇编中,获取函数的局部变量和传入参数,都是利用EBP的相对地址的。
就相当于图中的 param1, 地址为EBP+C
[a] 相当于param2, 地址为EBP+8
调用函数f之后的指令地址为[return addr], 地址为EBP+4
声明的本地变量从EBP开始减,
局部变量[abc]相当于 local pa1,地址为EBP-4,依次类推。
ESP的作用就是堆栈的栈顶指针,一般用于调用函数的时候,压入参数。
此次漏洞构造的目的,就是要利用Function 函数中拷贝函数的溢出特点,把局部变量local pa1,return addr 改变成自己想要的值得目的。
0x01 简单的输入漏洞
构造的具有漏洞的代码如下:/* note: 1、找到存储aut,buffer的位置。 本例中:aut=[esp-C] buffer=[esp-14] 2、查看堆栈,到数据窗口中跟随。 3、根据具体情况构造对应的overflow代码 */ #include <string.h> #include <stdio.h> #define PASSWORD "123456" int authen(char *password) { int aut; char buffer[8];//add to be overflowed!! aut = strcmp(PASSWORD,password); strcpy(buffer, password);//overflow! return aut; } int main() { char password[1024]; while(1) { printf("please input the password: "); scanf("%s",password); if( authen(password) )//输入的数小于123456,值00000001,覆盖00000000;反之,值FFFFFFFF,覆盖为FFFFFF00,, { printf("no! you should try again!\n"); } else { printf("Yes! you did it! \n"); break; } } getchar(); getchar(); return 0; }
想要挖掘这个代码中的漏洞,就是要看两点。是否有可以溢出的缓冲区?是否有可以向缓冲区填充数据的条件?
本代码中就是 buffer 和strcpy两个函数。我们的目的就是要通过向buffer填充数据,改变相邻变量aut的值为0.为0 表示密码比对成功。
溢出之前的堆栈:
溢出之后的堆栈,aut位被溢出成0了,表示字符串比较成功,为相等:
本例中要求输入的密码小于真正的密码,得到的值为正数1. 反之如果大于真正的密码,将得到负数 -1. 补码为 FFFFFFFF。 普通输入将无法正确的溢出,需借助文件输入。
0x02 修改函数返回地址
构造的漏洞代码:/* note: */ #include <string.h> #include <stdio.h> #define PASSWORD "123456" int authen(char *password) { int aut; char buffer[8];//add to be overflowed!! aut = strcmp(PASSWORD,password); strcpy(buffer, password);//overflow! return aut; } int main() { char password[1024]; FILE* fp; if(!(fp=fopen("password.txt","rw+")))//get the pass by read file return 0; fscanf(fp, "%s", password); if( authen(password) ) { printf("no! you should try again!\n"); } else { printf("Yes! you did it! \n"); } fclose(fp); getchar(); getchar(); return 0; }由于像地址这种特殊的字符"0x0041567",手打很难输入,因此,借助文件的输入。 这种构造完全是为了理解漏洞的原理来做的。
同样,也应该找到buffer的位置,同时还有返回地址的位置。
首先确定待跳转的地址。这里我们将在函数返回之后直接跳转到提示成功的地方。[b][0x00401467]
接着我们掌握堆栈结构,锁定具体哪一个位置填充我们的地址。
可以发现,每行四个字符,前面6行,24个字符,填充掉,后面四个字符表示返回地址。我们填上自己的地址。
构造的exploit文件时这样:
接着再执行。发现已经替换成我们的地址了。
显示执行成功了!
整理完之后还是感觉很有成就感的。
初步的漏洞理论学习。
下面是利用漏洞注入自己的代码,但是方法不是通用的。跟操作系统版本号,编译器等有关的。
相关文章推荐
- 【漏洞分析】两个例子-数组溢出修改返回函数与strcpy覆盖周边内存地址
- 让boolean类型验证用户函数同时修改返回输入的参数对象
- 【习题&基础知识】输入与输出、简单循环(好多图贴上去好累...要看图的话我把word文档发给你)
- Java简单输入&通过控制台输入相关指令,输出System类, RunTime类相关方法返回信息
- JavaSE8基础 函数返回一个匿名对象 简单示例
- 问题1:java中没有实现这种“byte a = 0xB2 --> String b = “B2””转换的简单实现需要自己实现。 答:自己编写的转换函数,思路将byte的高低4位分开,分别转换为对应的字符然后合成返回的字符串。 java 代码 1.
- C函数调用-不使用函数返回值,而用参数实现输入/输出的4种模式
- 一个函数返回两值的通用实现方法(简单,备忘)
- ASP.NET AJAX 说明文档->客户端引用->全局命名空间->JavaScript 基础类型扩展->Array 类型扩展->clone 函数
- 对函数返回形式及传参方式的简单理解(实例)
- 极限研究-"&amp;"函数返回引用与返回普通类型的区别
- delphi 一个修改系统时间的函数,超简单
- ASP.NET AJAX 说明文档->客户端引用->全局命名空间->JavaScript 基础类型扩展->Array 类型扩展->clear 函数
- "getline" bug fix for Microsoft Visual C++ 6.0 关于VC6的getline输入需要两个回车才结束的BUG修改方法
- tchar 输入输出类 和 string 类 函数简单说明
- Android的intent:基础概念以及显示/隐式使用Intent && 通过intent返回结果
- javascript入门系列演示·函数的定义以及简单参数使用,调用函数 .txt
- 日前有消息称,微软已经同意收购语义搜索引擎Powerset,收购价格将略高于1亿美元.微软将于下月发布正式声明.Powerset公司位于旧金山,其搜索引擎技术能够理解用户输入的短语的真实含义,并在这种理解的基础上返回搜索结果.
- ASP.NET AJAX 说明文档->客户端引用->全局命名空间->JavaScript 基础类型扩展->Array 类型扩展->addRange 函数
- 一个简单的oracle函数返回数组的例子