官术网_书友最值得收藏!

3.6 .dtors區(qū)

任意內存寫攻擊的另外一個目標是覆寫由GCC生成的可執(zhí)行文件的.dtors區(qū)中的函數(shù)指針[Rivas 2001]。GNU C允許程序員利用__attribute__關鍵字后跟一個包含于雙括號中的屬性修飾符來聲明函數(shù)的屬性[FSF 2004]。屬性修飾符包括constructor和destructor。constructor屬性指示函數(shù)在main()之前被調用,destructor屬性則表示函數(shù)將在main()執(zhí)行完成后或exit()被調用后進行調用。

例3.7所示的程序展示了constructor和destructor屬性的用法。該程序包含3個函數(shù):main()、create()和destroy()。第4行聲明的create()函數(shù)是一個構造函數(shù),第5行聲明的destroy()函數(shù)則是一個析構函數(shù)。這兩個函數(shù)都沒有被main()調用,main()只是打印了兩個函數(shù)的地址然后就退出了。例3.8展示了示例程序的執(zhí)行結果。顯然,create()首先執(zhí)行,然后是main(),最后才是destroy()。

例3.7 具有constructor和destructor屬性的程序


01  #include <stdio.h>
02  #include <stdlib.h>
03
04  static void create(void) __attribute__ ((constructor));
05  static void destroy(void) __attribute__ ((destructor));
06
07  int main(void) {
08    printf("create: %p.\n", create);
09    printf("destroy: %p.\n", destroy);
10    exit(EXIT_SUCCESS);
11  }
12
13  void create(void) {
14    puts("create called.\n");
15  }
16
17  void destroy(void) {
18    puts("destroy called.");
19  }

例3.8 示例程序的輸出


% ./dtors
create called.
create: 0x80483a0.
destroy: 0x80483b8.
destroy called.

構造函數(shù)和析構函數(shù)分別存儲于生成的ELF可執(zhí)行映像的.ctors和.dtors區(qū)中。這兩個區(qū)都具有如下的布局形式:


0xffffffff { 
函數(shù)地址 } 0x00000000 

.ctors和.dtors區(qū)映射到進程地址空間后,默認屬性為可寫。漏洞利用程序從未利用過構造函數(shù),因為它們都在main()函數(shù)之前執(zhí)行。結果,攻擊者的興趣都集中到了析構函數(shù)和.dtors區(qū)上。

如例3.9所示,可以使用objdump命令檢查可執(zhí)行映像中.dtors區(qū)中的內容,我們可以看到頭、尾標簽,以及destroy()函數(shù)的地址(采用小端格式)。

例3.9 .dtors區(qū)的內容


1  % objdump -s -j .dtors dtors 
2 
3  dtors:     file format elf32-i386 
4 
5  Contents of section .dtors: 
6  804959c ffffffff b8830408 00000000 

攻擊者可以通過覆寫.dtors區(qū)中的函數(shù)指針的地址從而將程序控制權轉移到任意的代碼。如果攻擊者能夠讀取到目標二進制文件,那么通過分析ELF映像,很容易就能確定要覆寫的確切位置。

有趣的是,即使沒有指定任何析構函數(shù),.dtors區(qū)仍然存在。在這種情況下,該區(qū)中只含有頭、尾標簽而中間沒有函數(shù)地址。不過,仍然可以通過將尾標簽0x00000000覆寫為攻擊者提供的外殼代碼的地址,從而將控制轉移過去。如果外殼代碼返回,則進程將會繼續(xù)調用接下來的函數(shù)直到遇到尾標簽或發(fā)生錯誤為止。

對于攻擊者而言,覆寫.dtors區(qū)的好處在于該區(qū)總是存在并且會映射到內存中 [1]。當然,dtors僅存在于用GCC編譯和鏈接的程序中。有時候,很難找到合適的外殼代碼注入點,使得在main()退出后外殼代碼仍然能夠駐留在內存中。

[1] .dtors 區(qū)不會被一個二進制strip(1) 刪除。
主站蜘蛛池模板: 云安县| 乳山市| 淳安县| 蒲城县| 乌苏市| 安化县| 宣恩县| 梓潼县| 景宁| 樟树市| 长垣县| 华容县| 兴仁县| 博罗县| 松阳县| 东阿县| 五莲县| 莒南县| 洮南市| 华安县| 太仓市| 深圳市| 榕江县| 清远市| 西藏| 建水县| 鄂州市| 友谊县| 山丹县| 连州市| 辽宁省| 彰化市| 灵璧县| 哈巴河县| 米脂县| 周宁县| 黎川县| 信宜市| 平定县| 蓬安县| 通河县|