华中科技大学计算机学院 《信息系统应用安全》实验报告 实验名称 团队成员: 注:团队成员贡献百分比之和为1 教师评语: 一.实验环境
? 操作系统:windows xp sp3 ? 编译平台:visual c++ 6.0 ? 调试环境:ollydbg 二.实验目的
1. 掌握缓冲区溢出的原理; 2. 掌握缓冲区溢出漏洞的利用技巧; 3. 理解缓冲区溢出漏洞的防范措施。 三.实验内容及步骤
1. 缓冲区溢出漏洞产生的的基本原理和攻击方法 ? 缓冲区溢出模拟程序 由于拷贝字符串时产生缓冲区溢出,用“abcd”字符串的值覆盖了原来eip的值,所以
main函数返回时eip指向44434241,引发访问异常。 ? 运行命令窗口的shellcode 由于把main函数的返回eip地址替换成了jmp esp的地址,main函数 返回的时候就会执行我们的shellcode代码。该shellcode,运行命令窗口。 2. ms06-040 缓冲区溢出漏洞分析和利用 ? 溢出点定位 篇二:缓冲区溢出实验报告 缓 冲 区 溢 出 报
告 院系:计算机与通信工程学院 班级:信息安全10-02班 1. 实验目的
掌握缓冲区溢出的原理 掌握常用的缓冲区溢出方法 理解缓冲区溢出的危害性
掌握防范和避免缓冲区溢出攻击的方法 2. 实验工具
溢出对象:ccproxy 7.2 (1)
(2)调试工具:
使用vmware虚拟机,安装ccproxy7.2进行实验调试。 3. 实验步骤
了解ccproxy 7.2 代理服务器为大家解决了很多问题,比如阻挡黑客攻击和局域网共享上网等。 ? 国内非
常受欢迎的一款代理服务器软件 ? 设置简单,使用方便
关于ccproxy6.2缓冲区溢出漏洞说明
ccproxy在代理telnet协议时,可以接受ping命令 ping命令格式:ping hostname\\r\\n 当hostname的长度大于或者等于1010字节时,ccproxy 6.2会发生缓冲区溢出,导致
程序崩溃 ccproxy 6.2缓冲区溢出漏洞演示 在目标主机运行ccproxy,使用默认设置 运行ccproxy的机器ip是192.168.6.132 使用telnet命令连接ccproxy: telnet 192.168. 6.132 23 返回信息:(如图) 输入ping命令,后接畸形数据: 在ping命令后接10个字符a(ping aaaaaaaaaa),观察返回信息 将字符a的数量变为100个、1000个、2000个,观察返回信息 (注:由于本人安装的是7.2版本,其漏洞已修复,故智能识别252个字符,其后被截断,所以当出现的畸形字符长度超过252时,就不再被识别,所以会有“host not found”) 原理: 如果终端提示“host not found”,说明ccproxy正确地处理了这个畸形数据,仍工作正常 如果终端提示“失去了跟主机的连接”,表明ccproxy已经崩溃 ccproxy 6.2缓冲区溢出漏洞利用 如何利用这个漏洞,来实现攻击目的,做一些特别的事情。 我们知道,栈是一个后进先出的结构,函数在入栈时,先将返回地址ret压入栈,接着是ebp基址寄存器,然后根据局部变量的大小,开辟一定大小的缓冲区,再将局部变量压入。 在将局部变量压入栈的时候,如果压入数据过长,大于事先声明的缓冲区大小,就会覆盖ebp和ret。
漏洞的利用有5个方面的问题需要考虑。 一是ret的定位,要用我们的地址覆盖ret,就需要先知道ret在哪,也就是我们定好
的这个地址,应该放在字符串的什么位置。 二是要寻找一个跳转指令,将这个指令的地址填充到ret,这样才能在返回时通过跳转
指令转到其它地方执行程序
三是要构造shellcode,也就是完成一些特定的功能。 四是将所构造的shellcode放在跳转指令转向的地方。 最后一个步骤就是根据上面的这些分析过程,将它们整合成攻击程序,运行这个攻击程
序就能直接利用缓冲区溢出漏洞。 函数栈布局,栈顶是内存低地址,栈底是内存高地址篇三:数据结构栈和队列实验报告 一、实验目的和要求
(1)理解栈和队列的特征以及它们之间的差异,知道在何时使用那种数据结构。 (2)重点掌握在顺序栈上和链栈上实现栈的基本运算算法,注意栈满和栈空的条件。 (3)重点掌握在顺序队上和链队上实现队列的基本运算算法,注意循环队队列满和队空的条件。
(4)灵活运用栈和队列这两种数据结构解决一些综合应用问题。 二、实验环境和方法 实验方法:
(一)综合运用课本所学的知识,用不同的算法实现在不同的程序功能。
(二)结合指导老师的指导,解决程序中的问题,正确解决实际中存在的异常情况,逐步改善功能。
(三)根据实验内容,编译程序。 实验环境:windows xp visual c++6.0 三、实验内容及过程描述 实验步骤:
① 进入visual c++ 6.0集成环境。 ② 输入自己编好的程序。 ③ 检查一遍已输入的程序是否有错(包括输入时输错的和编程中的错误),如发现有 错,及时改正。 ④ 进行编译和连接。如果在编译和连接过程中发现错误,频幕上会出现“报错信息”, 根据提示找到出错位置和原因,加以改正。再进行编译,如此反复直到不出错为止。 ⑤
运行程序并分析运行结果是否合理。在运行是要注意当输入不同的数据时所得结果 是否正确,应运行多次,分别检查在不同情况下结果是否正确。 实验内容:编译以下题目的程序并调试运行。 1)、编写一个程序algo3-1.cpp,实现顺 的各种基本运算,并在此基础上设计一 程序并完成如下功能: (1)初始化栈s;
(2)判断栈s是否非空; 序栈个主 (3)依次进栈元素a,b,c,d,e; (4)判断栈s是否非空; (5)输出出栈序列; (6)判断栈s是否非空;
(7)释放栈。 图3.1 proj3_1 工程组成 本工程proj3_1的组成结构如图3.1所示。本工程的模块结构如图3.2所示。图中方框
表示函数,方框中指出函数名,箭头方向表示函数间的调用关系。 图3.2 proj3_1工程的程序结构图 其中包含如下函数:
initstack(sqstack *&s) //初始化栈s destroystack(sqstack *&s) //销毁栈s stackempty(sqstack *s) //判断栈空 push(sqstack *&s,elemtype e) //进栈 pop(sqstack *&s,elemtype &e) //出栈 gettop(sqstack *s,elemtype &e) //取栈顶元素 对应的程序如下: //文件名:algo3-1.cpp #include <stdio.h> #include <malloc.h> #define maxsize 100 typedef char elemtype; typedef struct
{ elemtype data[maxsize];
int top; //栈顶指针 } sqstack;
void initstack(sqstack *&s) //初始化栈s { s=(sqstack *)malloc(sizeof(sqstack)); s->top=-1; //栈顶指针置为-1 }
void destroystack(sqstack *&s) //销毁栈s {
free(s); }
bool stackempty(sqstack *s) //判断栈空 {
return(s->top==-1); }
bool push(sqstack *&s,elemtype e) //进栈 { if (s->top==maxsize-1) //栈满的情况,即栈上溢出 return false;
s->top++; //栈顶指针增1 s->data[s->top]=e; //元素e放在栈顶指针处 return true; }
bool pop(sqstack *&s,elemtype &e) //出栈 { if (s->top==-1) //栈为空的情况,即栈下溢出 return false;
e=s->data[s->top]; //取栈顶指针元素的元素 s->top--; //栈顶指针减1 return true; }
bool gettop(sqstack *s,elemtype &e) //取栈顶元素 { if (s->top==-1) //栈为空的情况,即栈下溢出 return false;
e=s->data[s->top]; //取栈顶指针元素的元素 return true; }
设计exp3-1.cpp程序如下 //文件名:exp3-1.cpp #include <stdio.h> #include <malloc.h> #define maxsize 100 typedef char elemtype; typedef struct
{ elemtype data[maxsize]; int top; //栈顶指针 } sqstack;
extern void initstack(sqstack *&s); extern void destroystack(sqstack *&s); extern bool stackempty(sqstack *s); extern bool push(sqstack *&s,elemtype e); extern bool pop(sqstack *&s,elemtype &e); extern bool gettop(sqstack *s,elemtype &e); void main() {
elemtype e; sqstack *s;
printf(栈s的基本运算如下:\\n); printf( (1)初始化栈s\\n); initstack(s);
printf( (2)栈为%s\\n,(stackempty(s)?空:非空)); printf( (3)依次进栈元素a,b,c,d,e\\n); push(s,a); push(s,b); push(s,c); push(s,d); push(s,e);
printf( (4)栈为%s\\n,(stackempty(s)?空:非空)); printf( (5)出栈序列:); while (!stackempty(s)) {
pop(s,e);
printf(%c ,e); }
printf(\\n);
printf( (6)栈为%s\\n,(stackempty(s)?空:非空)); printf( (7)释放栈\\n); destroystack(s); }
运行结果如下: 2)、编写一个程序algo3-2.cpp,实现链栈的各种基本运算,并在此基础上设计一个主
程序并完成如下功能: (1)初始化链栈s;
(2)判断链栈s是否非空; (3)依次进栈a,b,c,d,e; (4)判断链栈s是否非空; (5)输出链栈长度;
(6)输出从栈底到栈顶元素; (7)输出出队序列;
(8)判断链栈s是否非空; 图3.3 proj3_2工程组成 (9)释放队列。