CSAPP-LAB3-Attack

本文详细介绍了CSAPP实验3(LAB3)的攻击部分,涉及代码注入和返回导向编程(ROP)。文章分为两部分,第一部分探讨了通过缓冲区溢出改变函数返回地址来实现code injection,包括phase_1至phase_3,逐步深入到栈帧的理解和利用。第二部分介绍了在栈随机化和NX位保护下,如何利用返回导向编程技术完成phase_4和phase_5的挑战,重点在于寻找和构造gadgets。

00 Prerequisite

听见课堂上老爷子说:

	But to be a good person you also know what the bet have to know what the bad people do, so part of it is to become more effective as a force for good.

Part 1: Code injection

关于Attack的,攻击两个c代码,分别是ctargetrtarget,前3个阶段是关于 ctarget 后面2个是关于rtarget的,Code injection and Return-oriented programming.

ctarget

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

关于getbuf实际上是在模拟c语言的库函数gets,这类函数容易出现Overunning on buffer 的现象

1 unsigned getbuf()
2 {
   
   
3 char buf[BUFFER_SIZE];
4 Gets(buf);
5 return 1;
6 }

运用GDB调试 ctarget

执行命令

disas test
Dump of assembler code for function test:
   0x0000000000401968 <+0>:	sub    $0x8,%rsp // 分配栈帧
   0x000000000040196c <+4>:	mov    $0x0,%eax
   0x0000000000401971 <+9>:	callq  0x4017a8 <getbuf>
   0x0000000000401976 <+14>:	mov    %eax,%edx // 返回值 -> %edx
       // 准备调用 printf 函数
   0x0000000000401978 <+16>:	mov    $0x403188,%esi // 0x403188 -> %esi
   0x000000000040197d <+21>:	mov    $0x1,%edi // Load rdi ready to call fun print
   0x0000000000401982 <+26>:	mov    $0x0,%eax
   0x0000000000401987 <+31>:	callq  0x400df0 <__printf_chk@plt>
   0x000000000040198c <+36>:	add    $0x8,%rsp
   0x0000000000401990 <+40>:	retq 

对于0x401388的地址check一下,是对应的printf输出的内容

(gdb) x/s 0x403188
0x403188:	"No exploit.  Getbuf returned 0x%x\n"

执行命令

(gdb) disas getbuf
Dump of assembler code for function getbuf:
   0x00000000004017a8 <+0>:	sub    $0x28,%rsp // 分配 40bytes的栈帧
   0x00000000004017ac <+4>:	mov    %rsp,%rdi
   0x00000000004017af <+7>:	callq  0x401a40 <Gets>
   0x00000000004017b4 <+12>:	mov    $0x1,%eax
   0x00000000004017b9 <+17>:	add    $0x28,%rsp
   0x00000000004017bd <+21>:	retq   
End of assembler dump.
disas Gets
Dump of assembler code for function Gets:
   0x0000000000401a40 <+0>:	push   %r12
   0x0000000000401a42 <+2>:	push   %rbp
   0x0000000000401a43 <+3>:	push   %rbx
   0x0000000000401a44 <+4>:	mov    %rdi,%r12
   0x0000000000401a47 <+7>:	movl   $0x0,0x2036b3(%rip)        # 0x605104 <gets_cnt>
   0x0000000000401a51 <+17>:	mov    %rdi,%rbx
   0x0000000000401a54 <+20>:	jmp    0x401a67 <Gets+39>
   0x0000000000401a56 <+22>:	lea    0x1(%rbx),%rbp
   0x0000000000401a5a <+26>:	mov    %al,(%rbx)
   0x0000000000401a5c <+28>:	movzbl %al,%edi
   0x0000000000401a5f <+31>:	callq  0x4019a0 <save_char>
   0x0000000000401a64 <+36>:	mov    %rbp,%rbx
   0x0000000000401a67 <+39>:	mov    0x202a62(%rip),%rdi        # 0x6044d0 <infile>
   0x0000000000401a6e <+46>:	callq  0x400dc0 <_IO_getc@plt>
   0x0000000000401a73 <+51>:	cmp    $0xffffffff,%eax
   0x0000000000401a76 <+54>:	je     0x401a7d <Gets+61>
   0x0000000000401a78 <
CSAPP(Computer Systems: A Programmer&#39;s Perspective)课程中的 Attack Lab 是一个关于程序安全和漏洞利用的经典实验,主要目的是让学生理解缓冲区溢出攻击的原理以及如何通过代码注入或重定向执行流来实现特定功能。该实验通常分为多个阶段,从简单的栈溢出到更复杂的代码注入攻击。 ### 实验环境准备 Attack Lab 通常需要在 Linux 环境下运行,并使用 `gdb`、`objdump`、`hexedit` 等工具进行逆向分析和调试。实验中会提供一个可执行文件和若干目标函数,如 `touch1`、`touch2` 和 `touch3`,每个阶段的目标是将控制流转移到这些函数并传入正确的参数值(通常是某个 cookie 值)[^1]。 --- ### 阶段一:基本栈溢出(Phase 1) 第一阶段的目标是触发缓冲区溢出,将返回地址覆盖为 `touch1` 函数的地址。步骤如下: 1. **获取函数地址**: 使用 `objdump -d ctarget > ctarget.asm` 获取反汇编信息,查找 `touch1` 的地址。 2. **构造 payload**: 在 `farm.c` 中找到用于输入的缓冲区大小(通常是 56 字节),然后填充 56 字节的 NOP 指令(例如 `\x90`),接着写入 `touch1` 的地址(小端序格式)。 3. **验证执行**: 使用 `make test` 或 `./ctarget -i exploit.txt` 运行 payload 文件,确认是否成功跳转至 `touch1`。 --- ### 阶段二:带参数的函数调用(Phase 2) 第二阶段要求将指定的 cookie 值(如 `0x59b997fa`)作为参数传递给 `touch2` 函数,并跳转至其地址(如 `0x4017ec`)[^1]。 1. **分析 touch2 函数**: 查看 `touch2` 的汇编代码,确认其期望的参数是存储在寄存器 `rdi` 中。 2. **构造 ROP 链**: 使用 `popq %rdi; ret` 指令(称为 gadget)将 cookie 值压入 `rdi` 寄存器,随后跳转至 `touch2` 地址。 3. **生成 payload**: 构造如下结构: ``` [padding (56 bytes)] → [address of popq rdi gadget] → [cookie value] → [address of touch2] ``` 4. **测试与调试**: 使用 `gdb` 调试程序,观察栈布局是否正确,确保寄存器 `rdi` 的值被正确设置。 --- ### 阶段三:代码注入攻击(Phase 3) 第三阶段要求直接注入一段自定义的机器码(shellcode),修改程序行为,最终跳转至 `touch3` 并传入正确的 cookie 字符串。 1. **编写 shellcode**: 编写一小段汇编代码,将 cookie 值(如 `0x59b997fa`)转换为字符串并将其地址放入 `rdi`。 2. **汇编与提取机器码**: 使用 `gcc -c shellcode.s` 和 `objdump -d shellcode.o` 提取机器码。 3. **构造 payload**: 填充缓冲区后,在栈上注入 shellcode,并跳转至其起始地址。 4. **绕过 NX 保护机制**: 如果系统启用 NX(No-eXecute),则需采用其他方式(如 ROP 技术)完成攻击。 --- ### 工具推荐与调试技巧 - **GDB 调试技巧**: - 使用 `break *main` 设置断点 - 使用 `x/16x $rsp` 查看栈内容 - 使用 `stepi` 单步执行指令 - **常用命令**: ```bash objdump -d ctarget > ctarget.asm gdb ./ctarget ``` - **注意事项**: - 所有地址必须以小端序格式写入 - payload 文件应为二进制格式(可使用 `hexedit` 编辑) ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值